server端是个单片机...我负责写client部分。
这个server端很烂,动不动就不响应动作.....winsock控件的senddata是异步的,只要送到缓冲就返回成功,这个完全没法用于判断是否发送成功。理论上说sendcomplete事件应当是缓冲区的数据发送结束并且接收到server端确认后才能触发,可是实际我监控程序TCP底层传输时,当winsock发送了PSH数据之后并没有收到server的ACK指令就触发了sendcomplete事件。望高手指点一下,到底怎么样才能监控到数据正确传输到server端呢... 或者winsock还有别的事件在收到server的ACK时触发?

解决方案 »

  1.   

    如果客户端发送错误, 会触发 Error 事件, Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)End Sub
    你在Error 中添加相关代码,看有没有发生错误.
      

  2.   

    对Error事件中其实也可以在sendcomplete事件中对数据进行校验
      

  3.   

    winsock控件的senddata函数是一个返回值等于Void的函数,所以不可能从senddata的函数返回参数告诉你发送失败。我只知道如果对方断线的话,要过很长一段时间,会从winsock的error事件中触发事件,告诉你winsock出错了。
      

  4.   

    感谢各位关注我的帖子 ^_^我知道tcp有自动重传机制....一次正常的通信过程中,当client发送了PSH包,其实很快就能收到server端的ACK确认,此时应当视为一次正常通信。当收不到ACK确认时,tcp协议会在一定延时之后再次发送PSH包,并期待server端确认。连续3次发送都无反应,才会通知上层程序报告数据发送失败。但是这个超时失败的错误要很长时间才能触发...我的程序根本无法接受这么长的等待时间。
    我的疑惑是sendcomplete事件并不是在client受到ACK确认后触发的,而是在PSH包发送后就触发了。
    我的想法是想办法监控client收到的ACK确认,当发送后一段时间(比如1秒)尚未收到ACK就视同此次发送失败。在程序上关掉该连接重新尝试。当然这种行为可能会导致server端收到重复的数据。但是没关系,我的应用可以接受这种情况。
      

  5.   

    似乎用winsock控件无法改变默认的超时时间~
      

  6.   

    用api做的话有SO_RCVTIMEO选项Winsock如何支持读超时 http://bbs.pediy.com/showthread.php?p=447418
      

  7.   

    To hellmester:
    我很长时间没用VB了,有些细节记不清了,提些思路你考虑一下。我以前用Winsock进行通讯的时候,并不喜欢用sendcomplete来判断另一端是否接受到,因为你并不知道数据在从一端到另一端的时候,中间都需要经过哪里。以前做这种程序,我一般喜欢是由接收端端自己发回一个消息来帮助发送端判断,这种方式也有利于发送端进一步判断接收端的状态,因为我们可以用不同的返回的命令来表示接收端的情况。出于很早以前写232串口通讯的习惯,我一般都习惯在用winsock的时候也加上一层自己的协议,格式一般是“start_flag cmd lenth cnt end_flag”,start_flag和end_flag是成对出现的,代表了需要传送的一包,cmd是你自己定义的一些命令,这些一般都是通信层需要的一些命令,比如测试链接、正常数据、接收正常等,lenth是cnt的长度,cnt是你真正通过winsock传递的东西。用类似这种方式来传递消息,坏处是你需要自己去判断来自winsock的各种数据,从中找出数据头、数据尾等;好处一是我们可以把数据的封装单独拿出来,以便以后改成比如usb通信、232通信等,二是你可以不用去关心winsock协议到底是怎么传的,因为我们自己定义了一层协议,winsock仅是一个通道。仅供参考。
      

  8.   

    非常感谢AresChen   ^_^ 我也考虑过类似的方案....可是我的server端是个固定的设备,无法编程的.....这个sendcomplete恐怕是winsock控件无法办到的吧......  我已经有点气馁了...  >_< 考虑直接用API来写了