10048错误(WSAEADDRINUSE)的错误处理

来源:互联网 发布:mac mini diy 编辑:程序博客网 时间:2024/05/16 11:02

 这两天在工作的过程中发现基于socket的网络程序中时不时发生connect()调用失败的错误,通过获取错误码,发现是WSAEADDRINUSE(10048)的错误,MSDN的说明如下:     

      这种错误常常发生在bind函数中,当bind已经绑定的端口被占用后,再次绑定同一端口就会发生错误,但这一错误不影响bind的执行,换句话说,bind第二次执行并不发生错误,但是在紧接着调用connect()时会出错,错误码就是10048。       

      应用程序调用bind在使用随机端口绑定时,如果操作系统预留的1024~5000之间的端口都被占用着的话,bind不出错,connect会失败。       

      什么情况下端口会被全部占用?      

      情况一:如果每个端口上都正在进行数据操作,那么端口就都处于占用状态。          

      情况二:connect的频率太快,每一个socket在调用closesocket进行关闭操作后,虽然closesocket执行完毕,但是对应的占用端口并不是立即释放,这些端口需要继续处于占用状态,等待时间大约2ML(数据包最大生存周期),默认最大值为4分钟。用netstat命令查看端口状态,端口显示TIME_WAIT,在4分钟内如果对同一个端口进行connect,就会发生10048错误。     

      如何修正错误?     

     方法一: 如果使用了bind函数,那么可以对绑定的端口进行指定,如果调用connect失败,那么就返回bind处更改绑定端口,然后继续connect,直到成功为止。     

     方法二: 如果没有使用bind函数,直接使用connect进行连接,那么可以对connect操作进行retry,在这种情况下如果connect失败,那么它下次被调用时仍会使用调用失败的端口进行连接,直到连接成功。    

     retry的间隔时间和次数如何确定?     

     理想的设定是retry的间隔时间要尽量短,次数要尽量少,但这两者是相互矛盾的,往往retry的总时间是一定的,也就是说retry的时间间隔短了,次数就多了;retry的时间间隔长了,次数就少了。呵呵,这里感觉很不好选择,那么只有通过实际的程序测试来判断了。

原创粉丝点击