C 通过套接字进行文件传输,最终大小为更少字节

C 通过套接字进行文件传输,最终大小为更少字节,c,sockets,file-transfer,C,Sockets,File Transfer,我试图通过C中的套接字接收一些文件。但是服务器发送给我一个1000000字节文件的64字节数据包,我在目标文件上得到大约999902字节 while ((n = read(sd, buffer_in, BUFSIZE ))) // BUFSIZE = 64 { if(n<0) { printf("Fail.\n"); fclose(archivo); return -1; } if(fwrite(buffer_

我试图通过C中的套接字接收一些文件。但是服务器发送给我一个1000000字节文件的64字节数据包,我在目标文件上得到大约999902字节

while ((n = read(sd, buffer_in, BUFSIZE ))) //  BUFSIZE = 64 
{
    if(n<0)
    {
       printf("Fail.\n");
       fclose(archivo);
       return -1;
    }

    if(fwrite(buffer_in, n, 1, f) !=1 ) 
    { 
       printf("fwrite error.\n");
       fclose(archivo);
       return -1;
    }

    bytes+=n;
}

printf("We received %d bytes",  bytes);
我知道read()和write()都可能返回N (编辑二)


用10673字节的C源代码测试,除了目标文件缺少前98个字节外,接收10575个字节而没有损坏

提供的发送代码忽略了一个事实,即套接字上的write()(或send())没有义务写入整个缓冲区

如果基础子系统拒绝接收更多数据,write()/send()可能会决定部分写入,或者根本不写入(例如,网络子系统可能有一个数据发送队列,而该队列已满)。这很可能发生在连接速度较慢的情况下

发送端应检查write()的返回值,以检测实际写入了多少数据,并进行相应调整

应该这样写:

int readAmount;
while( readAmount = read(file_fd, buffer, BUFSIZE) > 0 )
{
    int totalWritten = 0;
    do {
       int actualWritten;
       actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten);
       if( actualWritten == - 1 ) {
           //some error occured - quit;
       }
       totalWritten += actualWritten;
    } while( totalWritten < readAmount );
}
int readAmount;
而(readAmount=read(file_fd,buffer,BUFSIZE)>0)
{
int totalwrited=0;
做{
int实际编写;
ActualWrited=写入(sdaccept,buffer+TotalWrited,readAmount-TotalWrited);
如果(实际写入==-1){
//发生了一些错误-退出;
}
总写入+=实际写入;
}while(总写入量<读取量);
}

大约为999902?或者确切地说?我看不出这段代码中有明显的缺陷-请也显示发送代码。特别奇怪,因为64分为1000000个精确添加的发送代码。。。帕克斯:是的,999902完全来自一个100万字节的文件。你应该在((n=read(…)>0)时测试
。目前,即使出现错误(
n==-1)
,您仍在继续。发送代码很容易出现我描述的问题。已添加建议的修复程序。更具体地说,写入的字节数为1M,但接收的字节数较少!:(你的意思是,你将所有迭代的写入总数加起来是1M,但接收方仍然接收到不完整的数据?最后接收到的数据大小是30字节,似乎在该接收读取得到EOFY后,你应该尝试检测到底缺少了什么数据。例如,从磁盘读取一个块后,将一个整数写入其第一个数据块中四个字节并递增整数。在接收端检查它。
int readAmount;
while( readAmount = read(file_fd, buffer, BUFSIZE) > 0 )
{
    int totalWritten = 0;
    do {
       int actualWritten;
       actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten);
       if( actualWritten == - 1 ) {
           //some error occured - quit;
       }
       totalWritten += actualWritten;
    } while( totalWritten < readAmount );
}