利用TCP传递信息时要注意:TCP传输是流的方式:即send 100个字节后对方如果没有及时recv取出,
这时又send 100个字节,则recv有可能接收到两次发送叠加的部分或全部数据,所有在传送结构体数据
时,应当发送以后睡眠一段时间,使对方recv有足够的实际取走数据,不至于两个结构体数据发生粘连,
区分不出发送的是两个结构体数据。
另外,send(SOCKET,BUFF,SIZE,FLAG)发送的数据将存放到系统缓冲区,当系统缓冲区已满时,
send将返回发送的字节数,这时发送的字节数并不是SIZE大小了,同理,recv(SOCKET,BUFF,SIZE,FLAG)
每次接受的数据也不一定是SIZE大小,而是返回的值大小的字节。故发送和接收大文件即文件的大小大于SIZE时
可利用如下代码执行:
bool Server::SendFile(SOCKET sd) //向客户端发送文件 { cout<<"进入到发送文件内容"<<endl; cout<<"要发送的文件为"<<fileName<<endl; FILE *pFile; pFile=fopen(fileName,"r+b"); fseek(pFile,0,SEEK_SET); //定位到文件首位置 _int64 i=0; char buff[MAX_PACK_SIZE]; cout<<"要发送的文件长度为"<<fileLength<<endl; while(i<fileLength) { int nSize; if(i+MAX_PACK_SIZE>fileLength) { nSize=(int)(fileLength-i); } else { nSize=MAX_PACK_SIZE-1; } fread(buff,sizeof(char),nSize,pFile); int nSend; nSend=send(sd,buff,nSize,0); if(nSend==SOCKET_ERROR) { cout<<"发送失败"<<WSAGetLastError()<<endl; return false; } i+=nSend; fseek(pFile,-(nSize-nSend),SEEK_CUR); //定位到实际已发送到的位置 memset(buff,0,sizeof(char)*MAX_PACK_SIZE); //将buff清空 } fclose(pFile); return true; }
<pre name="code" class="cpp">bool Server::ReceiveFile(SOCKET sd) { char buff[MAX_PACK_SIZE]; FILE *pFile; pFile=fopen(fileName,"a+b"); _int64 i=0; while(i+1<fileLength) { int nRecv=recv(sd,buff,MAX_PACK_SIZE,0); if(nRecv==SOCKET_ERROR) { return false; } fwrite(buff,sizeof(char),nRecv,pFile); i+=nRecv; memset(buff,0,sizeof(char)*MAX_PACK_SIZE); } fclose(pFile); return true; }