我已经创建了代码,用于将新套接字绑定到计算机的地址,以侦听特定端口上的传入连接。我正在使用getaddrinfo。这是最好的方法吗?将端口整数转换为字符串似乎毫无意义。有没有一种不需要sprintf就能做到这一点的方法?
bool CBSocketBind(void * socketID,u_int16_t port){
struct addrinfo hints,*res,*ptr;
int socketIDInt;
// Set hints for the computer's addresses.
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
// Get host for listening
char portStr[6];
sprintf(portStr, "%u",port);
if (getaddrinfo(NULL, portStr, &hints, &res) != 0)
return false;
// Attempt to bind to one of the addresses.
for(ptr = res; ptr != NULL; ptr = ptr->ai_next) {
if ((socketIDInt = socket(ptr->ai_family, ptr->ai_socktype,ptr->ai_protocol)) == -1)
continue;
if (bind(socketIDInt, ptr->ai_addr, ptr->ai_addrlen) == -1) {
close(socketIDInt);
continue;
}
break; // Success.
}
freeaddrinfo(res);
if (ptr == NULL) // Failure
return false;
socketID = malloc(sizeof(int));
*(int *)socketID = socketIDInt; // Set socket ID
// Make socket non-blocking
fcntl(socketIDInt,F_SETFL,fcntl(socketIDInt,F_GETFL,0) | O_NONBLOCK);
return true;
}发布于 2012-07-17 03:43:15
getaddrinfo()的设计旨在适应任何网络协议,这些协议可能对特定服务使用不同的名称。指定的端口号可以不是数字,也可以使用大于TCP使用的16位整数端口号的数字。为了获得最大的灵活性,可以提供服务名称,该服务名称可以被转换为协议以及该协议特有的任何其它信息,例如ftp TCP IPv4或IPv6→端口21。如果您知道您将始终使用IPv4或IPv6和TCP,那么您可以传递NULL作为服务名,并在返回的套接字地址结构(对于IPv4为sin_port字段,对于IPv6为sin6_port字段)中自己填充端口号。但是,只使用sprintf()可能更干净;这将处理IPv4和IPv6使用的不同套接字地址结构,以及以网络字节顺序存储端口号的要求,并且还允许您在不更改代码的情况下支持其他未来协议。
发布于 2012-07-17 00:46:05
getaddrinfo()接受字符串而不是整数的原因是服务不一定只是一个端口。例如,用户可以请求服务"http“。
发布于 2012-07-17 00:42:58
这看起来相当习惯于在AI_PASSIVE状态下如何使用getaddrinfo()。字符串化的数字是典型的。
https://stackoverflow.com/questions/11508634
复制相似问题