190 likes | 442 Views
Сетевое программирование в .NET. Работа с сокетами. Сокеты.
E N D
Сетевое программирование в .NET Работа с сокетами
Сокеты Сокет - это один конец двустороннегo канала связи между двумя прогpаммами, работающими в сети. Соединяя вместе два сокета, можно передавать данные между разными процессами (локальными или удаленными). Реализация сокетов обеспечивает инкапсуляцию протоколов ceтeвoгo и транспортного уровней. Существуют два основных типа сокетов - потоковые сокеты и дейтаграммные.
Потоковый сокет • это сокет с установленным соединением, состоящий из потока байтов, который может быть двунаправленным. т. е. через эту конечную точку приложение может и передавать, и получать данные. Потоковый сокет гaрантирует исправление ошибок, обрабатывает доставку и сохраняет последовательность дaнных. На нeгo можно положиться в доставке упорядоченных, недублированных дaнных. Потоки базируются на явных соединениях: сокет А запрашивает соединение с сокетом В, а сокет В либо соrлашается с запросом на установление соединения, либо отверraет ero.
Порты Порт определен, чтобы разрешить задачу одновременноrо взаимодействия с несколькими приложениями. По существу, с ero помощью расширяется понятие IP aдреса. Компьютер, на котором в одно время выполняется несколько приложений, получая пакет из сети, может идентифицировать целевой процесс. пользуясь уникальным номером порта. определенным при установлении соединения.
Порты Сокет состоит из IP aдpeca машины и номера порта, используемоrо приложением ТСР. Поскольку IP-aдpec уникален в Интернете, а номера портов уникальны на отдельной машине, номера сокетов также уникальны во всем Интернете. Эта характеристика позволяет процессу общаться через сеть с дрyrим процессом исключительно на основании номера сокета. За определенными службами номера портов зарезервированы (80, 3306, 8080 и т.п.)
Создание сервера Не забудем подключить System.Net.Sockets и System.Net // создаем конечную точку подключения IPHostEntry ipHost = Dns.GetHostEntry("localhost"); IPAddress ipAddr = ipHost.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000); // создаем сокет Socket sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // и связываем его с точкой подключения sListener.Bind(ipEndPoint);
Создание сервера sListener.Listen(10); // запускаем прослушивание while(true) { Console.WriteLine("start"); Socket handler = sListener.Accept(); // подключился клиент string data = null; byte [] bytes = new byte[1024]; int bytesRec = handler.Receive(bytes); // принимаем от него сообщение data= Encoding.ASCII.GetString(bytes, 0, bytesRec); Console.WriteLine(data); string theReply = "thanks!"; byte[] msg= Encoding.ASCII.GetBytes(theReply); handler.Send(msg); // и отправляем ответ handler.Shutdown(SocketShutdown.Both); // завершаем сеанс handler.Close(); }
Создание клиента byte [] bytes = new byte[1024]; // таким же образом создаем конечную точку подключения IPHostEntry ipHost = Dns.GetHostEntry("127.0.0.1"); IPAddress ipAddr = ipHost.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000); // создаем сокет Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // устанавливаем соединение sender.Connect(ipEndPoint);
Создание клиента // отправляем сообщение string message = "Hello!"; int bytesSend = sender.Send(Encoding.ASCII.GetBytes(message)); // получаем ответ от сервера int bytesRec = sender.Receive(bytes); Console.WriteLine("Server:"+Encoding.ASCII.GetString(bytes, 0, bytesRec)); // завершаем работу sender.Shutdown(SocketShutdown.Both); sender.Close(); Не забудьте в приложениях обработать исключения!
Классы TcpListener и TcpClient В отличие от класса Socket, в котором для отправки и получения данных применяется побайтовый подход, классы TcpClient и TcpListener придерживаются потоковой модели. В этих классах все взаимодействие между клиентом и сервером базируется на потоке с использованием класса NetworkStream. Однако при необходимости можно работать и с байтами.
Класс TcpListener // Создать объект класса TcpListener и запустить // его на прослушивание порта 65125 IPHostEntry ipHost = Dns.GetHostEntry("127.0.0.1"); IPAddress ipAddr = ipHost.AddressList[0]; TcpListener tcpListener = new TcpListener(ipAddr,65125); tcpListener.Start(); Console.WriteLine("Start of listening"); while( true ) // Ожидание запроса приемника { // По запросу приемника установить соединение и возвратить новый // объект класса сокета, который используется для установки связи с // приемником; тем временем tcpListener продолжает прослушивание Socket clientSocket = tcpListener.AcceptSocket();
Класс TcpListener // теперь можно создать сетевой поток данных и // объект для работы с ним – например, бинарный поток NetworkStream netStream = new NetworkStream(clientSocket); BinaryWriter binWriter = new BinaryWriter(netStream); . . . // в конце работы с клиентом не забудем закрыть сокет: clientSocket.Close();
Класс TcpClient // создать объект TcpClient для работы с сервером TcpClient serverSocket; serverSocket = new TcpClient("localhost", 65125); // создать сетевой поток данных и объект для чтения из него NetworkStream netStream = serverSocket.GetStream(); BinaryReader binReader = new BinaryReader(netStream); Не забывайте в приложениях обработать исключения!
Задание Создайте простые приложения клиент и сервер на основе классов TcpListener и TcpClient. Пусть, например, клиент отправляет сообщение, сервер его принимает и в ответ тоже отправляет сообщение, и на этом сеанс клиента завершается.