我使用异步TCP服务器套接字得到一个奇怪的行为。 我跟着这个Microsoft example
首先,我发现使用示例中提供的代码我可以成功地只成为第一个TCP请求(我改为代码来处理我所需的modbus实现),因为在示例中指出服务器发送响应之后必须关闭处理程序:
Public Shared Sub sendCallback(ByVal ar As IAsyncResult)
' Retrieve the socket from the state object.
'Dim handler As Socket = CType(ar.AsyncState, Socket)
' Complete sending the data to the remote device.
Dim bytesSent As Integer = handler.EndSend(ar)
'Console.WriteLine("Sent {0} bytes to client.", bytesSent)
handler.Shutdown(SocketShutdown.Both)
handler.Close()
' Signal the main thread to continue.
allDone.Set()
End Sub
但是,当我使用TCP客户端发出第二个请求时,会发生错误(无法访问close对象或类似的东西)。好吧,我改变了代码注释了两行:
'handler.Shutdown(SocketShutdown.Both)
'handler.Close()
一切都很好......对于一个" n"要求。 我发现在32767消息(在win7上)和2500之后(在非常旧的XP上),服务器拒绝该请求,并且必须重新连接客户端。 这里是代码的相关部分:
Public Shared listener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
接受部分:
listener.Bind(localEP)
listener.Listen(100)
While True
' Set the event to nonsignaled state.
allDone.Reset()
' Start an asynchronous socket to listen for connections.
listener.BeginAccept(New AsyncCallback(AddressOf acceptCallback), listener)
' Wait until a connection is made and processed before continuing.
allDone.WaitOne()
End While
回调:
Public Shared Sub acceptCallback(ByVal ar As IAsyncResult)
Try
' Signal the main thread to continue.
allDone.Set()
' Get the socket that handles the client request.
Dim listener As Socket = CType(ar.AsyncState, Socket)
' End the operation.
handler = listener.EndAccept(ar)
' Create the state object for the async receive.
Dim state As New StateObject
While handler.Connected
state.workSocket = handler
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf readCallback), state)
End While
Catch ex As Exception
File.AppendAllText("log.txt", ex.Message & vbCrLf & ex.StackTrace & vbCrLf)
End Try
End Sub
Public Shared Sub readCallback(ByVal ar As IAsyncResult)
' Retrieve the state object and the handler socket
' from the asynchronous state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)
handler = state.workSocket
Dim rxBuf(12) As Byte
Dim i As Integer
handler = state.workSocket
Try
' Read data from the client socket.
'If (handler.Connected = False) Then
' handler = listener.EndAccept(ar)
'End If
Dim read As Integer = handler.EndReceive(ar)
' Data was read from the client socket.
If read >= 12 Then
ReDim rxBuf(read - 1)
For i = 0 To read - 1
rxBuf(i) = state.buffer(i)
Next
'Array.Clear(state.buffer, 0, state.buffer.Length)
TCPRequestRespond(rxBuf, handler)
'Else
' ' Not all data received. Get more.
' handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
' New AsyncCallback(AddressOf readCallback), state)
End If
Catch ex As Exception
Dim s As String = ex.StackTrace.ToString
File.AppendAllText("log.txt", ex.Message & vbCrLf & ex.StackTrace & vbCrLf)
End Try
End Sub 'readCallback
在:
Dim read As Integer = handler.EndReceive(ar)
如果我不评论之前指定的2行,我会在哪里得到错误。 然后TCPRequestRespond只是创建消息,然后开始发送它:
handler.BeginSend(TxBuf, 0, txCount, 0, New AsyncCallback(AddressOf sendCallback), handler)
发送回调是此问题中首次报告。 任何的想法?我发现服务器使用有限的请求响应号非常奇怪。 我发现了很多关于短暂端口限制的文档,但事实并非如此(我们只有一个连接)。