2012-04-10 3 views
2

Momentan erstelle ich eine Client-Server-Konsolenanwendung in C++. Unter Verwendung der winsock2.h-Bibliothek und des UDP-Protokolls verwenden wir sendto und recvfrom, um Nachrichten als Zeichenfolgen vom Client zum Server zu senden, der die Nachricht dann an einen anderen Client sendet, wenn der Client1 eine Nachricht an client2, client2 sendet empfängt die Nachricht erst, wenn sie versucht, eine Nachricht an Client1 zu senden. Ich möchte das Programm wie einen Instant Messenger funktionieren lassen, so dass client2 es fast sofort erhält, wenn client1 eine Nachricht an client2 sendet, ohne zuerst eine Nachricht senden zu müssen.Wie kann man ein synchrones Chat-Programm erstellen, um Nachrichten synchron zu senden und zu empfangen?

Auch wenn client1 eine Nachricht an client2 senden würde, wäre client1 nicht in der Lage, eine andere Nachricht zu senden, es sei denn, client2 hätte auf die erste geantwortet.

Wenn Sie weitere Informationen benötigen oder um Code zu sehen, fragen Sie einfach.

Der Code senden:

while(getline(cin, line)) 
{ 
    // send a string to the server. 
    sendto(hSocket, line.c_str(), line.size(), 0, 
     reinterpret_cast<sockaddr*>(&serverAddress), 
     sizeof(serverAddress)); 

    // recieve the response. 
    int n = recvfrom(hSocket, recvLine, MAXLINE, 0, NULL, NULL); 
    if(n == -1) 
    { 
     cout << "no reply" << endl; 
    } 
    else 
    { 
     recvLine[n] = 0; 
     string const terminateMsg = "server exit"; 
     string msg = recvLine; 
     if(msg == terminateMsg) 
     { 
      cout << "Server terminated" << endl; 
      break; 
     } 
     cout << n << ": " << recvLine << endl; 
    } 
} 
+1

Siehe [Boost.ASIO] (http://www.boost.org/libs/asio/). Es kommt sogar mit [einem Beispiel] (http://www.boost.org/doc/html/boost_asio/examples.html#boost_asio.examples.chat) für dieses genaue Szenario. – ildjarn

+0

@ildjarn danke, sie sind das Beispiel, was ich will, aber ich würde lieber mit der Winsock-Bibliothek bleiben – Beef

+1

Sie sind für viel mehr (sehr hässlich) Arbeit dann. ; -] – ildjarn

Antwort

1

jetzt, wenn die client1 eine Nachricht sendet an CLIENT2 client2 nicht die Meldung erhalten, bis sie eine Nachricht an client1 senden versuchen.

Sie haben es so codiert.

Auch wenn client1 eine Nachricht an client2 senden war, client1 nicht die Lage sein, eine andere Nachricht zu senden, es sei denn, client2 zum ersten geantwortet hatte.

Wieder haben Sie es so codiert. Ihr Code geht davon aus, dass jedem sendto() ein recvfrom() folgt. Aber deine Frage zeigt an, dass das nicht das ist, was du willst. Ich habe einige Kommentare zu Ihren Code unter

while(getline(cin, line)) 
{ 
    // send a string to the server. <-- will never get here a 2nd time through the loop without recvfrom() returning 
    sendto(hSocket, line.c_str(), line.size(), 0, 
     reinterpret_cast<sockaddr*>(&serverAddress), 
     sizeof(serverAddress)); 

    // recieve the response. <--- will never get here without getline() returning 
    int n = recvfrom(hSocket, recvLine, MAXLINE, 0, NULL, NULL); 
    if(n == -1) 
    { 
     cout << "no reply" << endl; 
    } 
    else 
    { 
     recvLine[n] = 0; 
     string const terminateMsg = "server exit"; 
     string msg = recvLine; 
     if(msg == terminateMsg) 
     { 
      cout << "Server terminated" << endl; 
      break; 
     } 
     cout << n << ": " << recvLine << endl; 
    } 
} 

Ich suche das Programm funktioniert wie ein Instant Messenger zu machen, so , dass, wenn client1 eine Nachricht sendet CLIENT2 client2 es erhalten fast sofort, ohne um zuerst eine Nachricht zu senden.

Verwenden Boost.Asio und asynchrone Steckdosen, die Asynchron chat_clientexample tut dies genau das, was perfekt TCP-Sockets verwenden, ist es ziemlich trivial ist das Beispiel für UDP zu ändern. Das asynchrone UDP echo server Beispiel kann ebenfalls nützlich sein. Sie möchten boost::asio::ip::udp::socket::async_recv_from() und boost::asio::ip::udp::socket::async_send_to() verwenden. Die anderen BSD-Socket-Schnittstellen weisen äquivalente Zuordnungen auf, die in der documentation beschrieben sind.

+0

danke, ich werde in was Sie in Ihren Kommentaren gesagt haben, und versuchen, die notwendigen Änderungen zu machen, in Bezug auf die Verwendung von Boost würde ich lieber mit der Winsock-Bibliothek bleiben, aber danke trotzdem – Beef

+0

@Beef Verwendung Boost, wird es machen dein Leben leichter. Es gibt keinen Grund, das Rad neu zu erfinden. Die Asio-Bibliothek hat eine ** explizite ** Zuordnung für die BSD-Socket-API. –

Verwandte Themen