2016-07-29 45 views
0

我使用Linux上的C++套接字發送數據(每個文件約10個,大約10-20 kb)。在服務器發送數據中的套接字問題

我的僞代碼:

for(i=0;i<10;i++){ 
    ret = send(sockfd, filedata, filedatasize, 0); 
} 

ret返回所有數據文件,沒有錯誤的正確的文件大小,但客戶只接收4-5文件。

但是,如果我用這個來代替:

for(i=0;i<10;i++){ 
    ret = send(sockfd, filedata, filedatasize, 0); 
    sleep(1); 
} 

客戶端收到的所有文件,並沒有錯誤!

什麼問題?

我試過調整SO_RCVBUFSO_SNDBUF,但沒有變化。

編輯:(完整的代碼有20萬行粘貼!)

這裏是服務器代碼:

int Socket::sendMsg(char * data, unsigned int uiSize) 
{ 
    unsigned short * us; 
    int i, iRet; 


     us = (unsigned short *)(m_pSendBuffer); 
     *us = (unsigned short)(uiSize + 2); 

     memcpy((char *)m_pSendBuffer + 2, data, uiSize); 
     iRet = isend(m_pSendBuffer, uiSize + 2); 
     if (iRet<0) { 
      return SOCKET_ERROR; 
     } 
     return iRet; 
} 
int Socket::isend(char * data, int size) 
{ 
    int outlen, ret; 

    outlen= 0; 
    while (outlen< size) { 
     ret= send(sockfd, (data+ outlen), size - outlen, 0); 

     if (ret< 0) { 
      return -1; 
     } 
     else outlen+= ret; 
    } 
    return outlen; 
} 

下面是客戶端代碼:

void XSocket::onRead() 
{ 
    int iRet; 
    unsigned short * usp; 
    unsigned int uiReadSize; 

    while (1) { 
     iRet = recv(m_Sock, (char *)m_pRecvBuffer, 2, 0); 
     uiReadSize = 0; 


     usp = (unsigned short *)(m_pRecvBuffer); 
     uiReadSize = (int)(*usp - 2); 

     iRet = recv(m_Sock, (char *)(m_pRecvBuffer + 2), uiReadSize, 0); 

     if (iRet < 0) { 
      //return error    
     } 
     else if (iRet == 0) { 
      //disconnect 
     } 
     //PROCCESS MSG 
    } 
} 
+0

你能在客戶端顯示代碼嗎? –

+0

是這個tcp或udp? –

+0

TCP @SamerTufail – Octavio

回答

1

在客戶端方:

  1. 在第一個recv()調用中,您沒有執行任何錯誤處理,如果服務器正常斷開連接,則第二個recv()調用不會中斷循環。

  2. 你沒有循環讀取每個數據緩衝區,就像循環發送它們在服務器端一樣。發送的字節數和接收的字節數之間沒有1對1的關係。如果您希望X字節到達,請繼續閱讀,直到您實際接收到很多字節。

鑑於這些錯誤,不能保證您的客戶端實際上能夠正確接收所有數據。

嘗試更多的東西是這樣的:

void XSocket::onRead() 
{ 
    int iRet; 
    unsigned short * usp; 
    unsigned int uiReadSize; 

    while (1) { 
     iRet = irecv((char *)m_pRecvBuffer, 2); 
     if (iRet<= 0) { 
      break; 
     } 

     usp = (unsigned short *)(m_pRecvBuffer); 
     uiReadSize = (int)(*usp - 2); 

     iRet = irecv((char *)(m_pRecvBuffer + 2), uiReadSize); 
     if (iRet<= 0) { 
      break; 
     } 

     //PROCCESS MSG 
    } 
} 

int XSocket::irecv(char * data, int size) 
{ 
    int inlen, ret; 

    inlen= 0; 
    while (inlen< size) { 
     ret= recv(m_Sock, (data+ inlen), size - inlen, 0); 

     if (ret< 0) { 
      return -1; 
     } 
     else if (ret== 0) { 
      return 0; 
     } 
     else { 
      inlen+= ret; 
     } 
    } 
    return inlen; 
} 
+0

hi @Remy Lebeau,im編碼一個僞代碼,完整源代碼有200k行!我已經在完整的代碼中考慮了2個案例。 – Octavio

+0

該解決方案解決epoll的邊緣觸發器!謝謝! – Octavio

0

IM解決了這個問題!,即時改變epoll的從邊緣觸發電平觸發,並解決了!