SslStream EndRead获得前1个字节

时间:2016-05-02 12:28:06

标签: c# read-write sslstream

我编写了一个通过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);
        }
    }

我错过了什么吗? 谢谢你的帮助

1 个答案:

答案 0 :(得分:1)

正如Lasse所解释的那样,流式API并不保证每次读取都会返回特定数量的字节。

最好的解决方法是不使用套接字。使用更高级别的API,例如WCF,SignalR,HTTP,......

如果您坚持认为可能应该使用BinaryReader/Writer来发送您的数据。这很容易。例如,它内置了字符串发送。您也可以使用这些类轻松地手动长度前缀。

可能您不需要异步IO,也不应该使用它。如果你坚持认为你至少可以使用await来消除回调。