2017-05-03 94 views
0

請幫我找出什麼是錯在客戶端服務器通信...發送和接收的所有數據(C++插座)

客戶端每秒使用此功能向服務器發送JPEG幀從相機25倍:

int SendAll(SOCKET &client_socket, string &data){ 
    int result, bytes_sent, sent_total, bytes_remain, package_size; 
    result = bytes_sent = sent_total = package_size = 0; 
    bytes_remain = data.size(); 
    while (bytes_remain && !result){ 
     package_size = (bytes_remain<KILOBYTE)?bytes_remain:KILOBYTE; 
     bytes_sent = send(client_socket, &data[sent_total], package_size, 0); 
     if (bytes_sent > 0){ 
      bytes_remain-= bytes_sent; 
      sent_total+= bytes_sent; 
     } 
     else if(bytes_sent == SOCKET_ERROR){ 
      result = WSAGetLastError(); 
      break; 
     } 
    } 
    return result; 
} 

在線程循環:

while(CAMERA.Stream){ 
    OperationStartTime = GetTickCount(); 
    //RecvBuffer.resize(512); 
    result = SendAll(CAMERA.Socket, CameraFrame); 
    if(result != 0){ 
     cout << "error in send - " << result; 
     CAMERA.Stream = false; 
     break; 
    } 
    if (recv(CAMERA.Socket, &RecvBuffer, 1, 0) < 0){ 
     CAMERA.Stream = false; 
     break; 
    } 
    while(OperationStartTime + StreamRate > GetTickCount()){ 
     if (!CAMERA.Stream){break;} 
     Sleep(1); 
    } 
} 

有時候我看到 「錯誤發送 - 10053」(在本地主機上測試)

Server使用此功能,接收的所有數據:

int RecvAll(SOCKET &client_socket, string &data){ 
    data = ""; 
    int bytes_received = 0; 
    int result = 0; 
    char* recv_buffer; 
    do { 
     recv_buffer = (char*)malloc(KILOBYTE); 
     bytes_received = recv(client_socket, recv_buffer, KILOBYTE, 0); 
     if (bytes_received > 0){ 
      data.append(recv_buffer, bytes_received); 
      if (bytes_received < KILOBYTE || data.size() >= 512*KILOBYTE){ 
       bytes_received = result = 0;} 
     } 
     else if(bytes_received == SOCKET_ERROR){ 
      data.clear(); 
      result = WSAGetLastError(); 
     } 
     free(recv_buffer); 
    } 
    while (bytes_received > 0); 
    return result; 
} 

而在服務器端沒有錯誤。

SendAllRecvAll函數有什麼問題以及如何實現穩定的數據傳輸?

PS:有時客戶端停止,只有重新連接有幫助。但是如果要重新連接,服務器會顯示另一個連接的套接字 - 這意味着CAMERA.Socket是阻止的,我不明白爲什麼

+0

你問我們調試程序的嗎? –

+0

你試過查找錯誤代碼嗎? –

+0

@BoundaryImposition,根本不用調試,但也許有人會看到邏輯上的錯誤 – Iceman

回答

1

客戶端不會將數據大小發送到服務器,以便知道有多少個字節爲每個正在發送的幀實際讀取。

它也不處理服務器斷開連接或正確處理計算正確的情況。

嘗試一些更喜歡這個:

客戶:

int SendAll(SOCKET client_socket, const void *data, int data_size) 
{ 
    const char *data_ptr = (const char*) data; 
    int bytes_sent; 

    while (data_size > 0) 
    { 
     bytes_sent = send(client_socket, data__ptr, data_size, 0); 
     if (bytes_sent == SOCKET_ERROR) 
      return -1; 

     data_ptr += bytes_sent; 
     data_size -= bytes_sent; 
    } 

    return 1; 
} 

int SendAll(SOCKET client_socket, const string &data) 
{ 
    ulong data_size = htonl(data.size()); 

    int result = SendAll(client_socket, &data_size, sizeof(data_size)); 
    if (result == 1) 
     result = SendAll(client_socket, data.c_str(), data.size()); 

    return result; 
} 

... 

int result; 
char reply; 

while (CAMERA.Stream) 
{ 
    OperationStartTime = GetTickCount(); 

    result = SendAll(CAMERA.Socket, CameraFrame); 
    if (result != 1) 
    { 
     cout << "error in send - " << WSAGetLastError(); 
     CAMERA.Stream = false; 
     break; 
    } 

    result = recv(CAMERA.Socket, &reply, 1, 0); 
    if (result <= 0) 
    { 
     if (result == 0) 
      cout << "server disconnected"; 
     else 
      cout << "error in read - " << WSAGetLastError(); 

     CAMERA.Stream = false; 
     break; 
    } 

    while (CAMERA.Stream && ((GetTickCount() - OperationStartTime) < StreamRate)) 
    { 
     Sleep(1); 
    } 
} 

服務器:

int RecvAll(SOCKET client_socket, void *data, int data_size) 
{ 
    char *data_ptr = (char*) data; 
    int bytes_recv; 

    while (data_size > 0) 
    { 
     bytes_recv = recv(client_socket, data_ptr, data_size, 0); 
     if (bytes_recv <= 0) 
      return bytes_recv; 

     data_ptr += bytes_sent; 
     data_size -= bytes_sent; 
    } 

    return 1; 
} 

int RecvAll(SOCKET client_socket, string &data) 
{ 
    ulong data_size; 
    int result; 

    data = ""; 

    result = RecvAll(client_socket, &data_size, sizeof(data_size)); 
    if (result == 1) 
    { 
     data_size = ntohl(data_size); 
     if (data_size > 0) 
     { 
      data.resize(data_size); 

      result = RecvAll(client_socket, &data[0], data_size); 
      if (result != 1) 
       data.clear(); 
     } 
    } 

    return result; 
} 

... 

string data; 
int result; 
char reply; 

while (true) 
{ 
    result = RecvAll(socket, data); 
    if (result != 1) 
    { 
     if (read == 0) 
      cout << "client disconnected"; 
     else 
      cout << "error in read - " << WSAGetLastError(); 

     break; 
    } 

    // process data as needed... 

    reply = 1; 
    if (send(socket, &reply, 1, 0) == SOCKET_ERROR) 
    { 
     cout << "error in send - " << WSAGetLastError(); 
     break; 
    } 
} 
+0

謝謝,它比我的代碼更穩定 – Iceman