目前我正在用c ++创建一个客户端服务器控制台应用程序。通过使用winsock2.h
库和UDP协议,我们使用sendto
和recvfrom
将消息作为字符串从客户端发送到服务器,然后服务器将消息发送到不同的客户端,现在,如果client1向client2发送消息,则client2在尝试向client1发送消息之前不会收到消息。我希望使程序像即时消息一样工作,这样当client1向client2发送消息时,client2几乎可以立即收到它而无需先发送消息。
此外,如果client1要向client2发送消息,则client1将无法发送另一条消息,除非client2已回复第一条消息。
如果您需要更多信息或查看一些代码,请询问。
发送代码:
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;
}
}
答案 0 :(得分:1)
现在,如果client1向client2发送消息,则client2不会 接收消息,直到他们尝试向client1发送消息。
你已经用这种方式编码了。
此外,如果client1要向client2发送消息,则client1不会 能够发送另一条消息,除非client2回复了 第一个。
同样,你已经用这种方式编码了。您的代码假定每sendto()
后跟一个recvfrom()
。但是你的问题表明这不是你想要的。我在下面的代码中添加了一些注释
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;
}
}
我希望让程序像即时消息一样工作,所以 当client1向client2发送消息时,client2将接收它 几乎立即无需先发送消息。
使用Boost.Asio和异步套接字,async chat_client example使用TCP套接字完美地完成了这项工作,修改UDP的示例非常简单。异步UDP echo server示例也可能有用。您需要使用boost::asio::ip::udp::socket::async_recv_from()
和boost::asio::ip::udp::socket::async_send_to()
。其他BSD套接字接口具有documentation中描述的等效映射。