2011-08-22 90 views
0

我想使用Winsock2製作一個程序,我可以從客戶端向服務器發送消息。我可以做到這一點,但問題是我只能發送一條消息,然後我必須重新啓動服務器才能收到下一條消息。這是服務器的代碼。我真的很困惑的部分是我在while循環中有recv()函數,爲什麼它不會繼續「接收」數據?接收多條消息Winsock2 C++

WSADATA wsaData; 
    int bytes_recieved; 
    char data_recieve[2048]; 
    string output; 

    WSAStartup(MAKEWORD(2, 2), &wsaData); 
    SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

    SOCKADDR_IN ServerInfo; 
    ServerInfo.sin_family = AF_INET; 
    ServerInfo.sin_addr.s_addr = INADDR_ANY; 
    ServerInfo.sin_port = htons(8888); 

    bind(ListenSocket, (LPSOCKADDR)&ServerInfo, sizeof(struct sockaddr)); 
    listen(ListenSocket, 1); 
    SOCKET ClientSocket = accept (ListenSocket, NULL, NULL); 

    while(true) 
    { 
     bytes_recieved = recv(ClientSocket, data_recieve, 2048, 0); 
      if (bytes_recieved > 1) 
      { 
       cout << data_recieve; 
      } 
    } 

    closesocket(ClientSocket); 
    closesocket(ListenSocket); 
    WSACleanup(); 

下面列出了客戶端(發件人)。

WSADATA wsaData; 
int bytes_sent; 
char send_msg[] = "super cool message!"; 

WSAStartup(MAKEWORD(2, 2), &wsaData); 
SOCKET ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
sockaddr_in ConnectInfo; 

ConnectInfo.sin_family = AF_INET; 
ConnectInfo.sin_addr.s_addr = inet_addr("127.0.0.1"); 
ConnectInfo.sin_port = htons(8888); 

connect(ConnectSocket, (SOCKADDR*)&ConnectInfo, sizeof(ConnectInfo)); 
bytes_sent = send(ConnectSocket, send_msg, sizeof(send_msg), 0); 
closesocket(ConnectSocket); 
WSACleanup(); 

我正在用MinGW編譯器在Windows 7中執行此操作。先謝謝你。

回答

2

您沒有顯示您的客戶端正在發送代碼,但是您的服務器讀取代碼沒有考慮到在TCP/IP編程中發送和接收不是1對1。如果客戶端發送2條消息,則服務器可能會在同一個讀取操作中接收到這兩個消息,甚至是部分消息!你告訴你的服務器套接字一次讀取2048個字節。它將返回當前在套接字上可用的任何內容。 TCP/IP是一個字節流,你需要對待它。這意味着你需要在你的消息之間加一個分隔符,或者在它們周圍放一個框架,以便知道一個消息的結束位置和下一個消息的開始位置。

+0

這是一個很好的觀點。有沒有關於這方面的任何文件?我可以挖掘簡單的Winsock指南,但是我找不到你描述的內容。 – llk

+0

本教程可能會有所幫助:http://www.codeproject.com/Articles/37496/TCP-IP-Protocol-Design-Message-Framing –