日期:2014-05-16  浏览次数:20743 次

socket传送文件丢失数据问题
我编写了传送文件的服务器/客户端程序,由服务端向客户端传送文件。服务端在Linux下用C语言编写,客户端在为windows下用C#编写。对于较大的文件通过分包的方式进行发送,每个包最大1024个字节。现在的问题是,如果发送的包与包之间不添加ulseep()函数,则会出现数据丢失的现象。如果添加上,让每次发送一个包后休眠一段时间,则客户端能完整的接收所有数据。
服务端主要代码如下:
void SendFile(int socketFd,Connection*conn)
{
    //接收客户端发来的文件请求
    char recvMsg[BUFFER_SIZE];
    ReceiveMessage(socketFd,recvMsg);
    string fileName=recvMsg;
    cout<<"Client request file: "<<fileName<<endl;
    
    
    //连接数据库,生成需要发送的文件
    //CreateDbXml(conn,fileName);

    //获取文件长度,并发送
    unsigned long fileLen=get_file_size(recvMsg);
    char buffer[BUFFER_SIZE];
    bzero(buffer,sizeof(buffer));
    snprintf(buffer,sizeof(buffer),"%u",fileLen);
    SendMessage(socketFd,buffer,strlen(buffer));

    //打开文件
    FILE * fp=fopen(recvMsg,"r");
    if(fp==NULL)
    {
        cout<<"File "<<fileName<<" not fount!"<<endl;
    }
    
    //发送文件
    bzero(buffer,sizeof(buffer));
    int file_block_length=0;
    while((file_block_length=fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0)
     {
               
         SendMessage(socketFd,buffer,file_block_length);
         cout<<buffer;
         bzero(buffer,sizeof(buffer));
         
         usleep(50000);//如果去掉此行代码,或者usleep()函数的参数过小,监控端都会出现数据丢失的情况
     }

       fclose(fp);
       cout<<"File "<<fileName<<" transfer finished!"<<endl;
}

//为了避免数据的粘粘问题,发送数据时先发送数据长度,再发送数据
int SendMessage(int socketFd,char * sendBuffer,int sendLen)
{
    char len[5];
    snprintf(len,sizeof(len),"%04d",sendLen);
    //printf("len:%s\n",len);
    if(send(socketFd,len,sizeof(len)-1,0)<0)