讨论:浅谈winsock ConnectionRequest事件
近期一直在研究sock编程(各种穿透代理服务器的方法),从控件级的编写到纯API的编写,在写了几个案例后,发现在使用控件编程时,二个事件的区别与费解。
在使用winsock编程时,会用到以下二个事件:Connect和ConnectionRequest
可能有朋友会说了,我在编写sock程式时并没有用到connect事件,只用了ConnectionRequest事件,达到了一样的效果(数据能够正确互通)。
Connect: 当一个 Connect 操作完成时发生。
ConnectionRequest: 当远程计算机请求连接时出现。
OK,上面是MSDN对上面二个事件的描述,仅从上面的描述来讲,只要是AB二地的通道正常打开,那么上面二个事件都将发生。
我们来举个例子(TCP为例):
A地(发起请求):
WinSock1.RemoteHost = “**.***.***.***”
WinSock1.RemotePort = 9000
WinSock1.connect
B地(响应请求):
Winsock1.LocalPort = 9000
Winsock1.Listen
调试上面的代码,你会发现仅当A地发出connect方法时,B地的ConnectionRequest事件才会进行响应
B地:
Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
‘仅当A地发出connect请求时,这里才会进行响应
dim strSend as string:strSend=”SendData”
Winsock1.Accept requestID
Do Until Winsock1.State = 7
DoEvents
Loop
Winsock1.SendData strSend
End Sub
A地:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
‘这里接收数据
End Sub
我看过许多VB程序员用上面的代码,写winsock程式,并且这么写也可以达到他们想要的效果(数据传输)。
那么如果我说上面的发送数据方代码有问题,你肯定会用鸡蛋砸我。
不知道这么写代码的程序员,有没有想过一个问题:就是我一开始就提出的
“OK,上面是MSDN对上面二个事件的描述,仅从上面的描述来讲,只要是AB二地的通道正常打开,那么上面二个事件都将发生。”
现在AB二地的通道已经打开,那么connect事件,究竟做了点啥?是不是微软疯了,同样的功能事件,设计员设计了相同的二个???
我刚才说了上面的发送方代码有问题:发送方端容易出现死循环
上面代码中,用循环不停的测试state的状态,仅当state=7时,才会终止循环,否则一直在移交控制权。
在大规模使用winsock的情况下,服务器端sock控件往往以数组形式出现,也就是说同一个sock控件会响应来自不同客户端的请求,而每个请求,服务器在接收后,都会进行一系列的处理(此时客户端state永远不会为7),然后才会响应客户端。也就是说如果服务器端在处理某个通道的逻辑时,发现了意外,那么此时此通道的客户端代码将变成死循环,可能你会说那是你服务器端代码写的不好,跟客户端代码没关系,但对于每个有点职业道德的程序员来讲,是不能够让自己的代码出现死循环的(这里指的是所有的商业代码)
那么如果是我,我会怎么改上面的代码呢,很简单我会用connect事件,接收服务端响应
Private Sub Winsock1_Connect()
Debug.print Winsock1.State
Winsock1.SendData strSend
End Sub
在Connect事件,如果你愿意可以像我一样每次响应时,都抛出state状态,看看它的状态是什么?
上面所写,仅代表个人意见与看法,欢迎大家讨论,有不对的地方请指正,谢谢!
[解决办法]
TCP/IP协议详解 第二册第一个例子的代码,你可以简单看下
connect 请求连接
listen 监听连接
ConnectionRequest 接收连接,返回确认,类似如下:
客户端服务器
||
请求连接监听请求
||
等待接收请求
||
等待返回标识(假设返回确认)
||
建立连接建立连接
客户端根据服务端的返回标识建立连接
其实这和TCP的三次握手很类似
如果有不对的地方请老大们指出,谢谢
[解决办法]
汗 我的tab都被CSDN吃了
[解决办法]
深奥呀
[解决办法]
每个事件都有它自己的作用,对于一次连接过程来说,Connect和ConnectionRequest事件只是发生在连接之初的,连接成功后就不会再发生了。
而DataArrival是发生在每次接收到数据时,A发送,到达B处,那么B就会发生DataArrival;B发送,到达A处,那么A就会发生DataArrival。
而那个ConnectionRequest,是在连接还没建立前,一方发出连接请求,另一方发生ConnectionRequest,它只会发生在被请求的一方。
不明白楼主怎么会对这几个事件纠缠不清。
[解决办法]
学习
[解决办法]
hao 联
[解决办法]
不太敢相信,那是商用代码...
ConnectionRequest是服务端握手确认的步骤,握手步骤是不应该破坏的,蓄意破坏用在这里常是属于flood的做法...
发送就不该是在握手过程调用的.因为一旦服务端忙,返回的是异常,那么数据就丢了,再者说这样的处理方式对于报文处理来说也不合理
后期维护人员会告诉客户,这是你们网络不稳定..丢包...
[解决办法]
ConnectionRequest我觉得就已经是连接建立了,只不过是给他分配本地的操作端口
[解决办法]