Linux 下 Address already in use 错误的解决

来源:互联网 发布:职业资格证书制作软件 编辑:程序博客网 时间:2024/06/05 10:22

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为一文件描述词,非socketENOPROTOOPT 参数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
原创粉丝点击