Двухсторонняя связь с localhost C # - PullRequest
1 голос
/ 23 сентября 2019

У меня есть служба, работающая в фоновом режиме как localhost.Мне нужно подключиться к этому сервису и начать получать / отправлять сообщения.

Я могу разделить всю задачу на 3 подзадачи:

  1. Установить связь
  2. Назначить поток(T1), который отвечает за получение сообщений от локального хоста
  3. Назначить поток (T2), который отвечает за отправку сообщений на локальный хост

ПРОБЛЕМА: Нужен ли отдельный поток для мониторинга соединения? ИЛИ Могу ли я позвонить CreateClientConnectionSettings() с T1 и T2 в случае потери соединения (например, в случае сбоя службы)

IPHostEntry ipHost;
IPAddress ipAddr;
IPEndPoint localEndPoint;
Socket clientSocket;

private void CreateClientConnectionSettings()
{
    // Establish the remote endpoint for the socket. 
    //This example  uses port 11111 on the local computer. 
    ipHost = Dns.GetHostEntry(Dns.GetHostName());
    ipAddr = ipHost.AddressList[0];
    localEndPoint = new IPEndPoint(ipAddr, 11111);

    // Creation TCP/IP Socket using Socket Class Costructor 
    clientSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    try
    {
        // Connect Socket to the remote endpoint using method Connect() 
        clientSocket.Connect(localEndPoint);
        UpdateConnectionStatusLabel( "Connected");
        //connectionStatusLabel.ForeColor = Color.Green;
        isConnected = true;
    }
    // Manage of Socket's Exceptions 
    catch (ArgumentNullException ane)
    {

        UpdateConnectionStatusLabel("ArgumentNullException" + ane.ToString());
    }

    catch (SocketException se)
    {

        UpdateConnectionStatusLabel("SocketException " + se.ToString());
    }

    catch (Exception e)
    {
        UpdateConnectionStatusLabel("Unexpected exception : " + e.ToString());
    }
}

PS: Есть ли какие-либо встроенные классы для этой функции в C #?

1 Ответ

0 голосов
/ 23 сентября 2019

Исходя из моего ограниченного опыта, доступ к одному и тому же сокету из разных потоков является очень опасной идеей, но, предполагая, что то, что вы делаете, является клиентским приложением с графическим интерфейсом, я бы предложил создать поток, который устанавливает соединение, создает событиякогда что-то приходит из сокета и отправляет данные из очереди.

для кодирования состояния соединения, вы можете создать свой собственный enum (вне класса, но в том же пространстве имен, даже в том же файле) для соответствующего соединениятакие состояния, как CONNECTED и DISCONNECTED:

public enum ConnStatus { CONNECTED, DISCONNECTED, FAULTED };

Затем вы можете создать класс, который управляет всеми сокетами, потоками, чтением / записью ... Поток вызовет некоторые события, такие как "messageReceived" и "statusChanged",они должны быть объявлены как поля класса:

public delegate void StringEventHandler(string param);
public StringEventHandler messageReceived;
public delegate void ConnStatusEventHandler(ConnStatus param);
public ConnStatusEventHandler statusChanged;

тогда в потоке вы можете запустить их следующим образом:

try {

    clientSocket.Connect(localEndPoint);
    statusChanged?.Invoke(ConnStatus.CONNECTED);

    while(runThread){
        // Send messages in queue

        string RX = String.Empty;
        //READ from Socket
        //perform some basic checks if needed
        messageReceived?.Invoke(RX);
    }

    statusChanged?.Invoke(ConnStatus.DISCONNECTED);

catch {
    statusChanged?.Invoke(ConnStatus.FAULTED);
}
finally {
    //perform some cleanup
}
...