我编写了一个应该实现基于UDP协议的库。 我是主持人A,远程是主持人B. 我需要从主机A,端口7011发送消息到主机B端口7011.然后主机B将应答主机A,端口7011.通信是异步的,所以我需要udp来监听传入的消息,有时候也是我需要从服务器绑定到的同一端口发送消息。
以下是我创建和绑定套接字的方法:
udp_server::udp_server(const std::string &localAddress, int localPort)
: f_port(localPort), f_addr(localAddress) {
char decimal_port[16];
snprintf(decimal_port, sizeof(decimal_port), "%d", f_port);
decimal_port[sizeof(decimal_port) / sizeof(decimal_port[0]) - 1] = '\0';
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
int r(getaddrinfo(localAddress.c_str(), decimal_port, &hints, &f_addrinfo));
if (r != 0 || f_addrinfo == NULL) {
throw udp_client_server_runtime_error(
("invalid address or port for UDP socket: \"" + localAddress + ":" + decimal_port + "\"").c_str());
}
f_socket = socket(f_addrinfo->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
if (f_socket == -1) {
freeaddrinfo(f_addrinfo);
throw udp_client_server_runtime_error(
("could not create UDP socket for: \"" + localAddress + ":" + decimal_port + "\"").c_str());
}
r = bind(f_socket, f_addrinfo->ai_addr, f_addrinfo->ai_addrlen);
if (r != 0) {
freeaddrinfo(f_addrinfo);
close(f_socket);
throw udp_client_server_runtime_error(
("could not bind UDP socket with: \"" + localAddress + ":" + decimal_port + "\"").c_str());
}
}
我在这里尝试发送消息:
ssize_t udp_server::sendto(std::string remoteHost, uint16_t port, const char *message, size_t messageLength) {
struct sockaddr_in remote;
remote.sin_family = AF_INET;
remote.sin_port = htons(7011);
remote.sin_addr.s_addr = ::inet_addr("10.8.0.6");
socklen_t addrSize;
addrSize = sizeof(remote);
memset(remote.sin_zero, '\0', sizeof(remote.sin_zero));
dout << "messageLength: " << messageLength << std::endl;
return ::sendto(this->f_socket, message, messageLength, 0, (struct sockaddr *)&remote, addrSize);
}
但是:: sendto总是返回-1。并且errno设置为22,这意味着无效的参数。有什么可能的解决方案?也许整体结构不好。
===解决方案=== 我已将我的服务器绑定到locahost :( 应为0.0.0.0或INADDR_ANY。
答案 0 :(得分:0)
如果绑定到localhost
并尝试发送到非本地IP,则会发生此错误。
如果您希望能够从任何界面发送,则应绑定到0.0.0.0
。
此外,在udp_server::sendto
中,您将remote.sin_port
和remote.sin_addr
设置为硬编码值。您可能希望在此处使用remoteHost
和port
参数。