For i = 0 To sckClient.UBound
     If sckClient(i).State = 7 Then
            sckClient(i).SendData sR
            DoEvents
     End If
Next
我不想用 DoEvents  ,,哪位  神仙 有办法呀????
因为
比如在FOR 循环的过程中,突然系统有别的事件发生,它就会跑去处理别的事情了
如果这样的别的事情太多,,那我的FOR 循环 还要不要工作呀,,我只是举个例子说明不想用Doevents甚 期盼 神仙级别的 高手 来救我一次呀

解决方案 »

  1.   

    不用 devents也行 用 一个事件 在那里面发送 不错处理起来麻烦 还要 加消息头和尾
      

  2.   

    vb没办法  要不用.net或者vc
      

  3.   

    影子:
     不用 devents也行 用 一个事件 在那里面发送 不错处理起来麻烦 还要 加消息头和尾
      麻烦你能不能详细的说说这个方法,好吗? 虽然用了这么久VB,但是有些 队列 什么的,还不会
      

  4.   

    我现在也在思考 用VC 完成端口做,,可是 完成端口 太复杂了,,到现在还没有啃下来,,,,
    所以  还得先用VB解决了,,,,以后再漫漫用VC 增强功能
      

  5.   

    既然你不希望程序分心,那你为啥还要加上DoEvents呢?不管用什么办法,多线程也好,多进程也罢,调度资源的始终是系统,你要专心的话还是让它专心地做吧
      

  6.   

    supergreenbean:  
       难道你就是那个 我曾经下载过你的很多程序  的 超级绿豆吗 ???
       -----不过感觉不是吧,,,超级绿豆  会不知道 我为什么必须在一个FOR 循环里 ,很无奈地,很不情愿地加上Doenents 吗?!
      
       回答:  我不想加Doenents,但必须在那里加Doenents,,原因是这是Visual Basic 的 WINSOCK 6.0
      

  7.   

    晕...为什么是winsock 6就要加 doevents
    如果你不想for被打扰,就搞多线程吧...
      

  8.   

    VirtualDesktop :
       从第一句看来,你确实不是对WINSOCK 6.0 很透彻
       
       第2句话,值得研究,,,可是VB的多线程 经得起考验吗? 程序是给客户安装用的,不是自己编个多线程玩玩,,
       要长期经得起运行考验的。 我在这只是想求助的,,说话没有半点 难为 OR 讽刺 OR 偏激 的 意思或行为。 只针对问题发表意见,,请谅解。
       如果有些朋友提出了好的思路,,能够再详细些,或者能够带上部分 代码,那就感激不尽了。
      

  9.   

    For i = 0 To sckClient.UBound 
         If sckClient(i).State = 7 Then 
                sckClient(i).SendData sR 
                DoEvents 
         End If 
    Next 不想用也可以不用呀 ,你不用DOEVENTS,同样也可以发送数据,不过这样发送的数据也许好多个SR组成一个大包,大概是8K后一起发送出去,.如果你加头尾标志的话,在接收端也很容易分离各段数据!
      

  10.   

    我对WINSOCK也了解得非常少,个人做过多个WINSOCK工作的事情就是,写过一个邮件群发软件.当时为了实现同时连接多个邮件服务器,从而实现同时发送多封邮件,就使用了WINSOCK数组,然后再将其封装在ActiveX EXE中,以使用VB6里官方推荐的"单元模型线程".在ActiveX EXE中,使用CreateObject建立的对象,它就工作于另一个单元线程中.虽然这种线程的线程间调度开销很大,但是却可以很稳定地实现多线程------至少我的应用中,没有发现API实现多线程里面那些非法操作啊之类的问题.推荐你测试一下.
      

  11.   

    但我认为,应该从你的程序流程里面再分析一下,看看能不能从流程上进行优化.毕竟WINSOCK本身也是事件驱动....
      

  12.   

    又仔细的看了你的要求,我发现我说错了,我理解为你的数据是数组而非你的WINSOCK数组,当我没有发言,哈哈
      

  13.   

    ZOU_SEAFARER:
       嘻嘻,你还可以看出其中的端倪,  说话也比较风趣 恩
      

  14.   

    见识过 老马 同志的 ActiveX EXE中建立多线程的 文章
      

  15.   

    首先,我还是我。其次,我对Winsock研究不多,所以胡说的成分比较大。好,下面开始胡说:1、DoEvents的作用是清除当前输入队列中的按键信息,然后调用Sleep(0)将本线程的剩余时间片分给其他需要使用的线程。所以,插入一个DoEvents,或者一个Sleep函数的作用是差不多。
    2、VB是单线程的,你在这里不能使用阻塞式的循环或其他类似的东西,否则就算等到宇宙毁灭的时候,你也不会看到这个程序恢复响应。
    3、照我的理解(当然,我的感觉在大部分时候都是错的),你这里是想将SendData的异步操作改为同步。因此,我粗略地想了一下(当然,我向来都很粗的),希望下面这种方法对你的问题是否有所帮助Private Sub MySendData(ByVal Index As Integer)
        With sckClient(Index)
            If .State = sckConnected Then
                .SendData CStr(Index) & ">" & Text1.Text & CStr(Index)
            End If
        End With
    End Sub
    Private Sub sckClient_SendComplete(Index As Integer)
        If Index < sckClient.UBound Then
            MySendData Index + 1
        End If
    End Sub
    Private Sub Command1_Click()
        MySendData (sckClient.LBound)
    End Sub
      

  16.   

    搞到现在我还是不明白为什么要加 doevents, 有否高人能指教一二?
      

  17.   

    首先,SendData将数据根据大小分段,段的大小为&H2000(8K)。而后,调用send函数把分段后的数据一点点写入缓冲区发掉。
    在这里DoEvents的作用就是让send函数有时间依次把缓冲区里的数据发完,否则后面的SendData所写入的数据会被并到前面的缓冲区中。因此,实际上解决这个问题的最关键之处就是,在调用SendData发送大数据前,对其进行分段处理;在接收到分段数据后,进行组装。
      

  18.   

    supergreenbean :
       
       首先,SendData将数据根据大小分段,段的大小为&H2000(8K)。而后,调用send函数把分段后的数据一点点写入缓冲区发掉。 在这里DoEvents的作用就是让send函数有时间依次把缓冲区里的数据发完,否则后面的SendData所写入的数据会被并到前面的缓冲区中。------[你的见解是对的]
       因此,实际上解决这个问题的最关键之处就是,在调用SendData发送大数据前,对其进行分段处理;在接收到分段数据后,进行组装。------[参考 ZOU_SEAFARER:‘又仔细的看了你的要求,我发现我说错了,我理解为你的数据是数组而非你的WINSOCK数组,当我没有发言,哈哈’]
      

  19.   

    supergreenbean 的VB.net的方法  以前曾经测试过, 但是好象没有你提供的这个好
        我再测试下 
      

  20.   

    supergreenbean:
         的VB.net的方法 ,也是有缺陷呀。
          当客户端(sckClient)很多,当它们发送数据的频率 很高的时候,,,就会出现问题了,,有些只能发给一个客户端(sckClient),,,因为其他的socket过来了,将INDEX 参数冲了?
         从这方面看, 是不是Private Sub sckClient_SendComplete(Index As Integer) 也是中间有个转让系统时间的过程? 那么它本身也就相当于一个Doevents了 !!!
      

  21.   

    老马  或 其他 高手能不能给 贴个在线程里  SOCKET发送数据的  代码,,期待 
      

  22.   

    或者 谁有没有成熟的用纯API编写的SOCKET的,,我自己在网络上找了几个,用在一般的应用了还说的过去,可是如果用在群发上就差了
      

  23.   

    网上不是流传有一个CSockMaster类的么,你可以下下来看看不过,你的问题其实很大程度上并不在于socket,而是在于你的算法本身
      

  24.   

    我觉得 不在于 算法上了!
       在于 VB里只能用那个Doevents了,,,,没招了!
      

  25.   

    阿门,即便使用DoEvents也是可能会出现数据被分割的现象的。保险起见,还是应该在发送端和接收端都加上分包和组包处理代码。或者你在这些数据传送的winsock之外,再增加一个发送控制命令的winsock。这样就可以完全确保你的数据是按照顺序发送的了。
      

  26.   

    汗,,比较 汗,,supergreenbean兄弟:
        你怎么现在还没有认识清楚 我现在的窘境 所在吗?
        问题根本不是出在“应该在发送端和接收端都加上分包和组包处理代码”之上! 你说的那是对于发送大文件的处理方法!!    我是一堆   WINSOCK数组  逐个地向外发送数据  ,不是一个WINSOCK 向外发送一堆数据。    “再增加一个发送控制命令的winsock。这样就可以完全确保你的数据是按照顺序发送的了。”这句话我不能完全理解它要怎么思路呀
      

  27.   

    哈里卤鸭,你逐个向外发送数据用的是UDP协议么?接收端没有重复的吧?增加一个控制Winsock的意思是,再放一个Winsock控件,用于监听由那些数据接收端发送而来的成功接收数据的消息
      

  28.   

    我自己五年前遇到过相同的问题,如果不加DoEvents则发送有可能失败,加上则无法自己控制程序的运行,后来才明白原来是为了配合VB,VB的Socket控件采用了公寓线程,容易Block,最后采用了纯API才解决了,因为纯API方式可以自己决定是否采取Block形式。
    不过在VB使用WinSocket API比较麻烦,因为没有相关的定义,需要自己来定义,如果你熟知C++数据类型和VB数据类型的转换就好办了。
      

  29.   

     supergreenbean :
         哈里卤鸭!  TCP,  接收端没有重复的 lyserver:
         用 WinSocket API 是解决的正途 呀
          能发个小Demo供调研下吗?  [email protected] 
         目前正在研究VC的IOCP,C++还能看动点
    哇哈哈哈------------俺的口号  
      

  30.   

    又认真的看看发言,这次是认真的,我觉得有很多WINDOWS内部的东西是不为VB所不能控制的!如果实在走不通的时候你为何不换一个方法呢,或者对要求降低点呢!人类还不能座飞机上火星,那就等科技进步了,或者换一个工具上!一位的总目前很渺茫的路,什么时候是个头呀!
      

  31.   

    也是.换.NET!!听说在VB.NET里面有极大的改进
      

  32.   

    我的新问题是不是和你的一样啊?我字VB控件栏发了帖,郁闷100分呢,不够我再加。不过没分了望高手帮我看看在VB控件
    http://topic.csdn.net/u/20080317/10/35c09da5-fe48-4f1a-93de-f5f8c68fc88d.html
    winsock服务端请求排队与事件响应难题,非要开多线程吗?请高手指点
      

  33.   

    个人很同意绿豆的说法,纯粹是代码处理问题我发大数据的时候是给数据"流压缩",然后包头+数据+包尾一次性发送的,我不管数据多大,反正sock会帮我分开发送的接收端在接收到包头后开始记录,直到收到包尾,中途的数据用copymemory组合到一个数组中,这样做处理后不管向多少个客户端同时发数据都没什么问题~~~方案2就是像绿豆所说的那样,做个处理程序把包处理了再发送~~(关键是在SendComplete的处理上),等SendComplete有反应了再继续发送下个包,那样可以保证接收端不会收到重叠的包,用sock数组处理方法也是差不多的,希望你能看懂
      

  34.   

    如果实在要让send不管缓冲区有无放满就发送数据的话,你可以在send完后马上使用shutdown...我已经是将我知道的都说了,楼主接下去就要靠你自己了,阿门
      

  35.   

    startbin :
        本来我对这个 帖子 也不抱 太大的奢望,都苦恼了那么久了,也深知道问题不是那么好解决,,可以说,如果不用lyserver 兄弟说的WINSOCK API, 已经没有希望了!!!
         但是至于 把问题看偏了方向,,或者没有很深入的测试调试情况下 说出来的方法,我包括看过这个帖子的人都会感谢你能拿出自己的见解和别人分享!  但是有些看似很有道理,但是经不起推敲,,,,
         程序就是这样,只要你有想不到的地方,只要有充足的时间,它都会给你暴露出来的。
         
         关于startbin 说的第一个问题: 前面已经说过,不是数据太大的问题,,而且我实际应用中给每个客户端每次发送的数据包都不大,也就几百个字节吧 ! 所以也就不存在分包了,当然也不用加协议报头/报尾了。
         关于startbin 说的第二个问题: 前面绿豆提出这个思路的时候,我就测试了,在客户端数量巨大的情况下,有很多客户会有很多本来应该收到的数据,原因我前面也说了,,如果你愿意可以实际做一下,,,,    在这里感谢大家的积极讨论,,ZOU_SEAFARER 兄弟说的可能也对,,因为VB有它的局限性 ,,但是也并不能说完全没有了希望了,, 我也在一直调试VC的完成端口,,但我不会轻易放弃的,毕竟VB用起来顺手。
       
        还有,,嗷嗷叫的老马:请教个问题, 我测试将WINSOCK 放在ACTIVE EXE 里面,怎么不能用呢,老是出错!  你如果测试可以用的话,能告一下吗?
      

  36.   

    supergreenbean兄:
       你说的shutdown是什么呢? 能否具体些?
       shutdown()函数我在VC里面见到过,VB里的是起什么作用的呢,无知中,能否详解告知!
       
      另外,,48楼发言纠正:"有很多客户会有很多本来应该收到的数据,"-----应该为"有很多客户会有很多本来应该收到的数据,收不到了,原因"
      

  37.   


    我没有发现你所说的现象呀.对于这个ActiveX EXE,我也研究不多,等于是刚接触.我利用这刚学到的一点知识写了一个下载程序的例子,看看能不能引一下玉:http://www.m5home.com/blog/article.asp?id=65
      

  38.   

    我看你是还没看懂我给你的答案,问题不是出在包的大小,+包头+包尾的意思是让接收端,好知道这个包哪里开始哪来结束你现在的问题就出在接收端里面没有处理,因为sock发的过快,包是会重叠的,导致你接收到的数据不正确例如你连续发:连续发3次"123",客户端可能并不是触发3次DataArrival事件来接收的,有可能只会触发2次,或者一次所以要是你+了包头包尾,就算叠加了也不会出现问题,懂意思了吗,问题就在你客户端处理数据上!!!
      

  39.   

    startbin :
        :)
        我的客户端 不是在一个程序里的,,是分布在很多台机器里,每台机器里有一个客户端,每个客户端里有一个接收WINSOCK
      

  40.   

    嗷嗷叫的老马:
       下载了,先调试,看尽量向这方面靠,,能否有突破!
       嗷嗷叫地 谢谢 嗷嗷叫的老马,先!   别的同志也可以帮忙向这方面凑,看多线程 或 ACTIVE EXE  能否缓解问题,能否稳定!
      

  41.   

    我说的send和shutdown都是socket api。Winsock控件上的SocketHandle可以直接作为api的参数使用。send sckClient(Index).SocketHandle, ByVal sSend, Len(sSend), 0
    shutdown sckClient(Index).SocketHandle, SD_SEND这样的话,可以保证数据马上被发送采用多线程或多进程对你的问题似乎也不会有什么太大的帮助。因为不管你上面怎么发送,最后都是要归到同一个底层缓冲的。另外,你可以调用WSASend函数使用完成端口
      

  42.   

    有N个客户端向服务端发包,而服务端用的是SOCK数组,连接建立后,按理服务端应该触发N次,但实际情况真的不是这样,用步进调试一个不少,运行就不一定能收到几个了。但这些包也没丢、排队在SOCK的端口,但DataArrival就是不触发。
    再问个深一点的问题:VB的调试中,暂停和开始功能实际上VB做了些什么???比如你窗体有个TRIMER控件,调试暂停,我想应该是TRIME.ENABLED=FALES,再开始,应该是.ENABLED=TRUE了,但对SOCK控件VB做了什么?因为我发觉排队在端口的包,只要暂停、开始后,DataArrival又被触发了。
      

  43.   

    winsock我也是仅入门,我也乱说几句
    TCP协议理论上是可以保证发送数据的完整性,如果数据发送过程中因各种原因造成数据发送失败,winsock会尝试重新发送。这里doevents的作用究竟是为什么?我觉得如果是为了清除缓冲区数据似乎说不过去,因为当数据大于8k的时候,winsock无需人工干预会自动分包发送,如果这个过程要doevents来帮助完成,好象联机帮助中并没有说循环发送中数据doevents是必须的,而且从简单测试来看,不加doevents是可以的。所以我觉得doevents更多的作用还是为了防止在循环发送数据过程中,因种种原因造成程序的假死状态
    我还是比较赞同要发送数据的处理问题,发送端接收端包的处理是关健
      

  44.   

    supergreenbean:
         测试了你提供的新的方案,觉得值得研究。
          本来下载过几个纯SOCKET API 编写的SOCKET,,以为若要使用SOCKET API,就必须完全的用SOCKET API做出一个SOCKET控件,然后在程序里调用自己写的这个SOCKET控件,才可以使用SOCKET API 。  呵呵,,看来还是自己的固定思维以及懒惰的心态  不好呀!
          测试了,但是还有问题:就是我发送的数组内的内容,,与客户端接受的内容 完全不一样;      只是客户端接受的长度与 我发送的长度一样。     可能是发送的缓冲区 有问题?
     
    supergreenbean,你的这两个函数里面的参数,你能不能用具体的例子   表示一下
    send sckClient(Index).SocketHandle, ByVal sSend, Len(sSend), 0 
    shutdown sckClient(Index).SocketHandle, SD_SEND   我刚查了VC里面,知道 #define  SD_SEND   0x01     
      

  45.   

    在IDE中,所有代码都是一句一句解释执行的,就跟P代码运行方式一样。暂停后,主程序的解释引擎停止工作,但winsock有着自己的线程。VB中接收数据的流程大致这样
    1、数据到达socket,系统投递 FD_READ消息到VB的NMNotifyXXX窗口
    2、VB应用程序在处理一些其他消息的过程中,调用ioctlsocket(s, FIONREAD...)提示有数据可读
    3、VB应用程序使用recv读取数据
    3、应用程序继续处理消息,直至下个FD_消息到来所以,我认为,事件之所以没有被触发是因为主线程在处理消息的时候堵塞了,从而造成接收不畅。
      

  46.   

    汗一个!
    我的帖子也成了onetiger1243 的帖子?
      

  47.   

    粗略地写了一个Private Sub cmdSend_Click()
        Dim sMsg As String
        Dim i   As Long
            
        For i = 0 To sckClient.UBound
            sMsg = "<" & Format(i + 1, "000") & ">" & Text1.Text
            
            With sckClient(i)
                If .State = sckConnected Then
                    send .SocketHandle, ByVal sMsg, Len(sMsg), 0
                    shutdown .SocketHandle, SD_SEND
    '                .SendData sMsg
                End If
            End With
        Next
        MsgBox "Sent"
    End Sub
      

  48.   

    VB.NET code,,看来和VB6  如此地相似呀,呵呵,,当初看人讨论,两个完全不是一样东西的!呵呵谢谢 supergreenbean了,,不过我自己也写出来了,我是用的数组指针。现在想略微地提高要求,因为send肯定是阻塞  方式的,,,想用WSAsend写,是不是问题就变的复杂了??
    另外:WSAsend作为非阻塞方式,一定要包含OVERLAPPED参数吗?  ---也就是说如果我想用WSAsend作为非阻塞方式,非要求用完成端口吗??  BAIDU了会,,也没有查出结果。    我想用  非阻塞方式  向外发送,,,更想用完成端口的方式 向外发送 (本楼 都特指在VB下调用),,但觉得VB下的完成端口 不可能处理好吧??  所以,退一步求: 能用非阻塞方式 向外发送吗?    我自己试验了下,ErrorCode = WSASend(sckClient(i).SocketHandle, ByVal Bfr, 1&, len, Flags, 0,0&)   发送了,,可是客户端什么也没有收到!
      

  49.   

    ------------------------------------------------------------------------------------
    shutdown()函数用于任何类型的套接口禁止接收、禁止发送或禁止收发。
      如果how参数为0,则该套接口上的后续接收操作将被禁止。这对于低层协议无影响。对于TCP协议,TCP窗口不改变并接收前来的数据(但不确认)直至窗口满。对于UDP协议,接收并排队前来的数据。任何情况下都不会产生ICMP错误包。
      若how为1,则禁止后续发送操作。对于TCP,将发送FIN。
      若how为2,则同时禁止收和发。
      请注意shutdown()函数并不关闭套接口,且套接口所占有的资源将被一直保持到closesocket()调用
    -------------------------------------------------------------------------------------
    不太明白 你为什么 要调用shutdown()函数呢?
      

  50.   

    在这个贴了里,我从没见过supergreenbean 的VB.net的方法。哪是都VB6的语法呀!
      

  51.   


    原谅我的懒惰,是在不想分析以上的代码。看了下我以前写的一些SOCKET服务器,好像的确没用到“Doevents"(如果这屎一种罪的话~~呵呵)解决问题的思路大致如下:[color=#FFFF00]1.首先建立一个Winsock控件的数组:我代码里面是 Winsock1(0)[/color]2.然后使Winsock1(0).listen3.在有客户端接入的时候,Load一个新的WinSock1控件Winsock1(n+1)进行处理,原来的Winsock1(0)一直起到listen的作用
    Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    load Winsock1(n++)    //n是接入的客户数目,可以起到控制同事接入的客户端的作用。到一定可以清1
    Winsock1(n+1).accept(requestID )
    End Sub4.在Winsock1_DataArrival事件里面处理工作Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)

    End Sub以上代码都是凭记忆写,可能语法有问题,但是主要屎为了叙述一下我的思路。基本能够实现多线程的处理!
      

  52.   

    我靠好乱,整理下1.首先建立一个Winsock控件的数组:我代码里面是 Winsock1(0)2.然后使Winsock1(0).listen 3.在有客户端接入的时候,Load一个新的WinSock1控件Winsock1(n+1)进行处理,原来的Winsock1(0)一直起到listen的作用 
    Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long) 
    load Winsock1(n++)    //n是接入的客户数目,可以起到控制同事接入的客户端的作用。到一定可以清1 
    Winsock1(n+1).accept(requestID ) 
    End Sub 
    4.在Winsock1_DataArrival事件里面处理工作
    Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long) 
    。 
    End Sub 以上代码都是凭记忆写,可能语法有问题,但是主要屎为了叙述一下我的思路。基本能够实现多线程的处理!
      

  53.   

      郁闷中。
      幽幽地问一下:shakoe,你的这代码  是干什么的??好象与我提出的问题 无关吧。
      
      你说的一个SOCKET的侦听,另外一个SOCKET数组accept(requestID),,,貌似 “地球人都知道”呀  继续郁闷
     
      

  54.   

    ...... 
    你说的一个SOCKET的侦听,另外一个SOCKET数组accept(requestID),,,貌似 “地球人都知道”呀 
    .....
    感谢网事如峰的好贴,我的问题真的是和你到一起了....
    我用了个SockMon的侦听软件,原来真的是SOCK的端口阻塞,更正我在55楼的说法,不是DataArrival不触发,而是DATASEND没有做.也就是该发的数据没有发..原因是服务器忙......
    在SOCK的记录中看到开始运行时服务端能同时运行几个进程,但几秒钟后就被其中一个进程独专了,直到该进程完成.......
    61楼超级绿豆的代码还有点不明白,SEND 和shutdown分别是什么,在VB6下怎么不能直接用?要引用什么吗?
      

  55.   

    更正55楼的说法,应该是:
    因为我发觉排队在端口的包,只要暂停、开始后,.SENDDATA又被触发了。
    引用楼主的原话就是:
    有很多客户会有很多本来应该收到的数据,收不到了,原因"
      

  56.   

    呵呵,理是越辩越明的,希望应该不远。我写的都是VB6的代码,发贴进行代码格式化的时候只有VB.NET和VBScript两个选项,所以就选了VB.NET咯shutdown可以让端口的数据被处理完毕后才关闭端口,而其他的函数则会立即关闭端口导致数据丢失
    WSASend如果最后两个参数都是0,那么它的行为就与send一样。
    Private Declare Function WSASend Lib "ws2_32.dll" (ByVal s As Long, buf As Any, ByVal dwBufferCount As Long, lpNumberOfBytesSent As Long, ByVal dwFlags As Long, lpOverlapped As Any, lpCompletionRoutine As Any) As Long
    Private Type WSABUF
      len As Long
      buf As String
    End Type...Dim tBuf As WSABUF,lBytesSent As LongtBuf.buf = sSend
    tBuf.len = Len(sSend)Debug.Print WSASend(sckClient(i).SocketHandle, tBuf, 1, lBytesSent, 0, 0, 0)
    如果使用完成端口,貌似要使用fAlertable参数为1的WSAWaitForMultipleEvents等API函数将线程置为alertable wait的状态还有,Winsock控件本身的发送方式就是异步的重叠IO操作
      

  57.   

    Winsock控件本身的发送方式就是异步的重叠IO操作???在VC里面,异步是你将数据放到缓冲去里,就返回,执行你自己的下一步代码; 而让系统发送,发送完毕,系统告诉你一声;     VB里怎么看也不象是 异步的呀,,应该是同步,即你sckClient(i)没有发送完毕之前,,你别想做其他的事情;;;    
    supergreenbean:
           WSASend(sckClient(i).SocketHandle, tBuf, 1, lBytesSent, 0, 0, 0)这样的应该也属于 同步了吧,,不喜欢啊!
          我需要异步的WSASend:  即我只管把 数据发送出去就可以了,就立即返回,让系统处理真正的发送!
           这样的WSASend 能举个例子吗?
      

  58.   

    绕了个圈子又回到原点了,呵呵。我的问题在今天早上算基本解决了,几点心得:
    1,对SOCK的发送端,完全没必要对大文件进行分段,分段操作,既浪费了系统资源,还减慢了发送速度。如果说是为了保证发送数据的准确性,只需要对整个文件进行加包头包尾,如果整个文件会丢包,分开发也会丢包,那是网络问题,因为TCP的确认机制基本能保证数据的准确性。
    2,对于SOCK的发送堵塞问题,我还是理解为系统问题,而不是SOCK本身,因为我只是把分段发送改成整个发送,让SOCK自己去分段。问题就解决了,同时10来个连接,发送同一个20M左右的文件,都只要2-4秒。
    3,WINSOCK的API没时间试了,还有堵塞问题,不是我不求甚解,我在这个问题上消耗了太多时间,接下来有好多事情,等空一点再好好烟酒烟酒
    4,多谢几位老大的支持和UP,真心感谢这段弯路。到VB控件我的贴去领分,呵呵虽然我知道你们也不在乎几个鸟粪。
      

  59.   

    呵呵,是我看错了,连接和读取是异步的,而发送应该是阻塞式的
    SendData的实际执行流程是这样的:1、调用SendData方法
    2、Winsock判断数据大小
    3、如果大于8K,则先取前面8K数据;如果小于8K则取全部数据
    4、调用API send,发送数据,并得到已发送数据长度 -> bytesSent=send (s,buf,len,0)
    5、调用SendProgress事件。将 已发送数据长度 bytesSent和剩余数据长度 bytesRemaining作为事件参数
    6、判断剩余数据长度bytesRemaining是否为0
    7、如果还有数据,则继续返回第2步;否则,跳出循环
    8、调用SendComplete事件WSASend的异步发送方式我还没试验过,不好说,估计实现上会有些麻烦事
      

  60.   

    supergreenbean:
        从理解上SendData的执行流程应该是这样的!!
         不知道你的这个流程的权威性?   是你根据自己的理解写出来的吗?   还是在某权威书籍上或者MSN等上得到的呢?
         
         我刚才直接调用API send 呢,它的流程:什么也没有做,没有进SendProgress,没有进SendComplete
         
        shutdown可以让端口的数据被处理完毕后才关闭端口,而其他的函数则会立即关闭端口导致数据丢失,  这句话 还是不能理解透彻呀 。       
         shutdown可以让端口的数据被处理完毕后才关闭端口,我查shutdown函数BAIDU里说
    注意shutdown()函数并不关闭套接口,且套接口所占有的资源将被一直保持到closesocket()调用 呀; 而其他的函数则会立即关闭端口导致数据丢失,其他的函数 指什么函数了?怎么会关闭端口呢??
        另外,我测试的时候,没有用shutdown函数,光用send函数,没有什么可以预见 到的危害吧?
        谢谢 supergreenbean  一直来的跟贴,解疑析惑! 崇拜中    另另外,我也在尝试用WSAsend, 正在求索中 希望supergreenbean能有好消息呀
      

  61.   

    实际执行流程是通过反汇编Winsock.ocx得来的,也许会有些小出入,但大体上就是如此。你直接调用 send当然不会触发那两个事件咯,因为那是Winsock控件做的事情啊。至于shutdown,你可以参考MSDN中Winsock章节的Graceful Shutdown, Linger Options, and Socket Closure,这篇文章中对shutdown WSASendDisconnect closesocket函数的作用进行解释其他的,阿门,有空再说了……
      

  62.   

    理解shutdown了,,它与close()差不多,但有区别。
        我的程序里不想发送完毕信息就关闭sckClient(ii)
        所以就不用执行shutdown sckClient(ii).SocketHandle, SD_SEND 了
      

  63.   

    本帖最后由 supergreenbean 于 2008-03-19 22:27:25 编辑
      

  64.   

      感谢 supergreenbean的鼎力相助!!
      经过测试, 发现WSASend() 与send() 的发送效率  没有区别,纳闷中
      准备 揭贴
      

  65.   

    SleepEx -1, 1  
    这个函数中的-1是表示INFINITE吗?
          在VC中  #define INFINITE     0xFFFFFFFF  // Infinite timeout
    参数也不是-1,
      

  66.   

    0xFFFFFFFF 就是 Long型的-1