1. 使用getaddrinfo获取主机IP,这种方法受系统,hostname与IP的绑定配置有关,最后不要用localhost,一般localhost配置的IP为127.0.0.1
另一种方法是使用getifaddress,没用过
int getIP(char *host, char *buf, int size)
{
assert(host != NULL && buf != NULL);
struct addrinfo hints;
struct addrinfo *result, *rp;
int s, sfd;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;// make sure this IP can do bind
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
s = getaddrinfo(host, NULL, &hints, &result);
if(s != 0)
{
fprintf(stderr, "Failed to get IP of %s: %s\n", host, gai_strerror(s));
return -1;
}
for(rp = result; rp != NULL; rp = rp->ai_next)
{
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if(sfd < 0) continue;
s = bind(sfd, rp->ai_addr, rp->ai_addrlen);
//inet_ntop(rp->ai_family, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, size);
//DEBUG_PRINT(" ----ip IS %s\n", buf);
close(sfd);
if(s == 0) break;// we find one IP that can bind
}
if(rp != NULL)
{
// convert to ip str
inet_ntop(rp->ai_family, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, size);
DEBUG_PRINT("Got IP of %s is %s\n", host, buf);
}
// release buf
freeaddrinfo(result);
return (rp == NULL) ? -1 : 0;
}
2. Address already in use错误
写的一个py脚本需要多次listen在断开,但在第二次断开时,报了这个错。
因为TCP协议中有TIME_WAIT,要求端口在指定时间超时后才能再连接,避免后续的socket把先前尚未传送过来的包当做正常消息接受
可设置如下属性:sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1),这个要在绑定前调用,并且需要保证前次的bind相关的fd都close,否则会无效