C# TCP/IP消息帧
我制作了一个TCP/IP服务器/客户端,它是异步的,但是它连接了消息。如何正确地在开头添加标题,然后在结尾使用字符串生成器取消连接完整消息 服务器读取消息:C# TCP/IP消息帧,c#,vb.net,sockets,networking,tcp,C#,Vb.net,Sockets,Networking,Tcp,我制作了一个TCP/IP服务器/客户端,它是异步的,但是它连接了消息。如何正确地在开头添加标题,然后在结尾使用字符串生成器取消连接完整消息 服务器读取消息: Private Sub ReadCallback(ByVal result As IAsyncResult) Try allDone.Set() Dim success As Boolean = result.AsyncWaitHandle.WaitOne(500, True) I
Private Sub ReadCallback(ByVal result As IAsyncResult)
Try
allDone.Set()
Dim success As Boolean = result.AsyncWaitHandle.WaitOne(500, True)
If success Then
Dim client As ServerClient = TryCast(result.AsyncState, ServerClient)
If client Is Nothing Then
Return
End If
Dim networkStream As NetworkStream = client.NetworkStream
Dim read As Integer = networkStream.EndRead(result)
If read = 0 Then
SyncLock Me.Clients
Me.Clients.Remove(client.ClientID)
Return
End SyncLock
End If
If client.NetworkStream.CanRead Then
dataString.Append(Me.Encoding.GetString(client.buffer, 0, read))
networkStream.BeginRead(client.buffer, 0, client.buffer.Length, AddressOf ReadCallback, client)
allDone.WaitOne(500, True)
End If
End If
Catch ex As IO.IOException
Dim client As ServerClient = TryCast(result.AsyncState, ServerClient)
SyncLock Me.Clients
Me.Clients.Remove(client.ClientID)
Return
End SyncLock
Catch ex As Exception
If Not Me.tcpListener.Server.Connected Then
Return
End If
End Try
End Sub
Public Function Write(value As String, encoding As Encoding) As Guid
Dim buffer As Byte() = encoding.GetBytes(value)
Return Me.Write(buffer)
End Function
Public Function Write(buffer As Byte()) As Guid
Dim guid__1 As Guid = Guid.NewGuid()
Dim networkStream As NetworkStream = Me.client.GetStream()
Dim result As IAsyncResult = networkStream.BeginWrite(buffer, 0, buffer.Length, Nothing, guid__1)
result.AsyncWaitHandle.WaitOne()
networkStream.EndWrite(result)
Return guid__1
End Function
客户端写入消息:
Private Sub ReadCallback(ByVal result As IAsyncResult)
Try
allDone.Set()
Dim success As Boolean = result.AsyncWaitHandle.WaitOne(500, True)
If success Then
Dim client As ServerClient = TryCast(result.AsyncState, ServerClient)
If client Is Nothing Then
Return
End If
Dim networkStream As NetworkStream = client.NetworkStream
Dim read As Integer = networkStream.EndRead(result)
If read = 0 Then
SyncLock Me.Clients
Me.Clients.Remove(client.ClientID)
Return
End SyncLock
End If
If client.NetworkStream.CanRead Then
dataString.Append(Me.Encoding.GetString(client.buffer, 0, read))
networkStream.BeginRead(client.buffer, 0, client.buffer.Length, AddressOf ReadCallback, client)
allDone.WaitOne(500, True)
End If
End If
Catch ex As IO.IOException
Dim client As ServerClient = TryCast(result.AsyncState, ServerClient)
SyncLock Me.Clients
Me.Clients.Remove(client.ClientID)
Return
End SyncLock
Catch ex As Exception
If Not Me.tcpListener.Server.Connected Then
Return
End If
End Try
End Sub
Public Function Write(value As String, encoding As Encoding) As Guid
Dim buffer As Byte() = encoding.GetBytes(value)
Return Me.Write(buffer)
End Function
Public Function Write(buffer As Byte()) As Guid
Dim guid__1 As Guid = Guid.NewGuid()
Dim networkStream As NetworkStream = Me.client.GetStream()
Dim result As IAsyncResult = networkStream.BeginWrite(buffer, 0, buffer.Length, Nothing, guid__1)
result.AsyncWaitHandle.WaitOne()
networkStream.EndWrite(result)
Return guid__1
End Function
您需要在TCP/IP之上定义一个(可能是精简且简单的)协议,以允许您知道一条消息的开始和结束位置。TCP/IP可以并且将分割您发送的消息,以便接收方可以获取部分消息、整个消息或多条消息。一种简单的方法是编写消息长度,然后是消息。然后,接收器读入字节缓冲区,一旦接收到适当数量的字节(基于发送的长度),消息就可以被提取出来并编码成字符串。当前代码中需要注意的一点是:不能保证(除非使用ASCII/代码页)您得到了整个字符。。。你可以有半个字符。我解决这个问题的一个方法是在消息末尾使用一个特殊字符,这样读者(服务器/客户端)可以继续阅读,直到他得到这个字符。在将字节转换为字符串的地方可以检查是否存在此字符。回答得好。这里有更多信息: