Socket端口复用
先说为什么要使用socket端口复用?如果你遇到过这样的问题:server程序重启之后,无法连接,需要过一段时间才能连接上?
1.一个监听(listen)server已经启动
2.当有client有连接请求的时候,server产生一个子进程去处理该client的事物.
3.server主进程终止了,但是子进程还在占用该连接处理client的事情.虽然子进程终止了,但是由于子进程没有终止,该socket的引用计数不会为0,所以该socket不会被关闭.
4.server程序重启。
这个时候由于端口已经被占用,所以无法重新再bind,这也使得TIME_WAIT状态设计的原因之一。
- int getsockopt(int sockfd, int level, int optname,
- void *optval, socklen_t *optlen);
- int setsockopt(int sockfd, int level, int optname,
- const void *optval, socklen_t optlen);
- int setsockopt(
- SOCKET s,
- int level,
- int optname,
- const char* optval,
- int optlen
- );
level:(级别): 指定选项代码的类型。
SOL_SOCKET: 基本套接口
IPPROTO_IP: IPv4套接口
IPPROTO_IPV6: IPv6套接口
IPPROTO_TCP: TCP套接口
optname(选项名): 选项名称
optval(选项值): 是一个指向变量的指针 类型:整形,套接口结构, 其他结构类型:linger{}, timeval{ }
optlen(选项长度) :optval 的大小
在bind之前添加源码,支持端口复用:
- int on = 1;
- if (setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,
- &on,sizeof(on)) == -1)
- err_exit("setsockopt SO_REUSEADDR error");
- void echo(int clientfd);
- int main()
- {
- int listenfd = socket(AF_INET, SOCK_STREAM, 0);
- if (listenfd == -1)