套接字的TCP消息限制

时间:2016-10-27 07:46:47

标签: vb.net sockets asynchronous tcp asyncsocket

我使用异步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)

发送回调是此问题中首次报告。 任何的想法?我发现服务器使用有限的请求响应号非常奇怪。 我发现了很多关于短暂端口限制的文档,但事实并非如此(我们只有一个连接)。

0 个答案:

没有答案