C# TCP 服务器-客户端:无法在无限循环中从客户端接收数据

本文关键字:客户端 客户 端接 数据 无限循环 服务器 TCP | 更新日期: 2023-09-27 18:28:59

面临以下问题。从文本文件中读取数据。每隔 40 毫秒,数据就会发送到服务器。服务器必须将数据读入单独流中的无限循环。但这并没有发生。怎么了?

客户:

class Client
{ 
    private TcpClient _client;
    private Stream _stream;
    private Boolean _isConnected;
    private double[] _values;

    public Client(String ipAddress, int portNum)
    {
        _client = new TcpClient();
        _client.Connect(ipAddress, portNum);
    }

    public void SendValues(double[] values)
    {
        _values = values;
        HandleCommunication();
    }

    public void HandleCommunication()
    {
        _isConnected = true;
        _stream = _client.GetStream();
        var dataBytes = new List<byte>();
        foreach (double value in _values)
        {
            dataBytes.AddRange(BitConverter.GetBytes(value));
        }
        _client.SendBufferSize = _values.Length * sizeof(double);
        _stream.Write(dataBytes.ToArray(), 0, _client.SendBufferSize);
        Console.Write("Sending...");
        _stream.Flush();
    }

发送数据:

 public partial class MainWindow : Window
{
    private double[] values;
    private System.Timers.Timer timer = new System.Timers.Timer(40);
    Client _client = new Client("127.0.0.1", 55443);

    public MainWindow()
    {
        InitializeComponent();
        OpenSrcFile();
        timer.Elapsed += TimerOnElapsed;
        timer.Enabled = true;
    }

    private void TimerOnElapsed(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("is sending...");
        _client.SendValues(values);
    }

    public void OpenSrcFile()
    {
        List<string> lines = File.ReadAllLines(@"file.txt").ToList();
        string r = lines[0];
        int sizeX = int.Parse(lines[1]);
        lines.RemoveRange(0, 2);
        values = GetValues(lines.ToArray());
    }

    private double[] GetValues(string[] lines)
    {
        return lines.Select(line => double.Parse(line.Replace(" ", ""), CultureInfo.InvariantCulture)).ToArray();
    }

服务器:

class Server
{
    private TcpListener _server;
    private Boolean _isRunning;
    public Server(int port)
    {
        _server = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
        _server.Start();
        _isRunning = true;
    }
    public double[] GetData()
    {
            // wait for client connection
            TcpClient client = _server.AcceptTcpClient();
            Console.WriteLine("Connected!");
            var stream = client.GetStream();
            byte[] buffer = new byte[256*sizeof (double)];

            stream.Read(buffer, 0, buffer.Length);
            double[] newValues = new double[buffer.Length/sizeof (double)];

            for (int i = 0; i < newValues.Length; i++)
            {
                newValues[i] = BitConverter.ToDouble(buffer, i*sizeof (double));
            }
            stream.Flush();
            return newValues;

    }

}

接收数据,但由于某种原因不起作用

public partial class MainWindow : Window
{
    private Thread _thread;
    private double[] _values;
    private Server _server = new Server(55443);
    public MainWindow()
    {
        InitializeComponent();
        InitializeThread();
    }

    private void InitializeThread()
    {
        _thread = new Thread(GetData);
        _thread.IsBackground = true;
        _thread.Start();
    }

    private void GetData()
    {
        while (true)
        {
            _values = _server.GetData();
            Console.WriteLine("...");
        }
    }
}

好的,客户端发送一个字节数组,这部分工作正常。然后我们需要将这个字节数组放入一个单独的线程中的无限循环中。就像在这个地方:

private void InitializeThread()
{
    _thread = new Thread(GetData);
    _thread.IsBackground = true;
    _thread.Start();
}

private void GetData()
{
    while (true)
    {
        _values = _server.GetData();
        Console.WriteLine("...");
    }
}

但不知何故,服务器接收到一次字节数组,接下来什么也没发生。函数 GetData 您可以在代码中找到

C# TCP 服务器-客户端:无法在无限循环中从客户端接收数据

你把循环放在了错误的位置!

你的客户端只连接一次;这是正确的。但是,在GetData函数中,您接受新连接。因此,在第一次读取后,循环再次调用GetData,这会在等待连接时阻塞,并且没有任何反应。

相反,您希望在服务器类本身中循环Accept调用,并在获得连接时为其启动"Read"线程(在获取数据时引发事件(。主应用程序中不应有用于处理服务器操作的循环。