Прослушайте ответы от 2 экземпляров TcpClient для одного и того же IP, но разных портов - PullRequest
0 голосов
/ 03 апреля 2020

Я работаю над TCP-соединением, где мой клиент подключается к IP-адресу сервера через 2 разных порта. Итак, у меня есть 2 экземпляра объектов TcpClient, один из которых подключается к IP-адресу через порт 9000, а другой - через порт 9001.

Цель двух подключений состоит в том, чтобы сервер использовал активное соединение на порт 9000 *. 1004 *, чтобы часто давать определенные ответы клиенту, и клиент использует эти ответы для формирования и отправки запроса на порт 9001 .

Теперь, когда я впервые подключаюсь к 9000, я Получив ответ, я формирую запрос и запускаю через 9001. Теперь у меня возникает ощущение, что я делаю что-то не так с тем, как я управляю асинхронными запросами к обоим портам, но я не могу найти альтернативный способ сделать this:

    IPAddress IPAddress = IPAddress.Parse("192.168.1.10");

    public static async Task ConnectToPort9000()
    {
        TcpClient TcpClient1 = new TcpClient();
        try
        {
            await TcpClient1.ConnectAsync(IPAddress, 9000);
            if (TcpClient1.Connected)
            {
                byte[] Buffer = new byte[1024];
                while (await TcpClient1.GetStream().ReadAsync(Buffer, 0, Buffer.Length) > 0)
                {
                    //Server returns a message on this port
                    string Port9000Response = Encoding.UTF8.GetString(Buffer, 0, Buffer.Length);

                    //Setting ConfigureAwait(false) so that any further responses returned
                    //on this port can be dealt with
                    await Task.Run(async () =>
                    {
                        await SendRequestToPort9001BasedOnResponseAsync(Port9000Response);
                    }).ConfigureAwait(false);
                }
            }
        }
        catch (Exception)
        {
            throw;
        }
    }

    private async Task SendRequestToPort9001BasedOnResponseAsync(string Port9000Response)
    {
        //Open connection on port 9001 and send request
        TcpClient TcpClient2 = new TcpClient();
        await TcpClient2.ConnectAsync(IPAddress, 9001);

        if (TcpClient2.Connected)
        {
            //Handle each string response differently
            if (Port9000Response == "X")
            {
                //Form a new request message to send on port 9001
                string _NewRequestMesssage = "Y";
                byte[] RequestData = Encoding.UTF8.GetBytes(_NewRequestMesssage);
                new SocketAsyncEventArgs().SetBuffer(RequestData, 0, RequestData.Length);
                await TcpClient2.GetStream().WriteAsync(RequestData, 0, RequestData.Length);
                await TcpClient2.GetStream().FlushAsync();
                //Handle any responses on this port

                //At this point, based on the request message sent on this port 9001
                //server sends another response on **port 9000** that needs separately dealing with
                //so the while condition in the previous method should receive a response and continue handling that response again
            }
            else if (Port9000Response == "A")
            {
                //Do something else
            }
        }
    }

Проблема, с которой я столкнулся на данный момент, заключается в том, что после отправки запроса на порт 9001 при обработке любых ответных сообщений на порт 9001 сервер уже отправил мне ответ на порт 9000. , но мое время l oop в первом методе не срабатывает, и кажется, что это потому, что он все еще выполняет второй метод для обработки request / res ponse для порта 9001. Я попытался использовать ConfigureAwait (false), чтобы в основном запустить и забыть , но, похоже, он не работает. Я неправильно обрабатываю асинхронные процессы? Или я должен посмотреть на альтернативы, такие как действие / делегаты?

1 Ответ

0 голосов
/ 03 апреля 2020

Цель двух соединений состоит в том, что сервер использует активное соединение через порт 9000, чтобы часто давать определенные ответы клиенту, и клиент использует эти ответы для формирования и отправки запроса через порт 9001.

Пожалуйста, не делайте этого. Программирование с помощью сокетов достаточно сложно, не делая его чрезвычайно сложным с несколькими подключениями. Обработка ошибок усложняется, обнаружение полуоткрытых соединений становится труднее (или невозможным), и затрудняется устранение взаимных блокировок связи.

Каждое сокетное соединение уже является двунаправленным; у него уже есть два независимых потока. Единственное, что вам нужно сделать, это всегда читать и отправлять по мере необходимости. Потоки чтения и записи независимы, поэтому сохраняйте независимость чтения и записи.

...