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