#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:
Существует два типа сокетов:
-
Прослушивающие сокеты. Их назначение — только принимать входящие соединения. Они не могут отправлять или получать. Для этого вы используете
Accept
илиBeginAccept
/EndAccept
. -
Обычные сокеты. Соединение устанавливается либо путем
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
Я не понимаю это утверждение.