none
vb.net TCP多客户端连接,异步方式的一个问题. RRS feed

  • 问题

  • 下面的连接是以前我发的一个帖子,今天才有时间拿来测试,但是碰到了问题.
    想问问大家有没有好的解决方法? 以下是代码,是从MSDN上找到的.
    Imports System
    
    
    
    Imports System.Net
    
    
    
    Imports System.Net.Sockets
    
    
    
    Imports System.Text
    
    
    
    Imports System.Threading
    
    
    
    Imports Microsoft.VisualBasic
    
    
    
    Module Module1
    
    
    
    
    
    
    
        Sub Main()
    
    
    
            Dim ttt As New AsynchronousSocketListener
    
    
    
            AsynchronousSocketListener.Main()
    
    
    
        End Sub
    
    
    
    
    
    
    
    End Module
    
    
    
    
    
    
    
    
    
    
    
    ' State object for reading client data asynchronously
    
    
    
    
    
    
    
    Public Class StateObject
    
    
    
        ' Client  socket.
    
    
    
        Public workSocket As Socket = Nothing
    
    
    
        ' Size of receive buffer.
    
    
    
        Public Const BufferSize As Integer = 1024
    
    
    
        ' Receive buffer.
    
    
    
        Public buffer(BufferSize) As Byte
    
    
    
        ' Received data string.
    
    
    
        Public sb As New StringBuilder
    
    
    
    End Class 'StateObject
    
    
    
    
    
    
    
    
    
    
    
    Public Class AsynchronousSocketListener
    
    
    
        ' Thread signal.
    
    
    
        Public Shared allDone As New ManualResetEvent(False)
    
    
    
    
    
    
    
        ' This server waits for a connection and then uses  asychronous operations to
    
    
    
        ' accept the connection, get data from the connected client, 
    
    
    
        ' echo that data back to the connected client.
    
    
    
        ' It then disconnects from the client and waits for another client. 
    
    
    
        Public Shared Sub Main()
    
    
    
            ' Data buffer for incoming data.
    
    
    
            Dim bytes() As Byte = New [Byte](1023) {}
    
    
    
    
    
    
    
            ' Establish the local endpoint for the socket.
    
    
    
            Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
    
    
    
            Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
    
    
    
            Dim localEndPoint As New IPEndPoint(ipAddress , 11000)
    
    
    
    
    
    
    
            ' Create a TCP/IP socket.
    
    
    
            Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    
    
    
    
    
    
    
            ' Bind the socket to the local endpoint and listen for incoming connections.
    
    
    
            listener.Bind(localEndPoint)
    
    
    
            listener.Listen(100)
    
    
    
    
    
    
    
            While True
    
    
    
                ' Set the event to nonsignaled state.
    
    
    
                allDone.Reset()
    
    
    
    
    
    
    
                ' Start an asynchronous socket to listen for connections.
    
    
    
                Console.WriteLine("Waiting for a connection...")
    
    
    
                listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
    
    
    
    
    
    
    
                ' Wait until a connection is made and processed before continuing.
    
    
    
                allDone.WaitOne()
    
    
    
            End While
    
    
    
        End Sub 'Main
    
    
    
    
    
    
    
    
    
    
    
        Public Shared Sub AcceptCallback(ByVal ar As IAsyncResult)
    
    
    
            ' Get the socket that handles the client request.
    
    
    
            Dim listener As Socket = CType(ar.AsyncState, Socket)
    
    
    
            ' End the operation.
    
    
    
            Dim handler As Socket = listener.EndAccept(ar)
    
    
    
    
    
    
    
            ' Create the state object for the async receive.
    
    
    
            Dim state As New StateObject
    
    
    
            state.workSocket = handler
    
    
    
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
    
    
    
        End Sub 'AcceptCallback
    
    
    
    
    
    
    
    
    
    
    
        Public Shared Sub ReadCallback(ByVal ar As IAsyncResult)
    
    
    
            Dim content As String = String.Empty
    
    
    
    
    
    
    
            ' Retrieve the state object and the handler socket
    
    
    
            ' from the asynchronous state object.
    
    
    
            Dim state As StateObject = CType(ar.AsyncState, StateObject)
    
    
    
            Dim handler As Socket = state.workSocket
    
    
    
    
    
    
    
            ' Read data from the client socket. 
    
    
    
            Dim bytesRead As Integer = handler.EndReceive(ar)
    
    
    
    
    
    
    
            If bytesRead > 0 Then
    
    
    
                ' There  might be more data, so store the data received so far.
    
    
    
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))
    
    
    
    
    
    
    
                ' Check for end-of-file tag. If it is not there, read 
    
    
    
                ' more data.
    
    
    
                content = state.sb.ToString()
    
    
    
                If content.ToLower.IndexOf("<eof>") > -1 Then
    
    
    
                    ' All the data has been read from the 
    
    
    
                    ' client. Display it on the console.
    
    
    
                    Console.WriteLine("Read {0} bytes from socket. " + vbLf + " Data : {1}", content.Length, content)
    
    
    
                    ' Echo the data back to the client.
    
    
    
                    Send(handler, content)
    
    
    
                Else
    
    
    
                    ' Not all data received. Get more.
    
    
    
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
    
    
    
                End If
    
    
    
            End If
    
    
    
        End Sub 'ReadCallback
    
    
    
    
    
    
    
        Private Shared Sub Send(ByVal handler As Socket, ByVal data As String)
    
    
    
            ' Convert the string data to byte data using ASCII encoding.
    
    
    
            Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)
    
    
    
    
    
    
    
            ' Begin sending the data to the remote device.
    
    
    
            handler.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), handler)
    
    
    
        End Sub 'Send
    
    
    
    
    
    
    
    
    
    
    
        Private 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 'SendCallback
    
    
    
    End Class 'AsynchronousSocketListener
    
    

       今天趁空测试了一下上面的代码,发现一个问题,就是客户端消息是遵循先进先出原则的,就是说我有好多客户端发送给服务端消息的话,一定要等到最先连接的客户端发送<EOF>字串之后才能继续操作.这样在正常情况下没有问题,但是万一某个客户端发送的字串中由于某种意外的原因没有了<EOF>的话,它后面的所有消息都没法继续,导致服务端一直挂起了...
       不知道该怎么来解决这个问题呢?
    • 已编辑 picat 2009年5月2日 8:42
    2009年5月2日 8:36

答案

全部回复