Linux 下 Address already in use 错误的解决

原创 2015年07月10日 11:07:40

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来创建多个线程,这样属于一种硬编码的方式,有其资源共享的优点,但是会增加维护的复杂度。而一个程序同时执行多份的话,由于代码段共享的原因,系统同样不会有太大的内存开销,并且可以方便地由用户态决定启动多少个任务而不依赖代码实现。当然从资源消耗的角度来考虑的话,多线程还是更合适的。


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Linux服务启动报:Address already in use 解决方法:预留端口避免占用ip_local_reserved_ports

问题描述: 业务遇到这个情况,在重启服务时,出现50020端口被占用而无法启动, 非得等该端口释放后才启动成功。 问题分析: 50020端口被该服务器上的客户端 随机选取源端口给占用掉了。 ...
  • wzb56
  • wzb56
  • 2016年02月25日 08:29
  • 2198

Linux下Bind error: Address already in use处理

发生这种问题是由于端口被程序绑定而没有释放造成. 可以使用netstat -lp命令查询当前处于连接的程序以及对应的进程信息。 然后用ps pid 察看对应的进程,并使用kill pid 关闭该进...
  • lopper
  • lopper
  • 2012年03月10日 15:37
  • 16648

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

启动tomcat时报错:Address already in use [linux]

测试服务器  tomcat启动时,访问test.varkj.com :8080/sms/Auth/main时报错,查看日志 INFO [main] org.apache.catalina.star...

bind:address already in use的深刻教训以及解决办法

今天在linux下,编写了一个简单的回射客户/服务器(就是客户机从控制台标准输入并发送数据,服务端接受数据,但是不对数据进行处理,然后将数据返回,交由客户机标准输出),然后遇到了一些问题,郁闷了好长时...

Ubuntu下运行Goagent出现Address already in use问题解决方法

前文提到,在ubuntu下运行goagent方法为命令行输入: sudo python google_appengine/goagent-goagent-496b57e/local/proxy...

Linux下Socket编程的端口问题( Bind(): Address already in use )

Linux下Socket编程的端口问题( Bind(): Address already in use ) 转载请注明 本文引用地址 http://blog.csdn.net/xl_xunzhao/...

Linux 套接字编程中 bind 错误:bind fail:Address already in use 解决方法

最近在学Linux 网络编程,调试TCP并发服务器时遇到一个问题,当我连接上一个或多个客户端后,用 CTRL+C 关闭进程后,重新打开进程就发生错误了:bind fail:Address alread...

linux socket通信bind error:Address already in use

socket tcp 通信 绑定了ip 和 port 正常顺序 客户端发起socket 服务端收到socket的时候 没有问题 但是有时候,顺序错误,就导致程序死了 再起运行程序的时候...

socket编程小问题:地址已经被使用——Address already in use

很多socket编程的初学者可能会遇到这样的问题:如果先ctrl+c结束服务器端程序的话,再次启动服务器就会出现Address already in use这个错误,或者你的程序在正常关闭服务器端so...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux 下 Address already in use 错误的解决
举报原因:
原因补充:

(最多只允许输入30个字)