2014-03-01 71 views
0

我正在編寫一個客戶端請求登錄到服務器並可以請求查看其他客戶端的在線狀態的服務器/客戶端通信系統。我可以讓客戶端登錄正常,但是當我嘗試登錄(成功),然後發送另一個請求另一個客戶端信息的數據包時,服務器不會收到該數據包。如何連續發送和接收數據包?

服務器的主要部分,而不是技術方面的東西從綁定服務器開始:

Users client[2]; //I intialized them already 

//Bind 
bind(WelcomeSocket, (sockaddr*)&SvrAddr, sizeof(SvrAddr)); 

//listening 
listen(WelcomeSocket, 5); 

//temp users 
Users temp; 

//while loop for the connection 
while (1) { 

    ConnectionSocket = accept(WelcomeSocket, NULL, NULL); 



    if (recv(ConnectionSocket, RxBuffer, sizeof(RxBuffer), 0)) 
     cout << "WORKEDDDDDDDD" << endl; 

    memcpy(&temp, RxBuffer, sizeof(struct Users)); 

    cout << temp.message << temp.userName << endl << endl; 

    //check which message type is being sent 
    switch(temp.message) { 

    //if message type 1 
    case 1 : 
     for (int i = 0; i < 2; i++) { 

      //if receieved username matches with any username in the database 
      if (strcmp(temp.userName, client[i].userName) == 0) { 

       //assign the recieved users information to the matched one in database 
       strcpy(client[i].userName, temp.userName); 
       client[i].online = true; 
       client[i].message = 2; 

       cout << client[i].userName << endl << client[i].online << endl; 

       //send the acknowledgement packet 
       send(ConnectionSocket, (char *)&client[i], sizeof(struct Users), 0); 
      } 

     } 
     closesocket(ConnectionSocket); 
     break; 

    //if message type 3 
    case 3 : 
     cout << "3"; 
     break; 

    default : 
     break; 

    } 

} 

closesocket(ConnectionSocket); 
WSACleanup(); 
} 

客戶:

connect(ClientSocket, (sockaddr*)&SvrAddr, sizeof(SvrAddr)); 



//cout << "Name: "; 
//cin >> login; 

//Send request to login 
int log; 
char * name = new char[128]; 
char * request = new char[128]; 
Users client; 
Users talkto; 



    cout << "To login press (1). "; 
    cin >> log; 
    flushall(); 

    if (log == 1) { 

     cout << "Username : "; 
     cin.getline(name, 128, '\n'); 
     flushall(); 

     //Set client login info 
     strcpy(client.userName, name); 
     client.message = 1; 



     send(ClientSocket, (char *)&client, sizeof(struct Users), 0); 


     //Recieve acknowledgement 
     recv(ClientSocket, RxBuffer, sizeof(RxBuffer), 0); 
     //create temp users 
     Users temp; 

     memcpy(&temp, RxBuffer, sizeof(struct Users)); 



     if (temp.message == 2) { 

      cout << "Enter user for user information: "; 
      cin.getline(talkto.userName, 128, '\n'); 
      flushall(); 
      talkto.message = 3; 

      //send request for user information packet 
      if (send(ClientSocket, (char *)&talkto, sizeof(struct Users), 0)) 
      cout << "SENDT" << endl; 
     } 

     //cout << temp.userName << endl << temp.online << endl << temp.message; 

     closesocket(ClientSocket); 


WSACleanup(); 

}

用戶

struct Users { 

int message; 
char userName[50]; 
char ipAddress[50]; 
int PortNumber; 
bool online; 

}; 
結構

不知道爲什麼它不是多次接收信息

+0

您正在關閉情況1的交換機上的套接字,因此在它收到消息類型1後,它會斷開套接字。 –

+0

即使我不關閉套接字,我仍然遇到同樣的問題@DavidOtano – user2981393

+0

我知道爲什麼。你的'accept'函數阻塞了等待下一個客戶端的循環的其餘部分。 –

回答

0
ConnectionSocket = accept(WelcomeSocket, NULL, NULL); 

你應該把該循環之前,內部沒有,因爲accept功能正在等待另一個客戶端,從接收到另一包阻止你。

此外,當您recv調用返回0,這意味着連接已關閉,這是流的結束,所以你應該從你的迴路斷線時recv返回0,或一些意想不到的SOCKET_ERROR

+0

是的,這將有助於爲單個連接提供服務。但是任何其他客戶端在連接打開時將無法連接。 – Inspired

+0

@Inspired確實。 –

+0

令人驚歎!我做了一個if(n == 0)break;並在我的客戶端進行一些修復,並且工作正常!謝謝! – user2981393

0

對於每個客戶端連接,您的服務器執行accept-recv-send-closesocket。期。

服務器處理第一個數據包後關閉客戶端連接。在發送客戶端的每個數據包之前,您必須建立一個新的連接(但這可能會使您的登錄過程無用),或者使服務器能夠維持多個併發的客戶端連接,在無限循環中輪詢它們,也許在單獨的線程中(S)。

+0

我在服務器端的while(1)循環中有accept-recv-send-closesocket,但是我錯過了接受多個數據包的內容? – user2981393

+0

'accept'接受連接,而不是數據包。 – Inspired

+0

這是接受包的權利?在我的服務器中,recv沒有收到兩次數據包,它在第一次不知道爲什麼時會停止。 – user2981393