局域网的两台电脑,一台winsock客户端程序,一台winsock服务器端程序,当客户端没有时间间隔地向服务器端senddata 超过3次时,服务器端在第二次getdata起,将会把之后的data合并在一起,使用doevents语句现象依然。但两程序在同一机器就不会出现该现象。请问如何解决?谢谢

解决方案 »

  1.   

    同意:thelostland(落日忍者)数据不长的话,还是结合到一起发送好!如 "<数据1> , <数据2> , <数据3>"
    一次过发过去.另一端则用Split函数分解出来!
    注:Split函数VB5是不存在的
      

  2.   

    to 1-3楼:
        客户端采用数据合并不要,因为之前的数据已经有格式了,
        采用timer控件比较难控制。
      

  3.   

    可以让服务器返回一个值,客户端再发送下一个数据不过 服务器 每次 getdata 应该是有时间间隔的,这样好像很浪费
      

  4.   

    最近几天也在为同一问题困扰。虽然我们并没试出来,但是听别人说的确会有这种现象。
    感觉xiyou(溪游)兄的办法较好,可是觉得在没等到客户端返回数据之前的轮询怎么做呢?大家有无好办法?难道都是用Timer控件一次次轮询直道收到值吗?
    还有是否可以在本次发的数据前面带上本次数据的长度?
      

  5.   

    客户端不要用For...Next那样来发送!
    使用Winsock的SendComplete事件!像你现在这种情况不是接收问题!而是发送问题.Winsock传送一条信息需要一些时间的!发送端在SendComplete事件那就可以得知什么时候是发送下一条数据的成熟时了!OK...
      

  6.   

    qyii(-Let me fly-) ( ) 信誉:100 
    服务器的响应也需要一些时间。连续地for循环发送只会导致服务器性能的下降。
      

  7.   

    TO:boybluesky(boybluesky)    奇怪!!!
    我知道是需要一些时间.但似乎与楼主的问题,有些出入吧?
    连续地for循环发送会发生楼主这样的情况...
    我认为这,不是服务器性能下降引起的!大可以试试用循环发送.看看服务器触发了多少次DataArrival事件就清楚了!
    winsock的传送并不是实时的...这与以前曾经说过的关于怎样判断对方断开了.有人说用SendData通知.但,SendData以后,怎么知道服务器收到,并知道你要关闭Winsock呢?当然,做过winsock的人都知道.SendData后,下条语句马上关闭Winsock.则SendData的信息没有被发出去!也就是说,你用循环来发送信息,只会使信息都挤在winsock的缓冲区里!直到winsock有空闲,结果一次就把挤在一起的信息都发出去了!
    只有SendComplete事件触发,才能确定Winsock真的把信息发出去了!太过底层的东西我不清楚...还望指教!
      

  8.   

    如果对SendComplete事件还有什么疑问!请看我做的一个winsock传文件的源码!
    http://www.efile.com.cn/eFile/qyii/TestWinSock.rar
      

  9.   

    xiyou(溪游) 的办法是可用的,本人在两年前做过类似的功能,
    测试环境包括
    1:服务器,客户端都在一台机器上,一般没有丢包
    2:服务器,客户端在同一局域网的两台机器上,有丢包
    3:服务器,客户端在互联网上(异地),有严重丢包(网络不稳定)在反复调试后,只能采用一端发包,接受端回包确认的机制来保证.
    在没有收到回包确认时,延时重发,用winsock好象只能这样.
      

  10.   

    的确是发送的问题。
    小数据量,的我认为还是以自定义的一种报文格式把数据合并后,在发送TCP是一种“流”传递方式,也就是说,它发送数据就像流水一样,中间是不分隔的,只要带宽可以,会一口气把数据连贯起来发出去。如
    for i = 0 to 99
        winsock1.senddata "A"
    next i
    接收方不是100次接收到“A”
    接收方会收到一个字符串“AAAAAA……AAAAAA”你可以:
    当客户端收到一个信息后,向服务器发回一个“OK”(或别的什么)
    当服务器要发送信息时,先检查有无收到上次的“OK”,没有就不发新的,等待
    如已经收到上次的“OK”,就将“OK”标志清空,发本次的新信息。但这其实并不是一个十分好的办法,如果你是做聊天程序,最好还是自行设计一个报文的格式,虽然服务器以“流”的方式发送,但客户端依据报文格式,可以将信息一“条”一“条”地分开。
    如:每条信息都以“^%%$*&”开头,则两个“^%%$*&”之间的内容为一条信息另外,如果是聊天程序,一般以UDP方式为宜。
      

  11.   

    楼上说的是,考虑服务器性能,怎么彻底解决我也不知道,
    我也有个问题
    o 我想知道发送的数据大到多少的时候不适合用TCP
      

  12.   

    关于丢包:对于TCP连接,在一些资料中说,它能保证数据传输.实际上,那东西我还没有在局域网或互联网上测试过.
    至于不断发送的问题,我是参照了Web服务器的工作方法!我写过一个winsock下载文件的程序(没有完成).发现,程序与服务器只是在确定文件那里做了一些握手之外就只有服务器向下发送数据,而接收却完全被动的!服务器根本不需要确定你是否收到,它只顾一直发送.SendComplete事件的触发,是Winsock告诉程序,上一个发送动作已完成了.我就这样想出来的.
    在问题里,你是使用循环来发送的.就像我回复那样,Winsock传送不是实时的,它有一个缓冲.到了特定情况(周期吧?)才会把缓冲里的东西发送出去!使用循环,会导致缓冲内的数据叠加.到了winsock的周期,它就一次把缓冲里的数据都发送出去了!
    在单机里的情况与网络的情况有很大的区别.网络的API我不认识,到现在还只会用Winsock控件.所以,它的内部工作是怎样实在不清楚.
      

  13.   

    To monica8361(小猪):
    对于winsock建立的连接,暂且不论接收的动作是否比发送更复杂些,服务器的运算速度总是无法快到同步接收许多客户端同时发送数据。当然你可以说服别人买一台很昂贵的服务器,但是你可能同时还要说服别人买许多很破的客户端,这样你的软件运行起来或许才更为完善。
      

  14.   

    确实会存在多次发送的数据会在一次getdate 里。
    我想这是vb的原因。
    目前可以这样解决:
    1、客户端'客户端发送数据后sent=false
    '服务器响应后sent=true
    '(在客户端的datarrival里sent=true)
    wscli.senddata bytes
    while not sent
       doevents
       '超时处理
    loop
    2、服务端
    dataarrival事件里:
    wssrv.getdata bytes2,vbarry+vbbyte
    'msqu保存数据的集合队列
    'msqu.id=index'socket id
    'msqu.data=bytes2'variant
    msqu=bytes2
    wssrv.sendata sResponse'响应
    3、轮循
    while msqu.count>0
       '处理msqu.data
    loop
      

  15.   

    2、服务端
    dataarrival事件里:
    wssrv.getdata bytes2,vbarry+vbbyte
    'msqu保存数据的msqu_list的集合队列
    msqu.id=index'socket request id
    msqu.data=bytes2'variant
    msqu_list.add msqu
    wssrv.sendata sResponse'响应
    3、轮循
    while 
       if msqu_list.count>0 then
       '处理msqu.data
       end if
    loop
    //"同时有很多客户端连接,并连续发送数据,服务器性能会下降,甚至无响应或者死机。"
    在大量的循环中加 sleep n'n毫秒值
      

  16.   

    //"同时有很多客户端连接,并连续发送数据,服务器性能会下降,甚至无响应或者死机。"这问题...可能就是导致服务机是N个CPU,?GB内存,X+ MHz总线的原因吧?就像windows的消息系统了.你打的窗口越多,造成死机的机率就越高(或机器越慢)!同理吧???似乎这跟机器的处理速度成比例的.差的服务机,同时连接能力自然差.反之就好啰!像玩网游一样,CS的BOT也会说:Fucking lagged !!啦! 加多台服务机就没事了!有点像是小孩子说大道理一样~高手看了别见笑!
      

  17.   

    TO:vbxml(枫)理解正确!呵呵...发送一条消息出去,但不能马上结束程序.???那到底什么时候才能结束?不会又要等服务器返回吧?浪费...其实可以从winsock的state属性知道对方是否关闭了...
    正常退出:winsock.close.对方的state属性为"同级人员正在关闭..."详见:MSDN
    非正常退出:程序出错,进程被杀.对方的state属性为"错误..."另,还可以从winsock的Error事件里得知更多的信息!也是详见:MSDN :) frankwong(黄梓钿) 问题还没解决?
    发送你出错的那部分代码到:[email protected]
      

  18.   

    to qyii:
    代码已经发给您了