.NET TCP сокет с сессией - PullRequest
2 голосов
/ 16 марта 2010

Есть ли способ работы с сессиями с сокетами в C #?

Пример моей проблемы:
У меня есть сервер с прослушиванием сокета через порт 5672.

TcpListener socket = new TcpListener(localAddr, 5672);  
socket.Start();  
Console.Write("Waiting for a connection... ");  

// Perform a blocking call to accept requests.  
TcpClient client = socket.AcceptTcpClient();  
Console.WriteLine("Connected to client!");

И у меня есть два клиента, которые отправят один байт. Клиент A отправляет 0x1, а клиент B отправляет 0x2. Со стороны сервера я читаю эти данные так:

Byte[] bytes = new Byte[256];
String data = null;

NetworkStream stream = client.GetStream();
while ((stream.Read(bytes, 0, bytes.Length)) != 0)
{
     byte[] answer = new ...
     stream.Write(answer , 0, answer.Length);
}  

Затем клиент A отправляет 0x11. Мне нужен способ узнать, что этот клиент тот же, что отправил "0x1" раньше.

Ответы [ 4 ]

4 голосов
/ 16 марта 2010

Каждый экземпляр TcpClient предназначен для другого соединения. Соединение в TCP состоит из четырех вещей: исходный IP, исходный порт, целевой IP, целевой порт. Таким образом, даже если у вас один и тот же целевой IP-адрес и порт и один и тот же порт источника, у вас два разных подключения.

Данные, отправленные одним клиентом, не будут смешаны с данными, отправленными другим клиентом. Данные, отправленные клиентом по соединению, будут получены в порядке по этому соединению.

Единственный раз, когда сеансы становятся проблемой, это помнить клиента после закрытия соединения.

1 голос
/ 16 марта 2010

Существует много литературы о том, как сеансы реализованы в мире Web (HTTP).

Одним из ключей является то, закрываете ли вы клиентские соединения или они постоянны? Если они постоянны, просто идентифицируйте их по ссылке на объект. Если нет, то ...

1) Вы можете выполнять простые сеансы на основе исходного IP-адреса. Но если несколько клиентов находятся за брандмауэром NAT с общим IP-адресом, это не сработает, см. Следующий вариант.

2) Использовать «cookie»

3) Использовать аутентификацию для идентификации каждого клиента

Каждая опция, кроме сеансов на основе IP, требует добавления чего-либо в сам протокол.

Некоторые вещи, которые нужно помнить с помощью сокетов. Удаленный IP + удаленный порт однозначно идентифицирует клиентский TCP-сокет. Несколько подключений от одного и того же удаленного клиента будут иметь разные удаленные порты. Но вы не можете полагаться на это, если сокет закрывается, потому что удаленная ОС может перезапустить удаленный порт для нового соединения после истечения срока действия старого.

0 голосов
/ 16 марта 2010

Вам понадобится какой-то тип аутентификации или токен с предварительным согласованием, и все это будет каким-то образом зашифровано солью.

0 голосов
/ 16 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...