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)
{
perror("send :");
return -1;
}
int sendRecv;
if((sendRecv=send(socketFd,sendBuffer,sendLen,0))<0)
{
perror("send sendBuffer:");
return -1;
}
return sendRecv;
}
//为了避免数据的沾粘问题,接收数据时,先接收数据长度,再接收数据
int ReceiveMessage(int sockFd,char recvMsg[])
{
//获取接收数据的长度
char msgSize[5];
int sizeLen=sizeof(msgSize);
if(recv(sockFd,msgSize,sizeLen-1,0)<0)
{
perror("recv:");
}
msgSize[sizeLen-1]='\0';
int msgLen=atoi(msgSize);
int recvLen;
if((recvLen=recv(sockFd,recvMsg,msgLen,0))<0)
{
perror("recv:");
}
recvMsg[msgLen]='\0';
return recvLen;
}