zoukankan      html  css  js  c++  java
  • socket:10038错误

    转自:http://blog.csdn.net/chen495810242/article/details/42029825

    winSock的一个bug:当closesocket多次错误使用时会导致问题

           这几天想在一个开源的代码上进行修改,以期研发出一个产品出来。
           程序原来是单线程网络程序,需要修改为多线程,修改之后,总是出问题,辅助线程中的recv函数总是运行一阵子之后收到长度为-1的数据报,导致程序运行不正确甚至崩溃。
            由于是多线程,只好打日志进行调试,发现一个奇怪的问题。在A线程与B线程中,均使用了socket这个函数来产生socket,竟然会产生两个相同返回值的socket!也就是说,A线程与B线程能同时获得socket值为360的socket,这样当A正在使用360进行数据接收时,B去连接一把,A自然就出错了。

            这个问题实在是诡异,因为socket又不是COM组件,是可以直接在线程中共享的,究竟是出了什么问题呢,MSDN和网络上没有见到任何与此问题相关的内容。活脱脱地就是API出错了!按道理这是不可能的事情啊。
             实在没辙了,只好review代码,发现程序中有很多这样的语句:
            if( mSocket != INVALID_SOCKET )
            {
                    closesocket( mSocket );
             }
            这句有什么问题没有?呵呵看起来没什么问题,但是,不容置疑的是,肯定会导致一个socket被关闭多次。本着死马当着活马医的原则,进行修改,每次closesocket之后,将socket的值置为INVALID_SOCKET,运行程序,问题解决。

             这个问题也太ft了,windows竟然连这个容错都没有做,按道理这是很好做的,socket实际上只是一个索引值,系统内核在关闭时如果发现已经关闭就不要做操作就可以了。现在看起来,内核里面貌似是一个socket缓冲池,程序在使用的时候使用计数来管理生命周期。这样当一个socket被关闭多次后,再创建改socket之后,系统可能会认为该socket是关闭的(因为计数小于等于0)。所以下次分配的时候,会将该索引重新分配出去。

           该问题在vista home版上出现,其他平台又没有问题不得而知,由此可以看出成对编码的好处以及面向对象封装的好处。

  • 相关阅读:
    【IDEA】IDEA自定义注解无法自动识别入参和出参
    vue脚手架安装成功,但依然提示'vue' 不是内部或外部命令,也不是可运行的程序 或批处理文件。解决方案
    小程序怎么将input宽输入字母全部转大写字母
    微信小程序van-popup左右弹窗无法显示白色背景
    vscode中实现滚轮缩放代码
    element-ui监听el-dialog关闭事件
    测试人必看的5本好书,没看过你就吃亏啦~
    解决Access在Windows7下数据源的配置问题(32位)
    微软Win10补丁KB5005565更新后打印机连接不上(0x0000011b)
    Windows设置共享文件夹无法访问问题
  • 原文地址:https://www.cnblogs.com/yorkyang/p/7384354.html
Copyright © 2011-2022 走看看