当我尝试使用 SFML 将 UDP 套接字绑定到端口时,为什么会出现错误?
Why do i get an error when i try to bind my UDP socket to a port with SFML?
我目前正在使用 UDP 为 SFML 构建网络原型。我创建了一个应用程序,您可以在其中选择作为服务器或客户端。所以,通常我启动应用程序的 2 个实例,让一个作为服务器,另一个作为客户端。我正在连接到我的本地 IP 127.0.0.1.
大约 20 分钟前,这个精确的代码起作用了,我没有遇到任何问题。我没有做任何更改,但是这段代码不再起作用,当我为服务器调用 socket.bind()
时程序崩溃了。客户端,没有错误显示。
这是用 C++ 完成的。
有人知道这可能是什么原因吗?据我所知,这个端口也没有被使用。
我的客户代码:
void runUdpClient(unsigned short port){
sf::IpAddress server;
do
{
std::cout << "Type the address or name of the server to connect to: ";
std::cin >> server;
} while (server == sf::IpAddress::None);
sf::UdpSocket socket;
sf::Packet clientSendPacket;
std::string packetSendContent = "Packet data from the client";
clientSendPacket << packetSendContent;
if (socket.send(clientSendPacket, server, port) != sf::Socket::Done)
return;
std::cout << "Message sent to the server: \"" << packetSendContent << "\"" << std::endl;
// Maak variabelen
sf::IpAddress sender;
unsigned short senderPort;
sf::Packet clientReceivePacket;
std::string clientReceiveContent;
if (socket.receive(clientReceivePacket, sender, senderPort) != sf::Socket::Done)
return;
clientReceivePacket >> clientReceiveContent;
std::cout << "Message received from " << sender << ": \"" << clientReceiveContent << "\"" << std::endl;
}
我的服务器代码:
void runUdpServer(unsigned short port){
sf::UdpSocket socket;
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
std::cout << "Server is listening to port " << port << ", waiting for a message... " << std::endl;
sf::Packet serverReceivePacket;
std::string serverReceiveContent;
sf::IpAddress sender;
unsigned short senderPort;
if (socket.receive(serverReceivePacket, sender, senderPort) != sf::Socket::Done)
std::cout << "Error receiving packet for server";
return;
serverReceivePacket >> serverReceiveContent;
std::cout << "Message received from client " << sender << ": \"" << serverReceiveContent << "\"" << std::endl;
sf::Packet serverSendPacket;
std::string serverSendContent = "Packet data from server";
serverSendPacket << serverSendContent;
if (socket.send(serverSendPacket, sender, senderPort) != sf::Socket::Done)
std::cout << "Error sending packet from server";
return;
std::cout << "Message sent to the client: \"" << serverSendContent << "\"" << std::endl;
}
您的服务器很可能在没有正确关闭端口的情况下关闭。
如果您等待几分钟,端口将可以再次免费使用(在我的 Ubuntu 16.04 系统上大约需要 2-3 分钟,可能会有所不同,具体取决于您使用的 OS)
或者,您可以更改正在使用的端口。
问题出在 if
和 return
的格式上。按 Ctrl+Shift+K 后,代码再次格式化并且有效。
在您的服务器代码中,if
语句缺少大括号,因此您总是在 socket.bind()
退出时立即执行 return
,无论它是成功还是失败。此代码:
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
与此代码相同:
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
这在逻辑上等同于此代码:
if (socket.bind(port) != sf::Socket::Done) {
std::cout << "Error binding socket for server";
}
return;
空格格式对 C 和 C++ 并不重要。要在 if
块的主体内执行多个语句,您需要显式大括号:
if (socket.bind(port) != sf::Socket::Done)
{
std::cout << "Error binding socket for server";
return;
}
与服务器调用 socket.receive()
和 socket.send()
的 if
语句相同。
如果 socket.send()
或 socket.receive()
失败,您的客户端代码不会输出任何错误消息,这些 if
语句在其主体中执行单个语句(即,仅 return
), 所以大括号是可选的。
我目前正在使用 UDP 为 SFML 构建网络原型。我创建了一个应用程序,您可以在其中选择作为服务器或客户端。所以,通常我启动应用程序的 2 个实例,让一个作为服务器,另一个作为客户端。我正在连接到我的本地 IP 127.0.0.1.
大约 20 分钟前,这个精确的代码起作用了,我没有遇到任何问题。我没有做任何更改,但是这段代码不再起作用,当我为服务器调用 socket.bind()
时程序崩溃了。客户端,没有错误显示。
这是用 C++ 完成的。
有人知道这可能是什么原因吗?据我所知,这个端口也没有被使用。
我的客户代码:
void runUdpClient(unsigned short port){
sf::IpAddress server;
do
{
std::cout << "Type the address or name of the server to connect to: ";
std::cin >> server;
} while (server == sf::IpAddress::None);
sf::UdpSocket socket;
sf::Packet clientSendPacket;
std::string packetSendContent = "Packet data from the client";
clientSendPacket << packetSendContent;
if (socket.send(clientSendPacket, server, port) != sf::Socket::Done)
return;
std::cout << "Message sent to the server: \"" << packetSendContent << "\"" << std::endl;
// Maak variabelen
sf::IpAddress sender;
unsigned short senderPort;
sf::Packet clientReceivePacket;
std::string clientReceiveContent;
if (socket.receive(clientReceivePacket, sender, senderPort) != sf::Socket::Done)
return;
clientReceivePacket >> clientReceiveContent;
std::cout << "Message received from " << sender << ": \"" << clientReceiveContent << "\"" << std::endl;
}
我的服务器代码:
void runUdpServer(unsigned short port){
sf::UdpSocket socket;
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
std::cout << "Server is listening to port " << port << ", waiting for a message... " << std::endl;
sf::Packet serverReceivePacket;
std::string serverReceiveContent;
sf::IpAddress sender;
unsigned short senderPort;
if (socket.receive(serverReceivePacket, sender, senderPort) != sf::Socket::Done)
std::cout << "Error receiving packet for server";
return;
serverReceivePacket >> serverReceiveContent;
std::cout << "Message received from client " << sender << ": \"" << serverReceiveContent << "\"" << std::endl;
sf::Packet serverSendPacket;
std::string serverSendContent = "Packet data from server";
serverSendPacket << serverSendContent;
if (socket.send(serverSendPacket, sender, senderPort) != sf::Socket::Done)
std::cout << "Error sending packet from server";
return;
std::cout << "Message sent to the client: \"" << serverSendContent << "\"" << std::endl;
}
您的服务器很可能在没有正确关闭端口的情况下关闭。 如果您等待几分钟,端口将可以再次免费使用(在我的 Ubuntu 16.04 系统上大约需要 2-3 分钟,可能会有所不同,具体取决于您使用的 OS)
或者,您可以更改正在使用的端口。
问题出在 if
和 return
的格式上。按 Ctrl+Shift+K 后,代码再次格式化并且有效。
在您的服务器代码中,if
语句缺少大括号,因此您总是在 socket.bind()
退出时立即执行 return
,无论它是成功还是失败。此代码:
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
与此代码相同:
if (socket.bind(port) != sf::Socket::Done)
std::cout << "Error binding socket for server";
return;
这在逻辑上等同于此代码:
if (socket.bind(port) != sf::Socket::Done) {
std::cout << "Error binding socket for server";
}
return;
空格格式对 C 和 C++ 并不重要。要在 if
块的主体内执行多个语句,您需要显式大括号:
if (socket.bind(port) != sf::Socket::Done)
{
std::cout << "Error binding socket for server";
return;
}
与服务器调用 socket.receive()
和 socket.send()
的 if
语句相同。
如果 socket.send()
或 socket.receive()
失败,您的客户端代码不会输出任何错误消息,这些 if
语句在其主体中执行单个语句(即,仅 return
), 所以大括号是可选的。