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等回答。
| |
|
|
| |
|
|