我编写了一个通过SslStream进行通信的TcpClient和Server。 通信工作正常,但是当我从客户端向服务器发送消息时,首先服务器读取1个字节,然后在下一步中读取其余部分。示例:我想通过客户端发送“test”,服务器先收到“t”,然后“est”
以下是客户端发送的代码
public void Send(string text) {
byte[] message = Encoding.UTF8.GetBytes(text);
SecureStream.BeginWrite(message, 0, message.Length, new AsyncCallback(WriteCallback), null);
}
private void WriteCallback(IAsyncResult AR) {
}
这里是服务器用来读取的代码
private SslStream CryptedStream = ...;
private byte[] buffer = new byte[1024];
public void BeginReadCallback(IAsyncResult AsyncCall) {
// initialize variables
int bytesRead = 0;
try {
// retrieve packet
bytesRead = CryptedStream.EndRead(AsyncCall);
// check if client has disconnected
if (bytesRead > 0) {
// copy buffer to a temporary one
var temporaryBuffer = buffer;
Array.Resize(ref temporaryBuffer, bytesRead);
string read = Encoding.ASCII.GetString(temporaryBuffer);
SetText(read);
// read more data
CryptedStream.BeginRead(buffer, 0, 1024, new AsyncCallback(BeginReadCallback), null);
// client is still connected, read data from buffer
//ProcessPacket(temporaryBuffer, temporaryBuffer.Length, helper);
} else {
// client disconnected, do everything to disconnect the client
//DisconnectClient(helper);
}
} catch (Exception e) {
// encountered an error, closing connection
// Program.log.Add(e.ToString(), Logger.LogLevel.Error);
// DisconnectClient(helper);
}
}
我错过了什么吗? 谢谢你的帮助
答案 0 :(得分:1)
正如Lasse所解释的那样,流式API并不保证每次读取都会返回特定数量的字节。
最好的解决方法是不使用套接字。使用更高级别的API,例如WCF,SignalR,HTTP,......
如果您坚持认为可能应该使用BinaryReader/Writer
来发送您的数据。这很容易。例如,它内置了字符串发送。您也可以使用这些类轻松地手动长度前缀。
可能您不需要异步IO,也不应该使用它。如果你坚持认为你至少可以使用await
来消除回调。