Лучший способ открыть сокет, разрешить множественный одновременный доступ и закрыть, когда больше не будет ожидающих запросов в C#

#c# #sockets #concurrency

#c# #сокеты #параллелизм

Вопрос:

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

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

 public static class SymConnection
{
    private static TcpClient symSocket;
    private static NetworkStream stream;

    private static int _portNumber;
    private static string _hostName;
    private static int commandNumber;
    private static object myLock = "keepThoseSymCmdsInOrder";

    public static string executeCommand(string command)
    {
        incrementCommandCounter();

        lock (myLock)
        {
            Console.WriteLine("ExecCommand {0}", commandNumber);
            if (symSocket == null)
            {
                symSocket = new TcpClient(_hostName, _portNumber);
                symSocket.SendTimeout = 5000;
                symSocket.ReceiveTimeout = 5000;
                stream = symSocket.GetStream();
            }

            string s = sendCommand(command);


            commandNumber--;
            if (commandNumber == 0)
            {
                stream.Close();
                symSocket.Close();
                symSocket = null;
            }

            Console.WriteLine("ExecCmdEnd {0}", commandNumber);
            return s;
        }
    }

    public static void setConnectionParams(string hostName, int portNumber)
    {
        _hostName = hostName;
        _portNumber = portNumber;
    }

    static void incrementCommandCounter()
    {
        object myObj = "Lock Object";

        lock (myObj)
        {
            commandNumber  ;
        }

    }

    static string sendCommand(string command)
    {
        if (!symSocket.Connected) return null;

        StringBuilder sb = new StringBuilder();
        command = command   "n";
        Byte[] data = System.Text.ASCIIEncoding.ASCII.GetBytes(command.Replace("xFF", "xFFxFF"));
        stream.Write(data, 0, data.Length);

        do
        {
            int input = stream.ReadByte();
            sb.Append((char)input);
        } while (symSocket.Available > 0);

        return sb.ToString();
    }
}
  

Ответ №1:

Существует два типа сокетов:

  1. Прослушивающие сокеты. Их назначение — только принимать входящие соединения. Они не могут отправлять или получать. Для этого вы используете Accept или BeginAccept / EndAccept .

  2. Обычные сокеты. Соединение устанавливается либо путем Connect() ввода, либо путем принятия сокетов-слушателей.

Сокет TCP никогда не может быть общим для нескольких конечных точек. Каждое соединение уникально между локальным сокетом и удаленным сокетом.

Следовательно, ваш вопрос немного странный, и я действительно не знаю, в чем проблема. Вы являетесь сервером (принимаете соединения) или клиентом (подключаетесь к серверу)?

Комментарии:

1. Это для веб-приложения, которое действует как клиент для сервера, к которому можно подключиться только к одному порту. Не существует нескольких конечных точек, поскольку все команды поступают из веб-приложения. Здесь вы можете видеть, что способ определения того, когда закрывать соединение, совсем ненадежен.

2. Порт сервера может использоваться произвольным числом клиентов, а не только одним. Единственное, что может помешать серверу принимать больше клиентов, — это то, что он больше не вызывает Accept сокет. You can see here that the way it is determined when to close the connection is not reliable at all Я не понимаю это утверждение.