Exemplos e princípios de soquete simples (incluindo código-fonte)

O que é um soquete?

O soquete chamado geralmente também é chamado de "soquete", que é usado para descrever o endereço IP bai e porta, e é o identificador de uma cadeia de comunicação. O aplicativo geralmente envia uma solicitação à rede ou responde a uma solicitação da rede por meio de um "soquete".

 

Processo de conexão de soquete:

Socket é dividido em servidor e cliente, aqui usamos serverSocket e clientSocket para representar

Monitoramento do servidor: O soquete do lado do servidor não especifica ativamente o soquete do cliente, mas está em um estado de espera pelo monitoramento, monitoramento em tempo real do status da rede.

Solicitação do cliente: o cliente clientSocket envia uma solicitação de conexão e o destino é o serverSocket do servidor. Portanto, o clientSocket deve saber o ip e o número da porta do serverSocket

Confirmação de conexão: Quando o soquete do servidor monitora ou recebe uma solicitação de conexão do soquete do cliente, o servidor responde à solicitação do cliente, sugerindo um novo soquete e enviando o soquete do servidor para o cliente. Assim que o cliente confirma a conexão, a conexão é estabelecida .

 

A figura a seguir ilustra resumidamente o processo de vinculação:

 

Para obter detalhes, consulte o código simples (aqui o código-fonte foi colocado na conta oficial "Ink Direct", basta responder ao código-fonte do soquete ):

O código-fonte é wpf, porque o código-fonte do projeto não é fácil de dividir e empacotar, então um exemplo foi construído, se você não entendeu aqui, pode baixar o código-fonte e estudá-lo com atenção.

//Servidor

 Thread threadWatch = null;
 Socket Mysocket = null;
 ListBox ClientListboxs = null;
 //接受缓存
  byte[] arrMsgRec = new byte[1024 * 1024 * 2];
 Socket policy = null;
 Dictionary<string, Socket> SoketList = new Dictionary<string, Socket>();
 Thread threadRece = null;
   private void StartSocket()
        {
            //创建监听套接字
            Mysocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //获取ip对象
            IPAddress address = IPAddress.Parse("192.168.3.57");
            //创建IP和端口
            IPEndPoint endpoint = new IPEndPoint(address, int.Parse("4502"));
            Mysocket.Bind(endpoint);//绑定EndPoint对像 
            //监听队列长度
            Mysocket.Listen(10);
            threadWatch = new Thread(WatchConnection);
            threadWatch.IsBackground = true;
            threadWatch.Start();
        }
        
   // 监听新客户端请求    
 private void WatchConnection()
        {
            showMessage("等待客户连接");
            while (true)
            {
                policy = Mysocket.Accept();
                Socket policynew = policy;
                showMessage("连接成功");

                ListBox ClientListbox = ClientListboxs;
                ClientListbox.Dispatcher.Invoke(new Action(() => { ClientListbox.Items.Add(policynew.RemoteEndPoint.ToString()); }));
                SoketList.Add(policynew.RemoteEndPoint.ToString(), policy);//为新建连接创建新的socket
                if (threadRece == null)
                {
                    threadRece = new Thread(Rece);
                    threadRece.IsBackground = true;
                    threadRece.Start();
                }
            }
        }

Este tópico sempre existiu. A tarefa principal é monitorar se há uma conexão entre Cliente e Servidor. Se a conexão for bem-sucedida, outro tópico "Receber" será aberto. Neste segmento, é principalmente para obter o processamento de dados do personagem, incluindo o recebimento e envio de dados.

  private void Rece()
        {
            while (true)
            {
                try
                {
                    int strlong = policy.Receive(arrMsgRec);
                    byte[] message = arrMsgRec;
                    byte[] lin = arrMsgRec.Skip(2).Take(strlong - 4).ToArray();
                    string strMsgRec = System.Text.Encoding.UTF8.GetString(lin, 0, strlong - 4);//实际转换的字节长度为内容长度
                    showMessage(strMsgRec);
                }
                catch (Exception)
                {
                    
                }
            }
        }

        private void showMessage(string msg)
        {
            Action action = () => MsgContent.AppendText(msg + "\r\n");
            if (System.Threading.Thread.CurrentThread !=
        MsgContent.Dispatcher.Thread)
            {
                MsgContent.Dispatcher.Invoke
                    (System.Windows.Threading.DispatcherPriority.Normal,
                    action);
            }
            else
            {
                action();
            }
        }

O seguinte é enviar dados para o cliente

 private void send(object sender, RoutedEventArgs e)
        {
            senddate = System.DateTime.Now;
            var TELH = (char)0x02 + (char)0x30;//头部(无需照搬,测试用的)
            var TELF = (char)0x5F + (char)0x03;//尾部(无需照搬,测试用的)
            var Content = MsgContext.Text;
            var msg = TELH + Content + TELF;
            byte[] btMsg = System.Text.Encoding.UTF8.GetBytes(msg);
            policy.Send(btMsg);
            showMessage("发送:" +  MsgContext.Text);
        }

 Nota aqui: Na verdade, os dados transmitidos em TCP / IP devem ser em bytes. Por exemplo, transmitir 50 dados duplos é transmitir uma matriz de 400 bytes

//Cliente

Socket Mysocket = null;
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
   public void client()
        {
            Mysocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //获取ip对象
            IPAddress address = IPAddress.Parse("192.168.3.57");
            //创建IP和端口
            IPEndPoint endpoint = new IPEndPoint(address, int.Parse("4502"));
            Mysocket.Connect(endpoint);
            Thread threadWatch = new Thread(ReceiveMsg);
            //threadWatch.IsBackground = true;
            threadWatch.Start();
        }

A partir do código fonte do servidor, você pode ver que a composição da mensagem é composta de cabeçalho (dois bytes) + conteúdo + cauda (dois bytes), então se você deseja obter o conteúdo aqui, pule o cabeçalho e pegue o comprimento total -4 partes.

 public void ReceiveMsg()
        {
            while (true)
            {
                int strlong = Mysocket.Receive(arrMsgRec);
                byte[] message = arrMsgRec;
                byte[] lin = arrMsgRec.Skip(2).Take(strlong - 4).ToArray();
                string strMsgRec = System.Text.Encoding.UTF8.GetString(lin, 0, strlong - 4);//实际转换的字节长度为内容长度
                showMessage(strMsgRec);
            }
        }

//mandar

 public void Sends()
        {
           
            var TELH = (char)0x02 + (char)0x30;//头部
            var  TELF = (char)0x5F + (char)0x03;//尾部
            var Content = MsgSend.Text;
            var msg = TELH + Content + TELF;
            byte[] btMsg = System.Text.Encoding.UTF8.GetBytes(msg);
            Mysocket.Send(btMsg);
            showMessage("发送:" + MsgSend.Text);

        }

Exibir dados no controle

 private void showMessage(string msg)
        {
            Action action = () => MsgContent.AppendText(msg + "\r\n");
            if (System.Threading.Thread.CurrentThread !=
        MsgContent.Dispatcher.Thread)
            {
                MsgContent.Dispatcher.Invoke
                (System.Windows.Threading.DispatcherPriority.Normal,
                action);
            }
            else
            {
                action();
            }

        }

 Aqui, uma comunicação de soquete simples é concluída e o efeito é o seguinte:

Existem muitos usos práticos para sockets. Aqui eu os utilizo principalmente para comunicação entre programas e dispositivos. Por exemplo, qq usa sockets para comunicação, e navegadores e servidores também usam sockets para comunicação, mas a transmissão de pacotes http é baseada no http protocolo. Amigos interessados ​​podem estudar sozinhos

Aqui está uma postagem detalhada no blog http://www.jytek.com/seesharpsocket

Quem estiver interessado pode prestar atenção a " Ink Direct ", há muitos materiais de programação gratuitos para receber ~

 

Acho que você gosta

Origin blog.csdn.net/huxinyu0208/article/details/112758950
Recomendado
Clasificación