Использование сокетов для отправки и получения данных по протоколу 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
.
IPHostEntry ipHostInfo = await Dns.GetHostEntryAsync("host.contoso.com");
IPAddress ipAddress = ipHostInfo.AddressList[0];
Совет
Для ручного тестирования и отладки обычно можно использовать GetHostEntryAsync метод , чтобы получить заданное Dns.GetHostName() значение для разрешения имени localhost в IP-адрес.
Центр интернет-номеров (IANA) определяет номера портов для общих служб. Дополнительные сведения см. в разделе IANA: реестр имен служб и номеров портов транспортных протоколов). Другие службы могут использовать номера портов в диапазоне от 1024 до 65535. Следующий код объединяет IP-адрес для host.contoso.com
с номером порта, чтобы создать удаленную конечную точку для подключения.
IPEndPoint ipEndPoint = new(ipAddress, 11_000);
После определения адреса удаленного устройства и выбора порта для подключения приложение может установить подключение к удаленному устройству.
Создание Socket
клиента
Создав endPoint
объект , создайте сокет клиента для подключения к серверу. После подключения сокета он может отправлять и получать данные из подключения к сокету сервера.
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 = new byte[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
Когда является подтверждением, он записывается в консоль, и цикл завершается.
Наконец,
client
сокет вызывает Socket.Shutdown заданный SocketShutdown.Both, который завершает операции отправки и получения.
Создание Socket
сервера
Чтобы создать сокет сервера, объект может прослушивать входящие подключения по любому IP-адресу, endPoint
но необходимо указать номер порта. После создания сокета сервер может принимать входящие подключения и взаимодействовать с клиентами.
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 = new byte[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.Вызывает
listener
Socket.Bind метод с экземпляром вendPoint
качестве аргумента для связывания сокета с сетевым адресом.Метод Socket.Listen() вызывается для прослушивания входящих подключений.
Вызывает
listener
метод для Socket.AcceptAsync принятия входящего подключения к сокетуhandler
.В цикле
while
:- Вызовы Socket.ReceiveAsync для получения данных от клиента.
- При получении данных они декодируются и записываются в консоль.
response
Если сообщение заканчивается на<|EOM|>
, подтверждение отправляется клиенту с помощью Socket.SendAsync.
Запуск примера клиента и сервера
Сначала запустите серверное приложение, а затем запустите клиентское приложение.
dotnet run --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...
Клиентское приложение отправит сообщение серверу, а сервер ответит подтверждением.
dotnet run --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...
См. также раздел
.NET feedback
The .NET documentation is open source. Provide feedback here.
Обратная связь
Отправить и просмотреть отзыв по