TCPClient Threading - PullRequest
       5

TCPClient Threading

0 голосов
/ 24 мая 2018

Я занимаюсь разработкой игрового сервера.Через TCPListener я принимаю клиентов.

var Listener = new TcpListener(IPAddress.Any, CommonConfig.Settings.GamePort);
Listener.Start();
ListenerStarted = true;
while (ListenerStarted)
{
    TcpClient tcpClient = await Listener.AcceptTcpClientAsync();
    ProcessClientTearOff(tcpClient);
}

Затем через ReadAsync получает данные от клиента.

byte[] Buffer = new byte[8192];
int i = await Stream.ReadAsync(Buffer, 0, 8192);

После этого данные обрабатываются с использованием метода

RequestHandling(byte[] data)

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

Один поток для приема клиентов и получения данных, один поток для обработки и выполнения, один поток для отправки данных клиентам.Но я не могу понять, как это можно реализовать.Через Task вы можете указать порядок, в котором выполняются методы, но только перед запуском задач.Можно ли выполнить всю обработку пакетов в отдельном потоке, чтобы все действия выполнялись синхронно в порядке очереди?Или есть альтернатива этому?

1 Ответ

0 голосов
/ 25 мая 2018

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

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

Хороший пример для вашего случая выглядит следующим образом.Сделайте так, чтобы каждый поток / задача соединения выполняла этот цикл:

while (true) {
 var message = await ReceiveMessageFromNetwork();
 lock (globalLock) {
  ApplyMessage(message); //no IO here
 }
}

Очередь неявна в блокировке.Я пометил некоторый код как «no IO», потому что вы должны быстро выйти из блокировки, чтобы другие потоки / задачи могли войти.

...