【问题标题】:Synchronization in C# networkingC# 网络中的同步
【发布时间】:2015-06-15 14:58:06
【问题描述】:

我有这个简单的 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();
    }

}

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

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");
        }


    }

}

我在主函数中这样调用它

TheClient tc = new TheClient();

tc.ConnectV2();

我的问题是服务器程序似乎比客户端慢,他在来自客户端的第 13 条或更多消息之前没有反应:

[因为声誉问题,我无法发布图片]

它一口气读取前十条消息,然后一个接一个地读取其他消息。

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

有人可以解释一下这种行为吗?如何控制和同步?

【问题讨论】:

  • 可能值得知道“每个连接的客户端 1 个线程”并不能很好地扩展。

标签: c# tcp tcpclient tcpserver


【解决方案1】:

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

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

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

此外,您的代码实际上很好且可行。在 Stack Overflow 上看到几乎可以工作的 TCP 代码是极其罕见的。大多数代码都被严重破坏了。恭喜。

【讨论】:

  • 看不下去了,我是从网上的教程里拿来的,随便玩了一下就明白了
  • 这一定是网络上第一个展示漂亮套接字代码的教程。有链接吗?
  • 我刚试了一下,效果很好。你犯了一个小错误,它是 StreamReader.ReadLine() 而不是 StreamWriter.ReadLine() 。谢谢
【解决方案2】:

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

你可以试试:

  1. 在发送或接收数据时设置固定长度。

  2. 接收和拆分数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2020-10-04
    • 1970-01-01
    相关资源
    最近更新 更多