SslStream EndRead 获取第一个 1 字节
SslStream EndRead gets first 1 Byte
我编写了一个通过 SslStream 进行通信的 TcpClient 和服务器。
通信有效,但是当我从客户端向服务器发送消息时,服务器首先读取 1 个字节,然后在下一步中读取其余部分。例子:我想通过Client发送"test",Server先收到"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);
}
}
我错过了什么吗?
感谢您的帮助
正如 Lasse 解释的那样,流式传输 API 不会向您保证每次读取 return 特定的字节数。
最好的解决方法是不使用套接字。使用更高级别 API,例如 WCF、SignalR、HTTP、...
如果您坚持,您可能应该使用 BinaryReader/Writer
来发送您的数据。这使得它很容易。例如,它内置了字符串发送功能。您还可以使用 类.
轻松地手动设置长度前缀
您可能不需要异步 IO,也不应该使用它。如果你坚持你至少可以通过使用 await
.
来摆脱回调
我编写了一个通过 SslStream 进行通信的 TcpClient 和服务器。 通信有效,但是当我从客户端向服务器发送消息时,服务器首先读取 1 个字节,然后在下一步中读取其余部分。例子:我想通过Client发送"test",Server先收到"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);
}
}
我错过了什么吗? 感谢您的帮助
正如 Lasse 解释的那样,流式传输 API 不会向您保证每次读取 return 特定的字节数。
最好的解决方法是不使用套接字。使用更高级别 API,例如 WCF、SignalR、HTTP、...
如果您坚持,您可能应该使用 BinaryReader/Writer
来发送您的数据。这使得它很容易。例如,它内置了字符串发送功能。您还可以使用 类.
您可能不需要异步 IO,也不应该使用它。如果你坚持你至少可以通过使用 await
.