我在使用UDP和SFML进行客户端 - 服务器连接时出现了一些奇怪的问题,我正在慢慢地想出可能出错的想法,所以也许有人能够帮助我。
目前我可以将客户端连接到服务器并从服务器向客户端发送消息。当我终止客户端应用程序并重新启动它(在同一台机器上)时,提供相同的服务器连接参数,没有任何反应。似乎没有建立连接。客户端只是在等待消息格式服务器,而服务器则在不断地同时发送消息。
我的服务器端看起来像这样:
openstack_networks
和我的客户:
std::shared_ptr<sf::UdpSocket> startUdpServer()
{
std::cout << "Local address: ";
std::cout << sf::IpAddress::getLocalAddress().toString() << std::endl;
std::cout << "Public address: ";
std::cout << sf::IpAddress::getPublicAddress().toString() << std::endl;
std::shared_ptr<sf::UdpSocket> socket(new sf::UdpSocket());
if(socket->bind(sf::Socket::AnyPort) != sf::Socket::Done)
return nullptr;
std::cout << "Server is listening to port " << socket->getLocalPort() << ", waiting for a message... " << std::endl;
return socket;
}
std::pair<sf::IpAddress, unsigned short> runUdpServer(std::shared_ptr<sf::UdpSocket> socket)
{
// Wait for a message
char in[128];
std::size_t received;
sf::IpAddress sender;
unsigned short senderPort;
if (socket->receive(in, sizeof(in), received, sender, senderPort) != sf::Socket::Done)
{
std::cout << "Connection error" << std::endl;
return std::make_pair(sender, senderPort);
}
std::cout << "Message received from client " << sender << ": \"" << in << "\"" << std::endl;
return std::make_pair(sender, senderPort);
}
void sendUdpMessage(std::shared_ptr<sf::UdpSocket> socket, std::pair<sf::IpAddress, unsigned short> config,
std::string message)
{
const char* out = message.c_str();
if (socket->send(out, sizeof(char) * message.length(), config.first, config.second) != sf::Socket::Done)
{
std::cout << "Message not send" << std::endl;
return;
}
}
void sendMessages(std::shared_ptr<sf::UdpSocket> socket, std::pair<sf::IpAddress, unsigned short> config)
{
if(config.first != sf::IpAddress::None)
{
while(true)
sendUdpMessage(socket,config,"Test msg");
}
else
std::cout << "Message sending error" << std::endl;
}
auto socket = startUdpServer();
auto config = runUdpServer(socket);
std::thread messages_thread(sendMessages,socket,config);
答案 0 :(得分:1)
通过网络,有两个非常重要的关键注意事项要记住UDP和TCP。
TCP - 基于连接,这意味着每当它尝试向其发送消息时,它需要在另一端有人。
UDP--基于无连接,这意味着他会将信息发送到您想要的地方。他可以发送和接收信息,但为了接收数据,他需要绑定到端口。因此,在您的服务器中,您每次都将它绑定到同一个端口。
在您的客户端,您正在给他一个端口来发送信息,而不是将他绑定到特定端口。每当您关闭客户端时,他都应该释放端口,每当您重新启动客户端时,如果您希望他能够从您的服务器接收数据,他应该绑定到同一个端口。如果你没有发生什么事情,那么数据会被发送到它所发送的IP和端口,但是没有与该端口相关联的应用程序,因此数据包丢失了。
答案 1 :(得分:1)
为了通过UDP在双方之间进行通信,每一方都需要一个唯一的(地址,端口)对。通常,服务器将其套接字绑定到固定/已知端口,客户端端口因客户端而异 - 因此允许多个客户端与同一服务器通信,每个客户端都在自己的端口上。
如果您的客户端(如此处)没有明确地将其套接字绑定到端口,则操作系统将动态分配&#34;随机&#34;未使用的端口,并在第一次使用端口时自动绑定它以发送数据。只要该客户端继续使用相同的套接字,端口号就是固定的。
但是,当您重新启动客户端时,它会获得一个 new 套接字,并且在第一次使用新套接字发送时,操作系统会将套接字绑定到新端口。但是,您的服务器假设客户端端口号仍然是从第一个客户端收到的号码。
由于它的工作方式,对于UDP服务器,通常的模式是每个消息都是独立的。服务器每次收到消息时都会记下客户端的地址和端口号,然后回复该地址/端口。服务器通常不会假设任何两个连续的消息来自同一个客户端,因为它无法知道任何给定的客户端何时消失。
(你可以在UDP上构建你自己更持久的#34;连接&#34;概念 - 例如NFS传统上做的 - 但这是需要大量工作的在设计协议时要小心谨慎。它在上述相同的基本模型中工作。)
您的客户端也可以始终显式绑定到您选择的端口。但是,这会限制您在任何一台计算机上运行一个客户端实例(实际上,在任何一个网络地址上)。