Клиент сервер си шарп

Использование сокетов для отправки и получения данных по протоколу 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 , который при ожидании содержит список адресов и псевдонимов для запрошенного имени. В большинстве случаев можно использовать первый адрес из возвращенного массива AddressList. Следующий код получает объект , IPAddress содержащий IP-адрес сервера host.contoso.com .

IPHostEntry ipHostInfo = await Dns.GetHostEntryAsync("host.contoso.com"); IPAddress ipAddress = ipHostInfo.AddressList[0]; 

Для ручного тестирования и отладки обычно можно использовать GetHostEntryAsync метод , чтобы получить заданное Dns.GetHostName() значение для разрешения имени localhost в IP-адрес.

Читайте также:  Php server api example

Центр интернет-номеров (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: \"\""); // 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: \"\""); 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 сервера

    Чтобы создать сокет сервера, объект может прослушивать входящие подключения по любому 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: \"\""); var ackMessage = "<|ACK|>"; var echoBytes = Encoding.UTF8.GetBytes(ackMessage); await handler.SendAsync(echoBytes, 0); Console.WriteLine( $"Socket server sent acknowledgment: \"\""); 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. 

      Источник

      Клиент сервер си шарп

      Класс Socket применяется не только для создания tcp-клиента, но для определения tcp-сервера. Общая схема работы серверного сокета TCP будет следующей:

      Сервер на сокетах TCP в C# и .NET

      Привязка к конечной точке. Метод Bind

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

      public void Bind (EndPoint localEP);

      Если не имеет значения, на каком именно локальном адресе сервер будет запущен, то можно в качестве адреса использовать значение IPAddress.Any . Тогда серверу будет назначен наиболее подходящий сетевой адрес (при наличии нескольких сетевых интерфейсов). Кроме того, если номер порта не имеет значения, то в качестве порта можно указать число 0. Тогда серверу будет предоставлен один из доступных портов. При использовании такого подхода точный адрес и порт затем можно будет получить через свойство LocalEndpoint .

      using System.Net; using System.Net.Sockets; IPEndPoint ipPoint = new IPEndPoint(IPAddress.Any, 8888); using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(ipPoint); // связываем с локальной точкой ipPoint // получаем конечную точку, с которой связан сокет Console.WriteLine(socket.LocalEndPoint); // 0.0.0.0:8888

      В этом примере сокет будет прослушивать подключения по 8888 порту на любых локальных адресах. То есть клиент должен будет подключаться к локальному адресу, например, к 127.0.0.1, и порту 8888.

      Прослушивание подключений. Метод Listen

      Для запуска прослушивания подключений на выбранной локальной конечной точке применяется метод Listen :

      public void Listen (); public void Listen (int backlog);

      При обращении к серверу входящие подключения помещаются в очередь для последующей обработки. По умолчанию эта очередь допускает 2147483647 подключений. Вторая версия метода Listen через параметр позволяет переопределить длину очереди.

      stem.Net; using System.Net.Sockets; IPEndPoint ipPoint = new IPEndPoint(IPAddress.Any, 8888); using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(ipPoint); // связываем с локальной точкой ipPoint socket.Listen(1000); // запускаем прослушивание // количество входящих подключений, которые можно поместить в очередь, равно 1000

      Подключение клиента

      После начала прослушивания сокет готов принимать подключения. Для приема подключений применяются методы Accept()/AcceptAsync() . Эти методы имеют ряд перегруженных версий. Отмечу саму простую из них:

      Все версии методов Accept()/AcceptAsync() в качестве результа возвращают объект Socket, который инкапсулирует входящее подключение, то есть по сути представляет подключенного клиента.

      using System.Net; using System.Net.Sockets; IPEndPoint ipPoint = new IPEndPoint(IPAddress.Any, 8888); using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(ipPoint); socket.Listen(); Console.WriteLine("Сервер запущен. Ожидание подключений. "); // получаем входящее подключение using Socket client = await socket.AcceptAsync(); // получаем адрес клиента Console.WriteLine($"Адрес подключенного клиента: ");

      Через свойства Socket можно получить информацию о подключении клиента, в частности, свойство RemoteEndPoint позволяет получить адрес подключенного клиента.

      Для такого просто сервера для теста определим клиент. Возьмем новый проект консольного приложения на C# и определим в нем следующий код:

      using System.Net.Sockets; using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try < await socket.ConnectAsync("127.0.0.1", 8888); Console.WriteLine($"Подключение к установлено"); > catch (SocketException) < Console.WriteLine($"Не удалось установить подключение с "); >

      Здесь в метод ConnectAsync передаем данные конечной точки сервера и при успешном подключении выводим сообщение.

      Запустим сервер, а затем запустим клиент. В итоге после подключения клиента к серверу в консоли сервера мы увидим что-то наподобие:

      Сервер запущен. Ожидание подключений. Адрес подключенного клиента: 127.0.0.1:52767

      В данном случае мы видим, что в моем случае для подключения к серверу сокет-клиент использует адрес 127.0.0.1:52767. А в консоли клиента отобразится сообщение об успешном подключении:

      Подключение к 127.0.0.1:8888 установлено

      Источник

Оцените статью