C#网络中的同步

C#网络中的同步,c#,tcp,tcpclient,tcpserver,C#,Tcp,Tcpclient,Tcpserver,我有一个简单的tcp服务器类 class Server { private TcpListener tcpListener; private Thread listenThread; public Server() { this.tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000); this.listenThread = new Thread(new

我有一个简单的tcp服务器类

 class Server
{
    private TcpListener tcpListener;
    private Thread listenThread;

    public Server()
    {
        this.tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000);
        this.listenThread = new Thread(new ThreadStart(ListenForClients));
        this.listenThread.Start();
        Console.WriteLine("Hello");
    }


    private void ListenForClients()
    {
        this.tcpListener.Start();

        while (true)
        {
            //blocks until a client has connected to the server
            TcpClient client = this.tcpListener.AcceptTcpClient();

            //create a thread to handle communication 
            //with connected client
            Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
            Console.WriteLine("New connexion");
            clientThread.Start(client);
        }
    }

    private void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();

        Console.WriteLine("Got Stream");

        byte[] message = new byte[4096];
        int bytesRead;

        Console.WriteLine("Initializing..");
        while (true)
        {
            bytesRead = 0;

            try
            {
                //blocks until a client sends a message
                Console.WriteLine("Reading..");
                bytesRead = clientStream.Read(message, 0, 4096);
                Console.WriteLine("Received something");
            }
            catch
            {
                //a socket error has occured
                break;
            }

            if (bytesRead == 0)
            {
                //the client has disconnected from the server
                break;
            }

            //message has successfully been received
            ASCIIEncoding encoder = new ASCIIEncoding();
            Console.WriteLine(encoder.GetString(message, 0, bytesRead));

        }

        tcpClient.Close();
    }

}
我只是在main函数中这样调用它:

Server server = new Server();
在一个单独的客户端程序中,我有这个类

class TheClient
{
  public void ConnectV2()
    {


        TcpClient client = new TcpClient();

        IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);

        client.Connect(serverEndPoint);

        NetworkStream clientStream = client.GetStream();

        ASCIIEncoding encoder = new ASCIIEncoding();

        for (int i = 0; i < 20; i++)
        {

            byte[] buffer = encoder.GetBytes("Hello Server! " + i.ToString() + " ");

            Console.WriteLine("Processing..");

            clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();
            Console.WriteLine("Hello Server sent");
        }


    }

}
我的问题是服务器程序似乎比客户端慢,在客户端发出13或更多消息之前,他不会做出反应:

[由于声誉问题,我无法发布图片]

它一次读取前十几条消息,然后逐个读取其他消息

如果我让服务器先发出消息,客户端会收到消息,但它们都会停止,就像两个都在等待另一个发送消息一样


有人能给我解释一下这种行为吗?我如何控制和同步它?

这是因为您的客户端AP始终在发送数据,但您的服务器AP无法立即接收这些数据。所以,这些数据堆叠在缓冲区中,然后服务器AP一次接收所有数据

您可以尝试:

  • 发送或接收数据时设置固定长度

  • 接收和分割数据


  • TCP不是基于消息的。它提供一个字节流。您有责任将信息分开。还要注意的是,在一次
    Read
    呼叫中,您可能只收到消息的一部分

    这里有一个简单的方法:将消息作为单独的行发送。可能使用
    StreamWriter
    。使用
    StreamReader.ReadLine()
    接收消息

    这样,您还可以使用更合理的编码,例如
    encoding.UTF8


    除此之外,您的代码实际上是良好的和可行的。在堆栈溢出上几乎看不到工作的TCP代码。大多数代码都被严重破坏了。祝贺您。

    值得一提的是,“每个连接的客户端1个线程”的扩展性不太好。我不能接受它的优点,我是从网上的一个教程中获得的,我只是玩了一点来理解它。这一定是web上第一个展示漂亮套接字代码的教程。你有链接吗?我刚试过,它像沙姆一样工作。您犯了一个小错误,它是
    StreamReader.ReadLine()
    而不是
    StreamWriter.ReadLine()
    。谢谢
    TheClient tc = new TheClient();
    
    tc.ConnectV2();