Я видел много ресурсов здесь, на SO о Sockets. Я считаю, что ни один из них не охватывал детали, которые я хотел знать. В моем приложении сервер выполняет всю обработку и отправляет периодические обновления клиентам.
Намерение этой публикации состоит в том, чтобы охватить все основные идеи, необходимые при разработке приложения сокета и обсудить лучшие практики. Вот основные вещи, которые вы увидите почти со всеми приложениями на основе сокетов.
1 - Связывание и прослушивание сокета
Я использую следующий код. Он хорошо работает на моей машине. Нужно ли мне позаботиться о чем-то еще, когда я развертываю это на реальном сервере?
IPHostEntry localHost = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint endPoint = new IPEndPoint(localHost.AddressList[0], 4444);
serverSocket = new Socket(endPoint.AddressFamily, SocketType.Stream,
ProtocolType.Tcp);
serverSocket.Bind(endPoint);
serverSocket.Listen(10);
2 - Получение данных
Я использовал массив байтов размером 255. Поэтому, когда я получаю данные размером более 255 байт, мне нужно вызвать метод получения, пока я не получу полные данные, не так ли? Как только я получу полные данные, мне нужно добавить все полученные байты, чтобы получить полное сообщение. Это верно? Или есть лучший подход?
3 - Отправка данных и указание длины данных
Поскольку в TCP нет способа найти длину получаемого сообщения, я планирую добавить длину сообщения. Это будет первый байт пакета. Поэтому клиентские системы знают, сколько данных доступно для чтения.
Любой другой лучший подход?
4 - Закрытие клиента
Когда клиент закрыт, он отправит сообщение серверу с указанием закрытия. Сервер удалит данные клиента из его списка клиентов. Ниже приведен код, используемый на стороне клиента для разъединения сокета (часть сообщений не показана).
client.Shutdown(SocketShutdown.Both);
client.Close();
Любые предложения или проблемы?
5 - Закрытие сервера
Сервер отправляет сообщение всем клиентам, указывающим на выключение. Каждый клиент будет отключать сокет, когда он получит это сообщение. Клиенты отправят закрытое сообщение на сервер и закроют. Когда сервер получает сообщение от всех клиентов, он отключает сокет и прекращает прослушивание. Вызовите Dispose на каждом клиентском сокете, чтобы освободить ресурсы. Это правильный подход?
6 - Неизвестные отключения клиентов
Иногда клиент может отключиться, не сообщая серверу. Мой план заключается в следующем: когда сервер отправляет сообщения всем клиентам, проверьте состояние сокета. Если он не подключен, удалите этого клиента из списка клиентов и закройте сокет для этого клиента.
Любая помощь будет замечательной!