解决bind错误 bind: Address already in use

时间:2022-10-15 14:56:10

关于bind错误的处理:
bind: Address already in use

原因: 操作系统没有立即释放端口

解决一: 等待一段时间运行网络程序即可

解决二:通过setsockopt进行设置,关键代码如下。

         // 解决在close之后会有一个WAIT_TIME,导致bind失败的问题
int val = ;
int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(int));
if(ret == -)
{
printf("setsockopt");
exit();
}

举例:以多进程并发服务器为例

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h> #define PORT 7788 int init_tcp()
{
// 1.创建套接字 - 设置协议
int sfd = socket(AF_INET,SOCK_STREAM,);
if( - == sfd )
{
perror("socket");
exit(-);
}
//2. 解决在close之后会有一个WAIT_TIME,导致bind失败的问题
int val = ;
int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(int));
if(ret == -)
{
printf("setsockopt");
exit();
}
//3. 绑定IP和PORT
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons(PORT);
ret = bind(sfd,(struct sockaddr *)&saddr,sizeof(saddr));
if(ret == -)
{
printf("bind");
exit();
}
//4. 监听
ret = listen(sfd,);
if(ret == -)
{
printf("listen");
exit();
}
printf("Server is ready ... \n"); return sfd;
} void deal_communication(int cfd)
{
char buf[] = {'\0'};
while()
{
memset(buf,'\0',sizeof(buf));
recv(cfd,buf,sizeof(buf),);
printf("client say:%s\n",buf);
send(cfd,buf,strlen(buf),);
if(strncmp(buf,"quit",) == )
break;
} return ;
} int main()
{
//1. 初始化(创建套接字socket/地址复用+bind/listen)
int sfd = init_tcp();
//2. 并发处理客户端(accept / fork) 2-2通信
while()
{
int cfd = accept(sfd,NULL,NULL);
if(cfd == -)
{
perror("accept");
exit();
} // fork - create a child process
if(fork() == )
{
deal_communication(cfd);
close(cfd);
exit();
}
close(cfd);
signal(SIGCHLD,SIG_DFL);
}
close(sfd);
return ;
}