首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

关于winsock控件疑似“粘包”的有关问题

2012-01-08 
关于winsock控件疑似“粘包”的问题问题:在模拟一个设备和服务器的程序网络通信时,在通讯的过程中,模拟设备A

关于winsock控件疑似“粘包”的问题
问题:
在模拟一个设备和服务器的程序网络通信时,
在通讯的过程中,模拟设备A发送指定字节(如360byte)的数据后,服务器程序B在收到设备A的指定长度的数据后,会响应一个命令;然后A在接收到这个命令后,才会继续发送接下来的数据;如果没有收到B返回的响应命令,则也会在等待16s后自动发送。如此反复。 但在A的日志文件中记录到在超时自动发送之后,收到的数据是B返回的两个命令。感觉像是B其实早就把命令发出来了(或者B在代码中已调用senddata发送,但系统并没有立即真的发送出来,嫌数据少?),但A一直没收到,所以等待16s后自动发送。

有没有方法能保证在代码中调用winsock.senddata之后,系统不管数据有多少,哪怕只有一个字节,也立即给我发出去?

PS.
1、A、B之间发送的数据都是已经有指定的数据结构,所以即使多条数据过来,是可以正常拆分的。但是由于这两个程序之间的通讯是有时间要求的,不能超时16s,所以如果数据接收的时间延迟了,就算是错误的了。
2、tcp能保证数据的完整和顺序,但winsock控件能不能保证发送的“即时性”?

[解决办法]
tcp除了保证数据的完整和顺序,并不保证传送时间的固定性,就像邮局一样,多个包几乎同时送达是正常现象。
不过从你16s的等待看,问题估计不是传送的问题,几十个字节要什么网络会这么慢。
应该是服务器比较忙,响应不及时才导致客户端误判的。
其实你可以让服务端收到后马上回复一下,表示已收到,等真正执行后再将结果发回去。这样客户端收到第一个应答后可以将等待时间延长,如果这时再超时,通常是服务器或网络有问题了,重发不一定有意义了。
[解决办法]
有点点延迟是正常的,但如果16s就不对了,楼主仔细看看代码是否有问题?
[解决办法]
一般会送出去马上收到,延迟小于1秒,人是很难感觉到不同是。
刷新下流(流.flush),马上处理流中的数据。
[解决办法]

探讨
怎么在代码中把一段文字标注为红色 不起作用了???
直接显示【color...?

[解决办法]
响应命令之类的握手信号用udp发送吧,那个即时
[解决办法]
探讨让服务端收到后马上回复一下,表示已收到,等真正执行后再将结果发回去。

[解决办法]
C 是专职的,可以马上回应。
如果 B 正在忙来不及响应,A 就不知道命令已送达。
[解决办法]
TCP 收发消息有严格的时间控制。
仅仅是ACK包就占用半数以上带宽,太难做了吧
特来佩服LZ
[解决办法]
有没有方法能保证在代码中调用winsock.senddata之后,系统不管数据有多少,哪怕只有一个字节,也立即给我发出去?

调用winsock.senddata之后马上exit sub 执行其他的过程,一般会马上发出去,如果还在那个过程中执行比如数据库检索这种大块头,数据就不会发出去~~貌似如此


[解决办法]
调用winsock.senddata之后,紧跟一个doevents试试.
[解决办法]
很复杂,很弱,学习漂过。。。
[解决办法]
我觉得,应该有一个心跳机制.

每两秒发一次心跳包.

猜测是,上层数据已到达下层的发送缓冲区,本来应该被扫描发送,但由于上层的某些原因导致发送命令未正确送达,丢失了(比如上层调用了SLEEP导致挂起,或刚好处于某个循环中之类的无响应状态),那么数据虽然还是在缓冲区里,但却没来得及发送.

如果是这样,心跳包那就会有效,因为又有新的发送指令了.

以上思路作为一种尝试吧.
[解决办法]
有!
请在所有需要SendData的地方不要直接调用SendData,而是
dim SD as String'全局变量
...
dim after ad double
SD=要发送的数据
TimerSD.Interval=1
TimerSD.enabled=True
after = Now + 5# / 24# / 3600#
do
 doevents
 if TimerSD.enabled=False then exit do
 If Now > after Then
Msgbox "send data 5s overtime!"
Exit Do
 End If
loop
...
Private Sub TimerSD_Timer()
On Error GoTo MSerr
tcpServer.SendData SD
TimerSD.enabled=false
Exit Sub
MSerr:
If Err.Number = 40006 Then
TimerSD.enabled=false
Exit Sub
Else
TimerSD.enabled=false
tcpServer_Close
Exit Sub
End If
end Sub
试试看吧
[解决办法]
估计跟不要在中断处理程序中处理数据而要将数据放入FIFO队列立即退出中断,另一道程序发现FIFO队列中有数据再取出处理并发送反馈到中断请求方的原因类似吧

热点排行
Bad Request.