热情软件屋

 

Client端SendData了四次数据,但Server端的DataArrival事件只发生了一次


编号:QA004638
建立日期: 2002年11月25日 最后修改日期:2002年11月25日
所属类别:

陈韶斌:
    操作系统:Windows 2000
    编程工具:vb6.0
    问题:下面是我在编程中遇到的一个问题:我用VB编了一个客户端/服务器程序,client端用一个循环发送一个字符串数组的4个元素,如下所示:
     str1(0)="zero"
     str1(1)="one"
     str1(2)="two"
     str1(3)="three"
     for i = 0 to 3
     winsock_client.SendData str1(i)
     sleep(100) ' 为了使SendData之间有时间间隙
     Next i
    

    server端在DataArrival事件中的程序如下:
     winsock_server.GetData str1,vbString
     debug.print str1
    

    我期望的结果是(在debug窗口内)
     zero
     one
     two
     three
    但实际上是
     zeroonetwothree
    也就是说client端senddata了四次(且每两次之间都有延时),但server端的DataArrival事件只发生了一次,这使得不同次SendData发送出的多个数据都粘连在一起了,请问这是什么原因造成的?
    我把winsock_client.senddata放到timer_timer中,结果可以在server端产生四次DataArrival事件,数据不会粘连,但我的程序不可能允许把winsock_client.senddata放到timer_timer中,请问该如何解决?

回答:

    HappyXiaoXing的意见:
    这个问题的关键在于发送数据时用的延时方式,sleep并不能解决问题,应该使用DoEvents。sleep 是暂停进程,它不会把信息发出,DoEvents是把控制权交给系统,它会把信息发出去,所以要使用DoEvents。还有如果客户端下在处理大量的事务时,最后的也会出现问题上的情况,所以只有客户端和服务器都比较空闲时才会正确接收和发送。
    
    ipdown.com的意见:
    这个问题我以前也遇到过,解决方法如下:
    由于你用的 Sleep 函数来拖延时间,所以当一个 SendData 发送到缓冲区时,整个程序就开始 Sleep 了,包括动态连接库,缓冲区  的数据没有发出,但下一个数据又来了,这些数据就会堆积在一起,直到缓冲区慢 (默认为 8192 字节)。你可以采用如下两种方法解决。
    1:
          t = Timer
          Do
          DoEvents
          If Timer - t >= 100 Then Exit Do
          Loop
          ... 用它代替 Sleep(100)
    
    2:建立一个 OLE/DDE 服务器,放置 Timer 控件,通知你的程序,如果为不可见界面则用 WinSock 通知 (API 操作 DDE 也可以)。
    
    刘林海的意见:
    '增加一个变量
    Public SendComplete As Boolean
    
    Winsock_SendComplete()
    SendComplete=True
    Sleep(100)
    End Sub
    Winsock_SendProgress (bytesSent As Long, bytesRemaining As Long)
    SendComplete=False
    End Sub
    
     str1(0)="zero"
     str1(1)="one"
     str1(2)="two"
     str1(3)="three"
     for i = 0 to 3
     winsock_client.SendData str1(i)
     do until SendComplete=True
     doevents
     loop
     Next i
    

    
    Luo, Rui的意见:
    在发送端循环中加个DoEvents试试.
    另,这样通讯最好使用某种协议自己处理数据单位,比如对于你的情况可以这样:
    zero
    one
    two
    three
    这样接收端可以通过分析所得到的数据流析出数据来.
    
    stone的意见:
    Winsock控件有一个特殊的地方,就是它把数据先放入缓冲区然后再发送。在发送数据循环中使用如下方式即可。
    for i = 0 to 3
     winsock_client.SendData str1(i)
     doevents '发送
    Next i
    
    

    aDe的意见:
    将senddata后的sleep(100)改成doevents。已在同一台机上试验成功。这应该是由于sleep是将系统暂停,而doevents则是处理其他事务的区别吧。
    
    吹云的意见:
    你的代码中:
    sleep(100) ' 为了使SendData之间有时间间隙
    这句要看网络情况而定,网络慢,传输的数据还会在一起的,
    网络快,你这里浪费了好多时间(如果传输的数据多)
    (解决:)使用握手的方法,
    1)发一个数据
    2)收到后发一个确认收到(如:wsk.senddata "OK")
    3)发下一个数据……(如此循环)
    
    damo的意见:
    因为client端发送数据速度过快导致server端接收数据发生粘连,有两个较笨的解决方法如下:
    方法一:client端每发送一个数组元素时,要求sever端发送一个已接收到的回应信息比如"OK",
    当client端接收到server端的回应信息后才继续发送下一个数组元素。我也曾遇到这个问题就是这样解决的。
    方法二:client端发送一个数组元素后再发送一个分隔符,比如chr(255),再接着发送下一个数组元素,再在server端根据分隔符进行字符串分解,将粘连的数据重新分解成一个个的数组元素。
    
    catzhou的意见:
    客户端
    winsock_client.SendData "ok?"
    int i=0
    winsock_client.GetData str1,vbString
    if str="ok" then
     winsock_client.SendData str1(i)
     i=i+1
    endif
    

    
    winsock_server.GetData str1,vbString
     if str1<>"ok?" then
     debug.print str1
     endif
     winsock_server.SendData "ok"
    

    
    qg163的意见:
    我用的是WIN98,我是这样做的:
    server端dataarrival时
     TCPServer.GetData DataReceived, vbString
     Debug.Print DataReceived
     TCPServer.SendData "ok"
    
    

    
    client端
    DIM A AS BOOLEAN
    
    PRIVATE SUB ABC()
     Dim str1(3) As String, i
     str1(0) = "zero"
     str1(1) = "one"
     str1(2) = "two"
     str1(3) = "three"
     For i = 0 To 3
     a = False
     sktTCPChatClient.SendData str1(i)
    
     Do While a = False
     DoEvents
     Loop
     Next i
    END SUB
    
    Private Sub TCPClient_DataArrival(ByVal bytesTotal As Long)
     Dim vtData As Variant
     TCPClient.GetData vtData, vbString
     If vtData = "ok" Then a = True
    End Sub
    
    
如您有更好的办法,请给我也发一份代码。

此问题由HappyXiaoXing等回答。

 
把这个问题推荐给朋友
   
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio