问题描述:
代码是linux上一个socket服务器端,客户端与其建立连接;Ctrl+c 结束socket服务器。再次重启服务器后,端口被占用,bind失败(Address already in use);需经过大约2分钟后,重启服务器方能再次使用。
问题分析:
因为socket结束后,linux会保留此端口一定时间,据说是1~4分钟;过后才能再次被使用。
处理方法:
设置SO_REUSEADDR选项可以解决此问题,关闭socket后可立即再使用端口。代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32int Socket_base::SocketInit(void) { int serverSocketFd = -1; int serverLen = 0; struct sockaddr_in serverAddress; // sockaddr_in for AF_INET /* Create and name a socket for the server. */ m_serverSocketFd = socket(AF_INET, SOCK_STREAM, 0); // use SO_REUSEADDR, so may use the port again immediately after restarting the socket int optval = 1; if (setsockopt(m_serverSocketFd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { perror("setsockopt error"); } int flags = fcntl(m_serverSocketFd, F_GETFL, 0); // get file flag fcntl(m_serverSocketFd, F_SETFL, flags | O_NONBLOCK); // set file Non-blocking, for "accept" use in while serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(SOCKET_PORT); serverLen = sizeof(serverAddress); if((bind(m_serverSocketFd, (struct sockaddr *)&serverAddress, serverLen)) < 0) { perror("bind error"); } /* Create a connection queue and initialize readFds to handle input from serverSocketFd. */ listen(m_serverSocketFd, 0); }
注意事项:
SO_REUSEADDR的设置的位置是在socket创建之后,bind之前。
即使在析构函数中对socket进行close也不能解决,因为Ctrl+c强制退出了,析构未执行。close是否有作用不确定。
最后
以上就是个性吐司最近收集整理的关于socket重启 端口被占用的全部内容,更多相关socket重启内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复