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 ", 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 ", 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 ", 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,否则会无效