C # TCP-сервер-клиент: не может получать данные от клиента в бесконечном цикле

1

Столкнувшись со следующей проблемой. Читает данные из текстового файла. Каждые 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 вы можете найти в коде

  • 2
    Первая проблема - вы игнорируете возвращаемое значение stream.Read(buffer, 0, buffer.Length);
  • 0
    Я думаю, что вам нужно добавить еще Debug.WriteLine операторов Debug.WriteLine чтобы у вас было больше информации о том, что происходит.
Показать ещё 1 комментарий
Теги:
wpf
server
client
tcp

1 ответ

0
Лучший ответ

Вы поставили петлю в неправильном месте!

Ваш клиент подключается ровно один раз; что правильно. Однако в вашей функции GetData вы принимаете новое соединение. Таким образом, после первого чтения цикл снова вызывает GetData, который блокируется при ожидании нового соединения, и ничего не происходит.

Вместо этого вы хотите выполнить цикл вызова Accept в самом классе сервера, и когда вы получите соединение, запустите для него поток "Read" (поднимите событие, когда вы получите данные). В вашем основном приложении не должно быть циклов для обработки операций сервера.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню