Использование сокетов для отправки и получения данных через TCP
Статья
Перед использованием сокета для связи с удаленными устройствами необходимо инициализировать сокет, указав протокол и сведения о сетевом адресе. Конструктор класса Socket имеет параметры, которые определяют семейство адресов, тип сокета и тип протокола, которые сокет использует для подключения. При подключении сокета клиента к сокету сервера клиент будет использовать IPEndPoint объект для указания сетевого адреса сервера.
Создание конечной точки IP
При работе System.Net.Socketsс объектом представляется сетевая конечная точка IPEndPoint . Создается IPEndPoint с соответствующим номером IPAddress порта. Прежде чем начать беседу с помощью Socket, создайте канал данных между приложением и удаленным назначением.
В качестве уникального идентификатора службы протокол TCP/IP использует сетевой адрес и номер порта службы. Сетевой адрес определяет определенное назначение сети; Номер порта определяет определенную службу на этом устройстве для подключения. Сочетание сетевого адреса и порта службы называется конечной точкой, которая представлена в .NET классом EndPoint . Потомок EndPoint определяется для каждого поддерживаемого семейства адресов; для семейства IP-адресов класс имеет значение IPEndPoint.
Класс Dns предоставляет службы доменных имен приложениям, используюющим интернет-службы TCP/IP. Метод GetHostEntryAsync запрашивает DNS-сервер для сопоставления понятного доменного имени (например, "host.contoso.com") с числовым интернет-адресом (например 192.168.1.1, ). GetHostEntryAsync возвращает значение Task<IPHostEntry> , которое, когда ожидается, содержит список адресов и псевдонимов для запрошенного имени. В большинстве случаев можно использовать первый адрес из возвращенного массива AddressList. Следующий код получает IPAddress IP-адрес сервера host.contoso.com.
Для ручного тестирования и отладки метод обычно можно использовать GetHostEntryAsync с результирующий имя узла из Dns.GetHostName() значения для разрешения имени localhost на IP-адрес. Рассмотрим следующий фрагмент кода:
C#
var hostName = Dns.GetHostName();
IPHostEntry localhost = await Dns.GetHostEntryAsync(hostName);
// This is the IP address of the local machine
IPAddress localIpAddress = localhost.AddressList[0];
Центр назначения номеров Интернета (IANA) определяет номера портов для общих служб. Дополнительные сведения см. в разделе IANA: Имя службы и реестр номеров портов транспорта). Другие службы могут использовать номера портов в диапазоне от 1024 до 65535. Следующий код объединяет IP-адрес host.contoso.com с номером порта, чтобы создать удаленную конечную точку для подключения.
C#
IPEndPoint ipEndPoint = new(ipAddress, 11_000);
После определения адреса удаленного устройства и выбора порта, используемого для подключения, приложение может установить подключение к удаленному устройству.
Socket Создание клиента
endPoint Создав объект, создайте сокет клиента для подключения к серверу. После подключения сокета он может отправлять и получать данные из подключения сокета сервера.
C#
using Socket client = new(
ipEndPoint.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp);
await client.ConnectAsync(ipEndPoint);
while (true)
{
// Send message.var message = "Hi friends 👋!<|EOM|>";
var messageBytes = Encoding.UTF8.GetBytes(message);
_ = await client.SendAsync(messageBytes, SocketFlags.None);
Console.WriteLine($"Socket client sent message: \"{message}\"");
// Receive ack.var buffer = newbyte[1_024];
var received = await client.ReceiveAsync(buffer, SocketFlags.None);
var response = Encoding.UTF8.GetString(buffer, 0, received);
if (response == "<|ACK|>")
{
Console.WriteLine(
$"Socket client received acknowledgment: \"{response}\"");
break;
}
// Sample output:// Socket client sent message: "Hi friends 👋!<|EOM|>"// Socket client received acknowledgment: "<|ACK|>"
}
client.Shutdown(SocketShutdown.Both);
В приведенном выше коде C#:
Создает экземпляр нового Socket объекта с заданным endPoint семейством адресов экземпляров, SocketType.Streamа также ProtocolType.Tcp.
Socket.ConnectAsync Вызывает метод с endPoint экземпляром в качестве аргумента.
В цикле while :
Кодирует и отправляет сообщение серверу с помощью Socket.SendAsync.
Записывает отправленное сообщение в консоль.
Инициализирует буфер для получения данных с сервера с помощью Socket.ReceiveAsync.
response Когда подтверждение является подтверждением, он записывается в консоль и цикл завершается.
Наконец, вызовы Socket.Shutdown сокета, заданные clientSocketShutdown.Both, что завершает работу как операций отправки, так и получения.
Socket Создание сервера
Чтобы создать сокет сервера, endPoint объект может прослушивать входящие подключения по любому IP-адресу, но необходимо указать номер порта. После создания сокета сервер может принимать входящие подключения и взаимодействовать с клиентами.
C#
using Socket listener = new(
ipEndPoint.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp);
listener.Bind(ipEndPoint);
listener.Listen(100);
var handler = await listener.AcceptAsync();
while (true)
{
// Receive message.var buffer = newbyte[1_024];
var received = await handler.ReceiveAsync(buffer, SocketFlags.None);
var response = Encoding.UTF8.GetString(buffer, 0, received);
var eom = "<|EOM|>";
if (response.IndexOf(eom) > -1/* is end of message */)
{
Console.WriteLine(
$"Socket server received message: \"{response.Replace(eom, "")}\"");
var ackMessage = "<|ACK|>";
var echoBytes = Encoding.UTF8.GetBytes(ackMessage);
await handler.SendAsync(echoBytes, 0);
Console.WriteLine(
$"Socket server sent acknowledgment: \"{ackMessage}\"");
break;
}
// Sample output:// Socket server received message: "Hi friends 👋!"// Socket server sent acknowledgment: "<|ACK|>"
}
В приведенном выше коде C#:
Создает экземпляр нового Socket объекта с заданным endPoint семейством адресов экземпляров, SocketType.Streamа также ProtocolType.Tcp.
Socket.Bind Вызывает listener метод с endPoint экземпляром в качестве аргумента для связывания сокета с сетевым адресом.
Метод Socket.Listen() вызывается для прослушивания входящих подключений.
Вызывает listener метод для принятия входящего подключения в сокетеhandler.Socket.AcceptAsync
После получения данных он декодируется и записывается в консоль.
response Если сообщение заканчивается<|EOM|>, подтверждение отправляется клиенту с помощью Socket.SendAsync.
Запуск примера клиента и сервера
Сначала запустите серверное приложение и запустите клиентское приложение.
Интерфейс командной строки.NET
dotnetrun --project socket-server
Socket server starting...
Found: 172.23.64.1 available on port 9000.
Socket server received message: "Hi friends 👋!"
Socket server sent acknowledgment: "<|ACK|>"
Press ENTER to continue...
Клиентское приложение отправит на сервер сообщение, и сервер будет отвечать на подтверждение.
Интерфейс командной строки.NET
dotnetrun --project socket-client
Socket client starting...
Found: 172.23.64.1 available on port 9000.
Socket client sent message: "Hi friends 👋!<|EOM|>"
Socket client received acknowledgment: "<|ACK|>"
Press ENTER to continue...
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Присоединитесь к серии встреч для создания масштабируемых решений искусственного интеллекта на основе реальных вариантов использования с другими разработчиками и экспертами.
В этом модуле вы узнаете о брокере сообщений RabbitMQ и о том, как использовать его для развязки микрослужб, обеспечивая надежное взаимодействие. Вы также увидите, как .NET Aspire упрощает интеграцию с RabbitMQ.