关于 WinSock 的几个疑问,大家一定遇到过。那位高手能给我正确答案?

时间:2022-08-30 00:49:35
研究WinSock两天了,有一点收获,也有几个疑问,希望和大家讨论。

1、关于ConnectionRequest事件:
  我的理解是,仅当客户端计算机请求连接(也就是执行了Connect方法)时才发生。
  可是此时客户端的State是6(sckConnecting),如果因为某种原因客户端没有达到State 7(sckConnected),服务器端应该怎样判断客户端到底有没有成功连接?
  客户端成功连接之后 SendData 一个信息,服务器端收到之后,就可以判断“已经成功连接”了吧?

2、关于WinSock控件数组的加载
  我的服务器端把myWinSock(0)作为侦听用,LocalPort设定为“1001”。当客户端成功连接之后,动态加载WinSock控件。(myWinSock(0)只作为侦听)
  动态加载的新的WinSock控件的 LocalPort 应该怎么设定?
  有的例程将实际通信的WinSock控件的 LocalPort 与侦听用设定的相同。那么所有的客户端都使用服务器端的一个共同的端口对外通信,难道不会相互干扰吗?

  我的方法是,每一个新加载的控件数组的 LocalPort 都加1,也就是:
     myWinSock(0).LocalPort = 1001  '侦听用

     Load myWinSock(N)
     myWinSock(N).LocalPort = myWinSock(0).LocalPort + N  '实际通信用
  可是,如果我指定的端口刚好被其他程序使用,会出现什么状况?

3、将数据发送给远程计算机的 SendData 方法
  每次使用服务器端和客户端任何一方的 SendData 方法,我都判断是否状态为7:
     If myWinSock.State = sckConnected Then  
        SendData Data:="Hello"
        DoEvents
     End If

  我到底需不需要每次都判断状态?如果状态不是7,执行 SendData 方法会不会出错?
  DoEvents是不是必需的?

4、关于 DataArrival 事件:
  服务器端和客户端任何一方,是不是激活了 DataArrival 事件就意味着两方的连接没有问题?
  执行 GetData 时我需不需要判断状态是不是7,需不需要执行之后加上 DoEvents?

10 个解决方案

#1


1. 通过stste判断,能send且不出错说明已经连接
2. 不需要设定,或者说,设定为0,windows会自动分配
3. 这个随便,如果没连接就send,会有错误发生
4. 除非有特别要求(winsock有bug,有时候state为6的时候就可以触发data_arrival事件,几率取决于人品,我人品还好,暂时没碰到过),否则不需要

#2


楼上的搞笑!
对WinSock控件做任何操作之前检查状态是个好习惯,用错误处理也可,不过还是觉得能够自己处理的就自己处理。

#3


感谢二位的参与!

To fj182(阿花) :
  感谢你在“需要远程调用的C/S,我该选用COM+还是WinSock控件?各有什么好处? ”中的帮助!我已结贴。
  毕竟我现在只了解VB,我计划暂时先用VB和WinSock写程序,以后精通了C#之后再考虑COM+。

  以后多多帮助,谢谢!

#4


1.是否连接成功有一个事件有一个事件 Connect 客户端连接成功会触发这个事件
2。不需要设置 设置有时候会出错
3。2个都是必须 你不知道 服务器是否把你的连接断开 因此 加上此判断 2各作用 1避免错误 2断线重连,doevents是处理消息并发的一个方法,只是解决暂时问题 但是解决不了根本 
4。DataArrival 这个事件 是当一个数据包 senddate以后发生 因此有可能 在状态为6的时候触发 我想不是bug 这个事件 我 一般不用 一般用在需要分包处理的时候 如文件 的分包 我还见到有人用这个事件作发送的缓存 解决有时候 加上了doevents还会出现并发的情况

#5


感谢zyg0(影子(加班,加班,再加班)的指教!

1、不过我认为,服务端判断是否与客户端建立连接,不能用服务端的 Connect 事件。
   我的理解是,客户端执行 Connect 方法触发了服务端的 ConnectionRequest 事件,在 ConnectionRequest 事件中只有执行了 Accept 方法之后,才能说明本服务器端接受客户端的请求,从而触发客户端的 Connect 事件。
   服务端的 Connect 事件根本不会触发。
   我在服务端和客户端的 Connect 事件中都 Debug.Print 了调试,只有客户端的在立即窗口中出现。

2、新加载的控件数组的 LocalPort 看来只能设定为0,动态设定了。

3、这种每次使用 SendData 方法时都判断状态,DoEvents 释放CPU资源的习惯看来应该保持。

4、请问,如果不用 DataArrival 事件,怎么才能得到对方发送来的数据?
   我的理解是, GetData 方法只能在 DataArrival 事件中才能调用。

#6


再补充一个问题:
5、State 属性的sckOpen(1)和sckConnected(7)有什么不同?
   哪里有每个设置值详细的解释文档?其他几个设定值我不知道在什么情况下才会出现。

   MSDN中只有简单的解释:
        State 属性的设置值是:

        常数 值 描述 
        sckClosed 0 缺省的。关闭 
        sckOpen 1 打开 
        sckListening 2 侦听 
        sckConnectionPending  3 连接挂起 
        sckResolvingHost  4 识别主机 
        sckHostResolved  5 已识别主机 
        sckConnecting  6 正在连接 
        sckConnected  7 已连接 
        sckClosing  8 同级人员正在关闭连接 
        sckError  9 错误 

#7


4我看错了 也说错了

#8


0,1,2,6,7常用 其他的 3,4,5,-6太快了 没法抓住 8,9有时候也发生

#9


问题1  我只说客户端出发这个事件 这个只是请求方的事件
4 对 GetData 方法只能在 DataArrival 事件中才能调用。

#10


谢谢各位!
这几个问题我搞明白了。

#1


1. 通过stste判断,能send且不出错说明已经连接
2. 不需要设定,或者说,设定为0,windows会自动分配
3. 这个随便,如果没连接就send,会有错误发生
4. 除非有特别要求(winsock有bug,有时候state为6的时候就可以触发data_arrival事件,几率取决于人品,我人品还好,暂时没碰到过),否则不需要

#2


楼上的搞笑!
对WinSock控件做任何操作之前检查状态是个好习惯,用错误处理也可,不过还是觉得能够自己处理的就自己处理。

#3


感谢二位的参与!

To fj182(阿花) :
  感谢你在“需要远程调用的C/S,我该选用COM+还是WinSock控件?各有什么好处? ”中的帮助!我已结贴。
  毕竟我现在只了解VB,我计划暂时先用VB和WinSock写程序,以后精通了C#之后再考虑COM+。

  以后多多帮助,谢谢!

#4


1.是否连接成功有一个事件有一个事件 Connect 客户端连接成功会触发这个事件
2。不需要设置 设置有时候会出错
3。2个都是必须 你不知道 服务器是否把你的连接断开 因此 加上此判断 2各作用 1避免错误 2断线重连,doevents是处理消息并发的一个方法,只是解决暂时问题 但是解决不了根本 
4。DataArrival 这个事件 是当一个数据包 senddate以后发生 因此有可能 在状态为6的时候触发 我想不是bug 这个事件 我 一般不用 一般用在需要分包处理的时候 如文件 的分包 我还见到有人用这个事件作发送的缓存 解决有时候 加上了doevents还会出现并发的情况

#5


感谢zyg0(影子(加班,加班,再加班)的指教!

1、不过我认为,服务端判断是否与客户端建立连接,不能用服务端的 Connect 事件。
   我的理解是,客户端执行 Connect 方法触发了服务端的 ConnectionRequest 事件,在 ConnectionRequest 事件中只有执行了 Accept 方法之后,才能说明本服务器端接受客户端的请求,从而触发客户端的 Connect 事件。
   服务端的 Connect 事件根本不会触发。
   我在服务端和客户端的 Connect 事件中都 Debug.Print 了调试,只有客户端的在立即窗口中出现。

2、新加载的控件数组的 LocalPort 看来只能设定为0,动态设定了。

3、这种每次使用 SendData 方法时都判断状态,DoEvents 释放CPU资源的习惯看来应该保持。

4、请问,如果不用 DataArrival 事件,怎么才能得到对方发送来的数据?
   我的理解是, GetData 方法只能在 DataArrival 事件中才能调用。

#6


再补充一个问题:
5、State 属性的sckOpen(1)和sckConnected(7)有什么不同?
   哪里有每个设置值详细的解释文档?其他几个设定值我不知道在什么情况下才会出现。

   MSDN中只有简单的解释:
        State 属性的设置值是:

        常数 值 描述 
        sckClosed 0 缺省的。关闭 
        sckOpen 1 打开 
        sckListening 2 侦听 
        sckConnectionPending  3 连接挂起 
        sckResolvingHost  4 识别主机 
        sckHostResolved  5 已识别主机 
        sckConnecting  6 正在连接 
        sckConnected  7 已连接 
        sckClosing  8 同级人员正在关闭连接 
        sckError  9 错误 

#7


4我看错了 也说错了

#8


0,1,2,6,7常用 其他的 3,4,5,-6太快了 没法抓住 8,9有时候也发生

#9


问题1  我只说客户端出发这个事件 这个只是请求方的事件
4 对 GetData 方法只能在 DataArrival 事件中才能调用。

#10


谢谢各位!
这几个问题我搞明白了。