首先来说一下为什么要设置端口复用,有些时候在调试服务器代码时势必会经常启动或结束服务器进程,这样就会出现当再次启动服务器时有可能会出现端口绑定失败的情况,造成这个情况的原因是由于你上次关闭服务器时有连接尚未断开等等其他原因,出现绑定失败也是系统的一个机制,当端口绑定的进程结束时系统会保留一段时间端口的绑定状态,等过一会再去启动服务器时就又可以绑定成功了。
也有一种方法,可以实现程序关闭时,立即启动也可以绑定成功,那就是设置端口复用,下面介绍了如何在Windows和Linux下设置端口复用
Windows/Linux下设置端口复用
Windows和Linux系统下都是使用setsockopt
函数来设置端口复用
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
// sockfd:要设置的文件描述符(包括套接字)
// level:级别,端口复用对应的是SOL_SOCKET
/* optname:选项的名字,下面是复用的选项SO_REUSEADDR:允许将套接字绑定到已在使用中的地址(地址复用)SO_REUSEPORT:允许将套接字绑定到已在使用中的端口(端口复用)**Windows下没有这个选项,设置SO_REUSEADDR可以达到同样的效果**
*/
// optval:设置optname选项的值,复用对应的都是int类型
// optlen:optval参数的大小
// 返回值:设置成功返回0,否则返回非0(Linux下返回-1,Windows下返回SOCKET_ERROR)
注意这个函数的调用要在套接字创建之后,绑定之前
示例代码
// 创建套接字
int fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
{std::cout << "网络初始化失败\n";return;
}int optval = 1;
// 设置端口复用【Windows下不用设置,因为没有SO_REUSEPORT】
int ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
printf("%s(%d): ret=%d\n", __FILE__, __LINE__, ret);
// 设置地址复用
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
printf("%s(%d): ret=%d\n", __FILE__, __LINE__, ret);sockaddr_in addr{}, clientAddr{};
socklen_t cliAddrLen = sizeof(clientAddr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY; // INADDR_ANY所有的意思
addr.sin_port = htons(9556); // htons主机到网络
// 绑定端口
if (bind(fd, (sockaddr *)&addr, sizeof(addr)) < 0)
{std::cout << "服务器绑定端口失败\n";close(fd);return;
}
到这里,windows和Linux下设置套接字端口复用就介绍完了
感谢观看学习,大佬们多多指点,愿明天的自己会感谢当下的努力!!!!