关闭

Linux 下 Address already in use 错误的解决

标签: 服务器端口LinuxsocketC
10511人阅读 评论(0) 收藏 举报
分类:

Linux 下 Address already in use 错误的解决

Address already in use 解决方法

    当客户端保持着与服务器端的连接,这时服务器端断开,再开启服务器时会出现: Address already in use的错误。
    可以用netstat -anp | more 可以看到客户端还在使用服务器的端口。这是由于client没有执行close。连接还会等待client的FIN包一段时间。
    解决方法:使用setsockopt函数,使得该socket使用的端口可以被重用。
    具体的做法:在socket调用和bind调用之间加上对socket的设置的代码:    

int opt = 1;
setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

setsockopt的用法

    附 :setsockopt的用法。

函数定义:
    int setsockopt(int s,int level,int optname,const void * optval,,socklen_toptlen);
函数说明 :
    setsockopt()用来设置参数s所指定的socket状态。参数level代表欲设置的网络层,一般设成SOL_SOCKET以存取socket层。参数optname代表欲设置的选项,有下列几种数值:
SO_DEBUG 打开或关闭排错模式
SO_REUSEADDR 允许在bind()过程中本地地址可重复使用
SO_TYPE 返回socket形态。
SO_ERROR 返回socket已发生的错误原因
SO_DONTROUTE 送出的数据包不要利用路由设备来传输。
SO_BROADCAST 使用广播方式传送
SO_SNDBUF 设置送出的暂存区大小
SO_RCVBUF 设置接收的暂存区大小
SO_KEEPALIVE 定期确定连线是否已终止。
SO_OOBINLINE 当接收到OOB 数据时会马上送至标准输入设备
SO_LINGER 确保数据安全且可靠的传送出去。
参数: 
optval代表欲设置的值,参数optlen则为optval的长度。
返回值: 
成功则返回0,若有错误则返回-1,错误原因存于errno。
附加说明: 
EBADF 参数s并非合法的socket处理代码
ENOTSOCK 参数s为一文件描述词,非socket
ENOPROTOOPT 参数optname指定的选项不正确。
EFAULT 参数optval指针指向无法存取的内存空间

SO_REUSEADDR详解

   
     对于监听套接字,如果在bind之前对socket定义了SO_REUSEADDR,并且同时有两个套接字在同一个端口上进行接听,两个socket都进行ACCEPT,那么谁真正得到客户端的连接是具有随机性的,但必然会有一个socket来处理这个连接。如果定义了SO_REUSEADDR,只定义一个socket在一个端口上进行监听,如果服务器出现意外而导致没有将这个端口释放,那么服务器重新启动后,你还可以用这个端口,因为你已经规定可以重用了,如果你没定义的话,你就会得到提示,ADDR已在使用中。
    另外,SO_REUSEADDR也使用在服务器的负载均衡领域,也就是:
1. 可以同时让多个进程处理请求,负载均衡。
2. 避免一个进程崩溃时,在重新启动前,无法及时提供服务。

    当两个socket的address和port相冲突,而你又想重用地址和端口,则旧的socket和新的socket都要已经被设置SO_REUSEADDR特性,只有两者之一有设置SO_REUSEADDR还是会有问题。

一些网络基础

端口侦听:
    系统中的端口地址是唯一的,在默认情况下,IPV4和IPV6的同一个协议的套接口也最好不要绑定在同一个端口上,而socket编程的五元组就是 "IP,port,peerip,peerport,inet proto"。但有时候为了实现负载平衡,可能希望有多个进程来侦听同一个套接口,从而并发执行某个任务,此时就希望多个相同的进程(相同的可执行文件)来对同一个套接口进行侦听,从而完成负载分流和平衡。
    当然,多线程也是一种实现方法,但是缺点就是需要实现用户态编码,不对可执行程序透明,用户态的代码需要自己调用pthread_create来创建多个线程,这样属于一种硬编码的方式,有其资源共享的优点,但是会增加维护的复杂度。而一个程序同时执行多份的话,由于代码段共享的原因,系统同样不会有太大的内存开销,并且可以方便地由用户态决定启动多少个任务而不依赖代码实现。当然从资源消耗的角度来考虑的话,多线程还是更合适的。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:88505次
    • 积分:1060
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:0篇
    • 译文:0篇
    • 评论:2条
    文章分类
    文章存档
    经验交流与合作
    Email: 1967438171@qq.com QQ: 1967438171