写入服务器的不同数据正在附加成为一个字符串

Different data written to the server are becoming appended to become a single string

N.B。参考.

我写这个class是为了在服务器端用作代理,在客户端用作客户端。

我当前的源代码如下:

public class ClientClass : IDisposable
{
    private string Host { get; set; }
    private int Port { get; set; }

    public bool IsConnected { private set;  get; }

    public TcpClient Tcp { get; private set; }

    private System.Net.Sockets.NetworkStream stream;

    public ClientClass()
    {
        IsConnected = false;
    }

    //constructor for server program.
    public ClientClass(TcpListener listener)
    {
        Tcp = listener.AcceptTcpClient();

        Host = ((IPEndPoint)Tcp.Client.RemoteEndPoint).Address.ToString();
        Port = ((IPEndPoint)Tcp.Client.LocalEndPoint).Port;

        IsConnected = true;

        stream = Tcp.GetStream();
    }

    //constructor for client.
    public ClientClass(string host, int port)
    {
        Host = host;
        Port = port;
    }

    public string Read()
    {
        if (IsConnected)
        {
            byte[] buffer = new byte[Tcp.ReceiveBufferSize];//create a byte array
            int bytesRead = stream.Read(buffer, 0, Tcp.ReceiveBufferSize);//read count
            string str = Encoding.ASCII.GetString(buffer, 0, bytesRead);//convert to string
            return str.TrimEnd(new char[] {'\r', '\n'});//remove CR and LF
        }
        else
        {
            throw new Exception("Client " + ID + " is not connected!");
        }
    }

    public void Write(string str)
    {
        if (IsConnected)
        {
            str = str + Constants.CRLF;// add CR and LF
            byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(str);
            stream.Write(bytesToSend, 0, bytesToSend.Length);
            stream.Flush();
        }
        else
        {
            throw new Exception("Client " + ID + " is not connected!");
        }
    }

    public bool Connect()
    {
        if (IsConnected == false)
        {
            IsConnected = true;

            Tcp = new TcpClient(Host, Port);

            stream = Tcp.GetStream();

            return true;
        }

        return false;
    }

    public bool Disconnect()
    {
        if (IsConnected)
        {
            if (Tcp != null)
            {
                //stream.Flush();
                stream.Close();
                //Tcp.GetStream().Flush();
                //Tcp.GetStream().Close();
                Tcp.Close();

                return true;
            }
        }

        return false;
    }

    #region dispose pattern
    // Flag: Has Dispose already been called?
    bool disposed = false;

    // Public implementation of Dispose pattern callable by consumers.
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    // Protected implementation of Dispose pattern.
    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            // Free any other managed objects here
            if (stream != null)
            {
                stream.Flush();
                stream.Close();
                stream.Dispose();
                stream = null;
            }
            if (Tcp != null)
            {
                if (Tcp.Connected)
                {
                    Tcp.Client.Disconnect(false);
                    Tcp.Client.Close();
                    Tcp.Client.Dispose();
                    Tcp.Client = null;

                    //Tcp.GetStream().Flush();
                    //Tcp.GetStream().Close();
                    Tcp.Close();                        
                    Tcp = null;
                }
            }
        }

        // Free any unmanaged objects here.
        // ...
        disposed = true;
    }

    ~ClientClass()
    {
        Dispose(false);
    }
    #endregion
}

我遇到的问题是:

ClientClass client = new ClientClass(...);
client.Write("1");
client.Write("2");
client.Write("hello");

将作为唯一输入到达另一端:

"12hello"

,而不是三个单独的输入 {"1"、"2" 和 "hello"}。

我该如何解决这个问题?


TCP 是流协议,不是数据包协议。您所保证的只是相同顺序的相同字节(或套接字故障), 而不是 组的组成。所以:除此之外的任何内容 你都需要自己添加 。对于基于文本的协议,一种常见的方法可能是在每个逻辑负载之后放置一个换行符 (\n),然后在解码时查找相同的内容。对于二进制协议,长度前缀更为常见。