转自: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版上出现,其他平台又没有问题不得而知,由此可以看出成对编码的好处以及面向对象封装的好处。

socket:10038错误的更多相关文章

  1. java junit4-JUnit测试报 No socket available 错误

    问题描述 JUnit测试报 No socket available 错误 Eclipse进行JUnit测试时,总弹出 No socket available 窗口,导致测试不能进行. 解决方案一: 打 ...

  2. (转载) socket:10038错误{winSock的一个bug:当closesocket多次错误使用时会导致问题}

    这几天想在一个开源的代码上进行修改,以期研发出一个产品出来.       程序原来是单线程网络程序,需要修改为多线程,修改之后,总是出问题,辅助线程中的recv函数总是运行一阵子之后收到长度为-1的数 ...

  3. Socket常见错误

    一.简介 本文介绍 Socket 连接常见错误.   二.常见错误 1)ECONNABORTED 描述:"software caused connection abort",即&q ...

  4. jmeter接口测试报java.net.SocketException: Socket closed错误。

    如题,jmeter报出java.net.SocketException: Socket closed,我查询了下,服务器是正常的,可以返回数据,基本确定问题出在我这边jmeter.查询原因,看到有人说 ...

  5. socket 10060错误解决方案

    错误提示: socket 10060 无法加载或初始化请求的服务提供程序 解决方案: 打开cmd命令行工具,运行  netsh winsock reset

  6. Socket 连接错误及原因

    ECONNABORTED   该错误被描述为"software caused connection abort",即"软件引起的连接中止".原因在于当服务和客户 ...

  7. Java和.NET下socket转换错误记录

    一个项目,需要JAVA的Socket客户端转换为C#的Socket客户端,使用的是短连接. 首先,java客户端代码如下: Socket socket = new Socket(); socket.c ...

  8. socket 995 错误 boost

    这个错误的中文解释是:由于线程退出或应用程序请求,已中止 I/O 操作. 最近几天学习boost asio 在抄官方的一个实例代码时遇到 了,这个错误搞了我三天才解决,就是在一行代码中少了一个 s 所 ...

  9. 关于mysql连接抛出10038错误问题

    今天用Navicat Premium连接windows server 2003 mysql的时候, 抛出10038问题, 这种问题之前在rhel也出现过一次, 就是防火墙不允许连接kill掉了这个请求 ...

随机推荐

  1. Windows PyCharm永久激活

    1.下载 链接: https://pan.baidu.com/s/1LvQozk5lXdyk2p8qgGsr3A 提取码: x1t5 放置到 pycharm安装目录的\bin目录下(位置可随意,只要配 ...

  2. [LeetCode] 69. Sqrt(x)_Easy tag: Binary Search

    Implement int sqrt(int x). Compute and return the square root of x, where x is guaranteed to be a no ...

  3. css3--单行、多行文本溢出

    <style> .div1 { width: 200px; height: 200px; background: red url(img/user.png) no-repeat; text ...

  4. Amber TUTORIAL 4b: Using Antechamber to Create LEaP Input Files for Simulating Sustiva (efavirenz)-RT complex using the General Amber Force Field (GAFF)

    sustiva.pdb PDB: 1FKO Create parameter and coordinate files for Sustiva 1. 加氢: $ reduce sustiva.pdb ...

  5. cocos2d-x C++ (利用定时器自定义屏幕双击事件函数)

    //GameScene.h #include "cocos2d.h" USING_NS_CC; class GameScene : public cocos2d::Layer { ...

  6. 比较两种方式的form请求提交

    [一]浏览器form表单提交 表单提交, 适用于浏览器提交.像常见的pc端的网银支付,用户在商户商城购买商品,支付时商家系统把交易数据通过form表单提交到三方支付网关,然后用户在三方网关页面完成支付 ...

  7. React创建组件的不同方式(ES5 & ES6)

    一. 首先缕清楚React.createElement.React.createClass.React.Component之间的关系 1. React.createElement(HTML eleme ...

  8. Lambda表达式语法

    基础语法:‘->’Lambda操作符* 左侧:Lambda表达式的参数列表 对应接口中方法中的参数列表中的参数(比如nice1中MyPredict这个接口中的方法)* 右侧:Lambda表达式中 ...

  9. PLSQL乱码

    PLSQL乱码 博客分类: oracle oracleplsql乱码  问题:PL/SQL插入和更新乱码. 解决乱码问题需要关注的三点: 1. Oracle数据库内部的字符集 2. Oracle客户端 ...

  10. sqlserver 用一个表的值 更新另一个表

    update cas set cas.DocumentHeaderIdOfTransferredForForm = apply.Id from dbo.CaseTransfer cas join db ...