Резюме сокета

искусственный интеллект

Один: что такое SOCKET

Английское значение слова «сокет» — «отверстие» или «гнездо». В качестве механизма связи процесса примите последнее значение. Также часто называемый «сокетом», он используется для описания IP-адресов и портов и является дескриптором цепочки связи (на самом деле он используется двумя программами для связи).
Розетка очень похожа на телефонную розетку. Возьмем в качестве примера телефонную сеть: две стороны телефонного звонка эквивалентны двум программам, которые общаются друг с другом, а номер телефона — это IP-адрес. Перед совершением звонка любой пользователь должен сначала владеть телефоном, что эквивалентно заявке на розетку, и в то же время он должен знать номер другой стороны, что эквивалентно тому, что другая сторона имеет стационарную розетку. Затем наберите вызов другой стороне, что эквивалентно выдаче запроса на соединение. Если другая сторона присутствует и свободна, поднимите трубку, и две стороны могут официально поговорить, что эквивалентно успешному соединению. Процесс разговора между двумя сторонами — это процесс, в котором одна сторона отправляет сигнал на телефон, а другая сторона получает сигнал от телефона, что эквивалентно отправке данных в сокет и получению данных из сокета. Если после завершения вызова один из абонентов кладет трубку, это эквивалентно закрытию сокета и отмене соединения.

1. Классификация розеток

Чтобы удовлетворить требования к качеству связи и производительности различных программ, общие сетевые системы предоставляют пользователям следующие три разных типа сокетов, которые они могут выбирать в соответствии с различными потребностями при разработке программ:

Потоковый сокет (SOCK_STREAM): обеспечивает надежный, ориентированный на соединение сервис двусторонней передачи данных. Он реализует безошибочную, неповторяющуюся передачу данных, встроенное управление потоком, а передаваемые данные рассматриваются как поток байтов без границ записи. В наборе протоколов TCP/IP TCP используется для реализации передачи потоков байтов.Когда пользователи хотят отправлять большие пакеты данных или предъявляют высокие требования к надежности передачи данных, используются потоковые сокеты.

Сокеты дейтаграмм (SOCK_DGRAM): обеспечивают ненадежную двустороннюю передачу данных без установления соединения. Данные отправляются отдельными пакетами, а границы записи сохраняются без каких-либо гарантий надежности. Данные могут быть потеряны или дублированы во время передачи, и нет гарантии, что данные будут получены на принимающей стороне в том порядке, в котором они были отправлены. В наборе протоколов TCP/IP сокеты дейтаграмм реализованы с использованием UDP.

Необработанный сокет (SOCK_RAW): этот сокет обеспечивает прямой доступ к протоколам нижнего уровня, таким как IP или ICMP. Обычно используется для сетевого программирования основного протокола TCP/IP.

два: SOCKET Связанные концепции

1. Порт

В Интернете много таких хостов, и на этих хостах обычно работает несколько служебных программ, и они предоставляют несколько услуг одновременно. Каждая служба открывает сокет и привязывает его к порту.Разные порты соответствуют разным службам (приложениям).Поэтому номера портов используются в сетевых протоколах для идентификации различных процессов на хосте.
Например: http использует порт 80, FTP использует порт 21.

2. Соглашение

2.1 ПТС:

TCP — это ориентированный на установление соединения, надежный протокол связи транспортного уровня на основе потока байтов. Предоставляет высоконадежные услуги передачи данных для двух хостов. Он может передавать данные с исходного хоста на целевой хост без ошибок. Когда есть данные для отправки, данные, отправленные процессом приложения, фрагментируются, чтобы быть пригодными для передачи на сетевом уровне; при получении пакета с сетевого уровня необходимо подтвердить полученный пакет, а также установить тайм-аут для повторной передачи. потерянных пакетов и т.д. С этой целью TCP необходимо добавить много дополнительных накладных расходов, чтобы выполнять некоторые необходимые элементы управления в процессе передачи данных для обеспечения надежной передачи данных. Поэтому эффективность TCP-передачи относительно низка.

2.1.1 Рабочий процесс TCP

TCP — это протокол, ориентированный на установление соединения.Протокол TCP завершает процесс установления соединения, аналогичный телефонному звонку, посредством трех сегментов сообщения.Этот процесс называется трехсторонним рукопожатием, как показано на рисунке:

https://images2015.cnblogs.com/blog/1033738/201612/1033738-20161224160027854-1956600516.png

Первое рукопожатие: когда соединение установлено, клиент отправляет SYN-пакет (SEQ=x) на сервер и переходит в состояние SYN_SEND, ожидая подтверждения от сервера.

Второе рукопожатие: сервер получает пакет SYN и должен подтвердить SYN клиента (ACK=x+1), и в то же время отправляет пакет SYN (SEQ=y), то есть пакет SYN+ACK, в этот момент время, когда сервер входит в состояние SYN_RECV.

Третье рукопожатие: клиент получает пакет SYN+ACK от сервера и отправляет на сервер пакет подтверждения ACK (ACK=y+1).После отправки пакета клиент и сервер переходят в состояние «Установлено» и завершают трехстороннее рукопожатие.

2.1.2 Передача данных

Как только две взаимодействующие стороны устанавливают TCP-соединение, любая из сторон в соединении может отправлять данные и получать данные от другой стороны. Протокол TCP отвечает за составление пользовательских данных (потоков байтов) в несколько дейтаграмм определенного формата и длины для отправки, а также за повторную сборку и восстановление пользовательских данных в порядке разборки после получения дейтаграмм.
При использовании TCP для передачи данных данные передаются в виде потока байтов.

2.1.3 Прекращение соединения

Для установления соединения требуется три рукопожатия, а для прекращения соединения требуется четыре рукопожатия, что вызвано полузакрытием TCP. Конкретный процесс показан на рисунке:

https://images2015.cnblogs.com/blog/1033738/201612/1033738-20161224161001261-2026303529.png

2.1.4 Основные возможности TCP

Основные особенности TCP заключаются в следующем.
(1) является протоколом, ориентированным на соединение.
(2) Сквозная связь. Каждое TCP-соединение может иметь только две конечные точки и может обмениваться данными только один-к-одному, а не прямой связью «точка-многоточка».
(3) Высокая надежность. Данные, передаваемые через TCP-соединение, могут гарантировать, что данные поступят к получателю точно, без ошибок, потерь или повторений, а также гарантировать, что порядок поступления каждых данных будет таким же, как порядок, в котором они были отправлены.
(4) Полнодуплексная передача.
(5) Данные передаются в виде потока байтов.
(6) Передаваемые данные не имеют границы сообщения.

2.1.5 Синхронный и асинхронный

Синхронный режим работы означает, что когда программа, написанная на TCP, выполняет оператор прослушивания или получения, она не будет продолжать выполняться до тех пор, пока работа не будет завершена (прослушивание запроса на соединение или получение данных от другой стороны), и поток находится в состоянии ожидания. состояние заблокировано.Выполнение следующего оператора не продолжается до тех пор, пока оператор не завершит свою соответствующую работу.
Асинхронная работа означает, что когда программа выполняется для оператора мониторинга или получения, она будет продолжать выполняться независимо от того, завершена работа или нет.

2.2 UDP

UDP — это простой, ориентированный на дейтаграммы протокол без установления соединения, который предоставляет услуги передачи, которые не обязательно являются надежными. Так называемый «без установления соединения» означает, что нет необходимости устанавливать соединение с другой стороной перед официальным общением, и оно отправляется напрямую, независимо от состояния другой стороны. Это очень похоже на отправку текстового сообщения на мобильный телефон, если вы знаете номер мобильного телефона другой стороны, вам не нужно учитывать состояние мобильного телефона другой стороны. Хотя UDP не может гарантировать надежность передачи данных, эффективность передачи данных выше.

2.1.1 Разница между UDP и TCP
(1) UDP не так надежен, как TCP
TCP содержит специальный механизм гарантии доставки: когда получатель данных получает информацию от отправителя, он автоматически отправляет отправителю подтверждающее сообщение, отправитель продолжит передачу другой информации только после получения подтверждающего сообщения, в противном случае он будет ждать до тех пор, пока подтверждение получено. В отличие от TCP, UDP не обеспечивает гарантированного механизма доставки данных. Сам протокол не может обнаружить или указать на потерю дейтаграмм при передаче от отправителя к получателю. Поэтому люди обычно называют UDP ненадежным транспортным протоколом.
(2) UDP не гарантирует упорядоченную передачу
UDP не гарантирует порядок отправки и получения данных. Для пакетных дейтаграмм это может быть не по порядку.

2.1.2 Преимущества UDP

(1) UDP быстрее, чем TCP
Поскольку протоколу UDP не нужно сначала устанавливать соединение с другой стороной, а также не требуется подтверждение передачи, его скорость передачи данных намного выше, чем у TCP. Для приложений, в которых основное внимание уделяется производительности передачи, а не целостности передачи (таким как воспроизведение звука по сети, видео по запросу, сетевые конференции и т. д.), UDP больше подходит, поскольку его скорость передачи высока, поэтому видео, воспроизводимое по сети, имеет хорошее качество звука и четкое изображение.
(2) UDP имеет границы сообщений
Сообщение, отправленное UDP-отправителем в прикладную программу, доставляется непосредственно на уровень IP после добавления заголовка. Ни разделять, ни объединять, а сохранять границы этих пакетов. Использование UDP не требует рассмотрения проблемы границы сообщения, что делает программирование UDP более удобным, чем TCP, при обработке полученных данных. С точки зрения программиста сокеты UDP проще в использовании, чем TCP. Эта особенность UDP также показывает, что это протокол передачи сообщений.
(3) UDP может передавать один ко многим
Поскольку передача данных не устанавливает соединение, нет необходимости поддерживать состояние соединения (включая состояние отправки и получения и т. д.), поэтому сервер может передавать одно и то же сообщение нескольким клиентам одновременно. Используя UDP, вы можете использовать широковещательную или многоадресную рассылку для одновременной отправки сообщений всем клиентским процессам в подсети, что также удобнее, чем TCP.
Среди них высокая скорость является основным преимуществом UDP.
Поскольку в протокол TCP вживлены различные функции безопасности, в процессе фактической реализации будет занято большое количество системных накладных расходов, что, несомненно, серьезно повлияет на скорость. В отличие от UDP, поскольку от надежного механизма передачи информации отказываются, такие функции, как безопасность и сортировка, передаются для завершения приложению верхнего уровня, что значительно сокращает время выполнения и обеспечивает скорость. Короче говоря, «идея» UDP заключается в том, чтобы «несмотря ни на что, просто отправлять данные быстрее».

https://images2015.cnblogs.com/blog/1033738/201612/1033738-20161224175130214-655760387.png

Три: общий режим приложения сокета:

 https://images2015.cnblogs.com/blog/1033738/201612/1033738-20161222105102807-1112314980.png

 

Четыре: основная блок-схема связи SOCKET:

https://images2015.cnblogs.com/blog/1033738/201612/1033738-20161222110415651-1974763936.png

В соответствии с базовой блок-схемой связи через сокеты суммируйте основные этапы связи:

Сервис-терминал:

Шаг 1: Создайте объект Socket для прослушивания подключений;

Шаг 2: Создайте объект EndPoint с указанным номером порта и ip сервера;

Шаг 3: привяжите EndPoint к методу Bind() объекта сокета;

Шаг 4: Начните слушать с помощью метода Listen() объекта сокета;

Шаг 5: После получения соединения от клиента используйте метод Accept() объекта сокета, чтобы создать новый объект сокета для связи с клиентом;

Шаг 6: Не забудьте закрыть сокет после завершения связи;

Клиент:

Шаг 1: Создайте объект Socket;

Шаг 2: Создайте объект EndPoint с указанным номером порта и ip сервера;

Шаг 3: Используйте метод Connect() объекта сокета, чтобы отправить запрос на подключение к серверу с установленным выше объектом EndPoint в качестве параметра;

Шаг 4: Если соединение установлено успешно, используйте метод Send() объекта сокета для отправки информации на сервер;

Шаг 5: Используйте метод Receive() объекта сокета для получения информации с сервера;

Шаг 6: Не забудьте закрыть сокет после завершения связи;

Пятое: пример программы WinForm

Интерфейс сервера:

https://images2015.cnblogs.com/blog/1033738/201612/1033738-20161222163829870-923153496.png

Код реализован следующим образом:

 using System;

 using System.Collections.Generic;

 using System.ComponentModel;

 using System.Data;

 using System.Drawing;

 using System.Linq;

 using System.Net;

 using System.Net.Sockets;

 using System.Text;

 using System.Threading.Tasks;

 using System.Windows.Forms;

 using System.Threading;

 using System.IO;

 namespace SocketServer

 {

     public partial class FrmServer : Form

     {

         public FrmServer()

         {

             InitializeComponent();

         }

// Определить обратный вызов: решить проблему межпотокового доступа

       private delegate void SetTextValueCallBack(string strValue);

//Определяем обратный вызов для получения сообщения, отправленного клиентом

       private delegate void ReceiveMsgCallBack(string strReceive);

//объявляем обратный вызов

       private SetTextValueCallBack setCallBack;

//декларация

       private ReceiveMsgCallBack receiveCallBack;

//Определяем обратный вызов: добавляем элементы в элемент управления ComboBox

       private delegate void SetCmbCallBack(string strItem);

//декларация

       private SetCmbCallBack setCmbCallBack;

//Определяем обратный вызов для отправки файла

       private delegate void SendFileCallBack(byte[] bf);

//декларация

       private SendFileCallBack sendCallBack;

//Сокет для связи

       Socket socketSend;

//SOCKET для мониторинга

       Socket socketWatch;

// Сохраняем IP-адрес и сокет удаленно подключенного клиента в коллекции

         Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();

//Создаем поток, который прослушивает подключения

       Thread AcceptSocketThread;

//Поток, который получает сообщение, отправленное клиентом

       Thread threadReceive;

       /// <summary>

/// Начать прослушивание

       /// </summary>

       /// <param name="sender"></param>

       /// <param name="e"></param>

       private void btn_Start_Click(object sender, EventArgs e)

       {

//При нажатии, чтобы начать прослушивание, создайте сокет на стороне сервера, который отвечает за прослушивание IP-адреса и номера порта

             socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//получаем ip адрес

            IPAddress ip=IPAddress.Parse(this.txt_IP.Text.Trim());

// Создаем номер порта

             IPEndPoint point=new IPEndPoint(ip,Convert.ToInt32(this.txt_Port.Text.Trim()));

//Привязать IP-адрес и номер порта

           socketWatch.Bind(point);

This.txt_Log.AppendText("Отслеживание успеха"+" \r \n");

//Начать прослушивание: установить максимальное количество запросов, которые могут быть подключены одновременно

           socketWatch.Listen(10);

// экземпляр обратного вызова

           setCallBack = new SetTextValueCallBack(SetTextValue);

           receiveCallBack = new ReceiveMsgCallBack(ReceiveMsg);

           setCmbCallBack = new SetCmbCallBack(AddCmbItem);

           sendCallBack = new SendFileCallBack(SendFile);

//создать поток

           AcceptSocketThread = new Thread(new ParameterizedThreadStart(StartListen));

           AcceptSocketThread.IsBackground = true;

           AcceptSocketThread.Start(socketWatch);

       }

       /// <summary>

/// Ждем пока клиент подключится и создадим Socket для связи с ним

       /// </summary>

       /// <param name="obj"></param>

       private void StartListen(object obj)

       {

           Socket socketWatch = obj as Socket;

           while (true)

           {              

//Ждем, пока клиент подключится и создадим сокет для связи

               socketSend = socketWatch.Accept();

//Получить IP-адрес и номер порта удаленного хоста

               string strIp=socketSend.RemoteEndPoint.ToString();

               dicSocket.Add(strIp, socketSend);

               this.cmb_Socket.Invoke(setCmbCallBack, strIp);

String string strMsg = "Удаленный хост:" + socketSend.RemoteEndPoint + "Соединение установлено успешно";

// используем обратный вызов

               txt_Log.Invoke(setCallBack, strMsg);

//Определяем поток, который получает сообщения клиента

               Thread threadReceive = new Thread(new ParameterizedThreadStart(Receive));

               threadReceive.IsBackground = true;

               threadReceive.Start(socketSend);

           }

       }

       /// <summary>

/// Сервер продолжает получать сообщения, отправленные клиентом

       /// </summary>

       /// <param name="obj"></param>

       private void Receive(object obj)

       {

           Socket socketSend = obj as Socket;

           while (true)

           {

//После успешного подключения клиента сервер получает сообщение, отправленное клиентом

               byte[] buffer = new byte[2048];

//Количество действительно полученных байтов

               int count = socketSend.Receive(buffer);

Если (count == 0)//count означает, что клиент закрыт, для выхода из цикла

               {

                   break;

               }

               else

               {

                   string str = Encoding.Default.GetString(buffer, 0, count);

string strReceiveMsg = "Получено:" + socketSend.RemoteEndPoint + "Сообщение отправлено:" + str;

                     txt_Log.Invoke(receiveCallBack, strReceiveMsg);

               }

           }

       }

       /// <summary>

/// Метод, который должен выполнить делегат обратного вызова

       /// </summary>

       /// <param name="strValue"></param>

       private void SetTextValue(string strValue)

       {

           this.txt_Log.AppendText(strValue + " \r \n");

       }

       private void ReceiveMsg(string strMsg)

       {

           this.txt_Log.AppendText(strMsg + " \r \n");

       }

       private void AddCmbItem(string strItem)

       {

           this.cmb_Socket.Items.Add(strItem);

       }

      /// <summary>

/// Сервер отправляет сообщение клиенту

      /// </summary>

      /// <param name="sender"></param>

      /// <param name="e"></param>

      private void btn_Send_Click(object sender, EventArgs e)

      {

          try

          {

              string strMsg = this.txt_Msg.Text.Trim();

              byte[] buffer = Encoding.Default.GetBytes(strMsg);

               List<byte> list = new List<byte>();

               list.Add(0);

               list.AddRange(buffer);

//Преобразуем общую коллекцию в массив

               byte[] newBuffer = list.ToArray();

//Получить IP-адрес, выбранный пользователем

               string ip = this.cmb_Socket.SelectedItem.ToString();

                dicSocket[ip].Send(newBuffer);

            }

           catch (Exception ex)

           {

MessageBox.Show("Ошибка отправки сообщения клиенту:"+ex.Message);

          }

          //socketSend.Send(buffer);

      }

      /// <summary>

/// Выбираем файл для отправки

      /// </summary>

      /// <param name="sender"></param>

      /// <param name="e"></param>

      private void btn_Select_Click(object sender, EventArgs e)

      {

          OpenFileDialog dia = new OpenFileDialog();

//Устанавливаем начальный каталог

          dia.InitialDirectory = @"";

dia.Title = "Выберите файл для отправки";

// Фильтровать типы файлов

dia.Filter = "Все файлы|*.*";

          dia.ShowDialog();

// Назначаем полный путь к выбранному файлу текстовому полю

          this.txt_FilePath.Text = dia.FileName;

      }

      /// <summary>

/// Отправить файлы

      /// </summary>

      /// <param name="sender"></param>

      /// <param name="e"></param>

      private void btn_SendFile_Click(object sender, EventArgs e)

       {

           List<byte> list = new List<byte>();

//Получить путь к файлу для отправки

           string strPath = this.txt_FilePath.Text.Trim();

           using (FileStream sw = new FileStream(strPath,FileMode.Open,FileAccess.Read))

           {

               byte[] buffer = new byte[2048];

               int r = sw.Read(buffer, 0, buffer.Length);

               list.Add(1);

               list.AddRange(buffer);

               byte[] newBuffer = list.ToArray();

//Отправить btn_SendFile.Invoke(sendCallBack, newBuffer);

          }

       }

       private void SendFile(byte[] sendBuffer)

       {

           try

           {

      dicSocket[cmb_Socket.SelectedItem.ToString()].Send(sendBuffer, SocketFlags.None);

          }

          catch (Exception ex)

          {

MessageBox.show ("Ошибка отправки файла:" + примерная сумма);

          }

      }

      private void btn_Shock_Click(object sender, EventArgs e)

      {

          byte[] buffer = new byte[1] { 2};

          dicSocket[cmb_Socket.SelectedItem.ToString()].Send(buffer);

     }

     /// <summary>

/// перестать слушать

     /// </summary>

     /// <param name="sender"></param>

     /// <param name="e"></param>

     private void btn_StopListen_Click(object sender, EventArgs e)

     {

            socketWatch.Close();

            socketSend.Close();

// Завершить поток

            AcceptSocketThread.Abort();

            threadReceive.Abort();

        }

    }

}

клиентский интерфейс

https://images2015.cnblogs.com/blog/1033738/201612/1033738-20161222164540542-1315286554.pngКод реализован следующим образом:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Net.Sockets;

using System.Net;

using System.Threading;

using System.IO;

 

namespace SocketClient

{

    public partial class FrmClient : Form

    {

        public FrmClient()

        {

            InitializeComponent();

        }

// определяем обратный вызов

        private delegate void SetTextCallBack(string strValue);

//декларация

      private SetTextCallBack setCallBack;

//Определяем обратный вызов для получения сообщения, отправленного сервером

      private delegate void ReceiveMsgCallBack(string strMsg);

//декларация

      private ReceiveMsgCallBack receiveCallBack;

//Создаем подключенный сокет

      Socket socketSend;

//Создаем поток, который получает сообщения, отправленные клиентами

      Thread threadReceive;

      /// <summary>

/// соединять

      /// </summary>

      /// <param name="sender"></param>

      /// <param name="e"></param>

      private void btn_Connect_Click(object sender, EventArgs e)

        {

            try

            {

                socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                 IPAddress ip = IPAddress.Parse(this.txt_IP.Text.Trim());

                 socketSend.Connect(ip, Convert.ToInt32(this.txt_Port.Text.Trim()));

// экземпляр обратного вызова

                 setCallBack = new SetTextCallBack(SetValue);

                 receiveCallBack = new ReceiveMsgCallBack(SetValue);

This.txt_Log.Invoke(setCallBack, "Соединение установлено успешно");

//Открываем новый поток, который продолжает получать сообщения с сервера

                threadReceive = new Thread(new ThreadStart(Receive));

//Установить фоновый поток

               threadReceive.IsBackground = true;

               threadReceive.Start();

           }

           catch (Exception ex)

           {

MessageBox.Show("Ошибка подключения к серверу:" + ex.ToString());

            }

        }

        /// <summary>

/// Сообщение, отправленное интерфейсным сервером

        /// </summary>

        private void Receive()

        {

           try

           {

               while (true)

               {

                   byte[] buffer = new byte[2048];

//Количество фактически полученных байтов

                   int r = socketSend.Receive(buffer);

                   if (r == 0)

                   {

                       break;

                   }

                   else

                   {

//Определяем тип отправляемых данных

If (buffer[0] == 0)//Указывает, что текстовое сообщение отправлено

                       {

                           string str = Encoding.Default.GetString(buffer, 1, r - 1);

This.txt_Log.Invoke(receiveCallBack, "получить удаленный сервер:" + socketSend.RemoteEndPoint + "отправленное сообщение:" + str);

                       }

//Указывает, что файл отправлен

                       if (buffer[0] == 1)

                       {

                           SaveFileDialog sfd = new SaveFileDialog();

                              sfd.InitialDirectory = @"";

sfd.Title = "Выберите файл для сохранения";

sfd.Filter = "Все файлы|*.*";

                          sfd.ShowDialog(this);

                          string strPath = sfd.FileName;

                        using (FileStream fsWrite = new FileStream(strPath, FileMode.OpenOrCreate, FileAccess.Write))

                          {

                              fsWrite.Write(buffer, 1, r - 1);

                          }

MessageBox.Show("Файл успешно сохранен");

                      }

                  }

              }

          }

          catch (Exception ex)

             {

MessageBox.Show("Ошибка получения сообщения от сервера:" + ex.ToString());

           }

       }

       private void SetValue(string strValue)

       {

           this.txt_Log.AppendText(strValue + "\r \n");

       }

       /// <summary>

/// Клиент отправляет сообщение на сервер

       /// </summary>

       /// <param name="sender"></param>

       /// <param name="e"></param>

       private void btn_Send_Click(object sender, EventArgs e)

       {

           try

           {

               string strMsg = this.txt_Msg.Text.Trim();

               byte[] buffer = new byte[2048];

               buffer = Encoding.Default.GetBytes(strMsg);

               int receive = socketSend.Send(buffer);

           }

           catch (Exception ex)

           {

MessageBox.Show("Ошибка отправки сообщения:" + ex.Message);

           }

       }

       private void FrmClient_Load(object sender, EventArgs e)

       {

           Control.CheckForIllegalCrossThreadCalls = false;

       }

       /// <summary>

/// Отключить

       /// </summary>

       /// <param name="sender"></param>

       /// <param name="e"></param>

       private void btn_CloseConnect_Click(object sender, EventArgs e)

        {

//закрыть сокет

            socketSend.Close();

// Завершить поток

            threadReceive.Abort();

        }

    }

}

Шесть, пример консольной программы

using System.Net.Sockets;

using System.Net;

using System.Threading;

using System;

using System.Text;

пространство имен сокет сокет

{

    class SocketT

    {

private Socket _ServerSocket;//сокет прослушивания сервера

private bool _IsListionContect;//Прослушивание

        public SocketT()

        {

//Определяем конечную точку сети (инкапсулируем IP и порт)

            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1000);

//Создаем сокет

            _ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//Адрес привязки к серверу

            _ServerSocket.Bind(endPoint);

// Начать прослушивание

_ServerSocket.Listen(10);//Максимальная продолжительность прослушивания

Console.WriteLine("Сервер запущен...");

            try

            {

                while (true)

                {

//Метод Accept() принимает соединение от клиента, этот метод заблокирует выполнение текущего потока

                    Socket sockMsgSever = _ServerSocket.Accept();

Console.WriteLine("Имеется клиентское соединение...");

//Открываем фоновый поток для сеанса клиента

                    Thread thClientMsg = new Thread(ClientMsg);

thClientMsg.IsBackground = true;//Установить фоновый поток

                    thClientMsg.Name = "thClientMsg";

                    thClientMsg.Start(sockMsgSever);

                }

            }

            catch (Exception)

            {

                throw;

            }

        }

        /// <summary>

/// Полученный поток связи на стороне сервера и на стороне клиента

        /// </summary>

        /// <param name="?"></param>

        private void ClientMsg(object sokMsg)

        {

Socket socketMsg = sokMsg as Socket; // Преобразование типа объекта в связь через сокет

            while (true)

            {

// Подготавливаем кеш данных

                byte[] msyArray = new byte[0124 * 0124];

//Принимаем запрос, отправленный клиентом, и возвращаем реальную длину данных

                int TrueClientMsgLenth = socketMsg.Receive(msyArray);

//массив байтов в строку

                string strMsg = Encoding.UTF8.GetString(msyArray, 0, TrueClientMsgLenth);

// Отображаем данные клиента

Console.WriteLine("Данные клиента:" + strMsg);

            }

        }

        static void Main(string[] args)

        {

            SocketT obj = new SocketT();

            Console.ReadKey();

        }

    }

}