利用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;
}