我是靠谱客的博主 个性吐司,最近开发中收集的这篇文章主要介绍socket重启 端口被占用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

问题描述

代码是linux上一个socket服务器端,客户端与其建立连接;Ctrl+c 结束socket服务器。再次重启服务器后,端口被占用,bind失败(Address already in use);需经过大约2分钟后,重启服务器方能再次使用。

问题分析

因为socket结束后,linux会保留此端口一定时间,据说是1~4分钟;过后才能再次被使用。

处理方法

设置SO_REUSEADDR选项可以解决此问题,关闭socket后可立即再使用端口。代码如下:

int 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重启 端口被占用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部