private void ReadCallback(IAsyncResult ar)
        {
            try
            {
                MyObject state = (MyObject)ar.AsyncState;
                Socket clientSocket = state.workSocket;
                string srecv = "";                Int32 bytesRead = clientSocket.EndReceive(ar);
                if (bytesRead > 0)
                {
                    srecv = (Encoding.Default.GetString(state.buffer, 0, bytesRead));
                       if (srecv.Contains("投票成功"))
                    {
                     textBox1.Invoke((MethodInvoker)delegate { textBox1.AppendText( state.user+ "投票成功\r\n"); });
                      clientSocket.Close();
                     }
                  
................................//这里省略很多代码                }   程序大致接收代码如上. 出现N多的time_wait...多线程投票器,运行后循环的获取网页,结果造成很多的time_wait状态的半连接,达到一定数量造成网络直接断开.我知道可以通过添加注册表健值的方法缩短time_wait的停留时间,但最少也要30秒,这样我的程序很没效率...诚意求不出现time_wait的方法,我也知道这是TCP协议的正常现象,但是肯定有办法可以不出现time_wait半连接的(比如程序运行时有很多的 ESTABLISHED连接时我们直接关闭程序后一个连接都没有了)... 这问题折磨我N久了,帮忙解决了的网友酬谢200元!

解决方案 »

  1.   

    我是模拟出N多的IE客户端,并非服务器程序,大家看问题时注意区分呀
      

  2.   

    哪怕一个方法,一句代码,只要程序不出现time_wait我就会兑现我的承诺!
      

  3.   

    一般网页字节数较多的,我们接收到需要的内容时就clientSocket.Close();不会出现time_wait之类的半连接,但我现在这个业务返回的网页只有一行投票成功或失败的语句,长度不过几百字节..郁闷了.我设了public const int BufferSize = 32; 出现投票成功时后面应该还有内容,我clientSocket.Close();仍旧有N多的time_wait出现
      

  4.   


    你好.我真的非常真诚的..这问题以前请教过多次了,但都没有人会呢...按tcpip协议规则,主动关闭连接的一方就会进入time_wait状态,这个肯定会很影响程序运行效率的呀,我不知道高手是怎么做网络爬虫类程序的.
      

  5.   

    用多线程或者分布式多进程去处理
    把页面进行水平分割,每个线程处理一段,可使用BackGroundWorker 
    参考
      

  6.   

    UDP是肯定不行的,HTTP协议是TCP的~
    不过我怎么没遇见过“time_wait”异常?不了解
      

  7.   

    你在网页做一个frame和一个定时器,由网页来刷新,你的程序只要打开及查询这个frame既可
      

  8.   

    你好.如果连接量不大或长连接是没问题的.但诸如网络爬虫或投票器类程序就会有这样的问题出现,因为time_wait最小注销时间是30秒.
    你好.不是的呀.我是直接用tcpip协议模拟出N多的ie客户端呢谢谢你理解我的心情,某些问题解决不了睡觉都睡不好.唉...这问题困扰我很久了
      

  9.   


    你好.非常感谢像你这样的前辈帮忙解答问题.不过可能是我表达的能力欠佳,问题并不是这样的呀,我需要的是创建尽可能多的连接去访问对方网站服务器,在断开连接时不出现time_wait的...我想,有没有可能的异常关闭tcp连接呢.那样就不会有time_wait这样的半连接出现了
      

  10.   

    经过苦思瞑想,终于想出了一点解决问题的曙光:   
      if (bytesRead > 0)
                    {
                        srecv = (Encoding.Default.GetString(state.buffer, 0, bytesRead));
                           if (srecv.Contains("投票成功"))
                        {
                         textBox1.Invoke((MethodInvoker)delegate { textBox1.AppendText( state.user+ "投票成功\r\n"); });
     byte[] mss = Encoding.GetEncoding("gb2312").GetBytes(" "); //大家注意看这里,我制造一个空格 clientSocket.Send(mss);   //大家注意看这里,我把空格发出去  
                          clientSocket.Close();  //经过测试,像上面这样发送一个空格后马上close()不会有time_wait这样的半连接出现.但这想法有个问题,本来通信量就很大了,不是正规http封包服务器方会不会认为我在攻击他呢?
                         }
                      
    ................................//这里省略很多代码
    大家帮忙看看我这个想法可有哪些不妥之处.谢谢!
      

  11.   

    呵呵,给你搜来一个vb6的代码,或许可以作为参考,看看它的结束动作。http://www.williamlong.info/info/archives/35.html
      

  12.   


    你好,谢谢你的帮忙,这个是监听的,而且比我的应用还要低层些呢..没什么用呀..我现在用send null的方式..就是用try catch报错.因为线程较多这样也有个缺点就是比较占cpu...虽然问题没有得到好的解决.但还是谢谢大家的热心回帖!
      

  13.   


    只要socket是异常关闭的.就不会有time_wait...就好像我们用ie游览网页,直接关闭ie就不会半连接了
      

  14.   

    TIME_WAIT是不可避免的吧要不你关得彻底点
    System.Net.Sockets.Socket clientSocket;
                clientSocket.Shutdown(System.Net.Sockets.SocketShutdown.Both);
                clientSocket.Disconnect(false);
                clientSocket.Close();
      

  15.   

    ======================
    正常time_wait确实是不可避免,但只要socket连接不是正常关闭.就不会有time_wait之类的半连接产生
      

  16.   

    你做得跟我现在做的有点像,给你两个tips:1. 首先你直接socket.Close()是错误的,对tcp来说,应该首先Shutdown(Shutdown.Both),然后再Close()。MSDN上强调了又强调,你要去看看2. Time_Wait的问题。你的说法不完全正确,正确的是,哪边close的,哪边进入time_wait。或者说发出FIN的initiator会time_wait,而responder不会。所以,如果你要client不time_wait,就应该是server发出close()/FIN请求。请仔细看一下TCP/IP协议最后FIN/ACK的处理3. 客户端如果不是非常必要,就一定不要bind到特定端口。你直接bind(new IPEndPoint(IPAddress.Any, 0)就能bind到特定地址,或者直接connect,总之端口由OS来确定,不要自己指定,这样每次都会给你一个可用端口(以前的端口在time_wait,不管)。
      

  17.   


    你好.谢谢你的指点,可能我描述的不是很清析.其实我的问题根源是想模拟出尽可能多的client客户端.但是路由又限制了连接数不能超出指定数量.而正常关闭client就会产生大量半连接占用资源.使得后面的请求都要等前面产生的time_wait消失了才去建立client. 严重制约了效率
      

  18.   

    half open跟router的限制是两码事,这里只讨论对time_wait的处理。简单来说,这样子的话,client必须等time_wati结束,因为是同一个地址,同一个端口:
    for(int i=0;i<1000;++i)
    {
    Socket sock = new Socket(...);
    // 必须等前一次的time_wait结束
    sock.Bind(new IPEndPoint("127.0.0.1", 6666));
    ...
    sock.Shutdown(...);
    sock.Close();
    }
    你要避免对同一个endpoint的time_wait,就不能指定端口,像这样:for(int i=0;i<1000;++i)
    {
    Socket sock = new Socket(...);
    // OS自动选择可用端口
    sock.Bind(new IPEndPoint("127.0.0.1", 0));
    ...
    sock.Shutdown(...);
    sock.Close();
    }
    你说IE为什么能同时关闭多个socket?你认为那是“非正常关闭”???晕,那样子不被骂死才怪(因为服务器会一直等待)。浏览器不过是每次选择不同端口进行连接而已。