• Socket通讯


    1、TCP/IP、UDP、Socket 概念:

      TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。

      UDP(User Data Protocol,用户数据报协议)是与 TCP 相对应的协议。它是属于TCP/IP协议族中的一种。

      这里有一张图,表明了这些协议的关系。

      

       注:TCP/IP协议 包括  传输层、网络层、链路层。

      上图中没有 Socket 影子,请看下图:

      

       Socket 是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

    举个例子:一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。

      

       先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

      总结:Socket 起源于 Unix,而 Unix/Linux 基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。

    2、C# 实现 Socket 通讯:

      首先引用命名空间:using System.Netusing System.Net.Sockets;

      1️⃣ 客户端代码:

      private static byte[] result = new byte[1024];

      //设置服务器IP地址
      IPAddress ip = IPAddress.Parse("127.0.0.1");
      Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      try
      {
        clientSocket.Connect(new  IPEndPoint(ip, 1001));
        Console.WriteLine("连接服务器成功!");
      }
      catch (Exception)
      {
        Console.WriteLine("连接服务器失败!");
      }
      //通过 clientSocket 接收数据
      int receiveLength = clientSocket.Receive(result);
      Console.WriteLine("接收到服务器消息:{0}", Encoding.ASCII.GetString(result, 0, receiveLength));
      //通过 clientSocket 发送数据
      for (int i = 0; i < 10; i++)
      {
        try
        {
          Thread.Sleep(2000);
          string SendMsg = "客服端发送数据,时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
          clientSocket.Send(Encoding.ASCII.GetBytes(SendMsg));
          Console.WriteLine("向服务器端发送消息:{0}", SendMsg);
        }
        catch (Exception)
        {
          clientSocket.Shutdown(SocketShutdown.Both);
          clientSocket.Close();
          break;
        }
      }
      Console.WriteLine("消息发送完毕!");

      2️⃣ 服务端代码:

      private static byte[] result = new byte[1024];
      private static int ServicePort = 1001;
      private static Socket ServiceSocket;
      static void Main(string[] args)
      {
        //服务器IP
        IPAddress ip = IPAddress.Parse("127.0.0.1");
        ServiceSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        ServiceSocket.Bind(new IPEndPoint(ip, ServicePort)); //绑定IP地址,端口
        ServiceSocket.Listen(10); //设定最多10个排队连接请求
        Thread th = new Thread(ListenClientConnect);
        th.Start();
        Console.WriteLine("启动监听{0}成功", ServiceSocket.LocalEndPoint.ToString());
        Console.ReadLine();
      }
      /// <summary>
      /// 监听客户端连接
      /// </summary>
      private static void ListenClientConnect()
      {
        while (true)
        {
          Socket clientSocket = ServiceSocket.Accept();
          clientSocket.Send(Encoding.ASCII.GetBytes("Service say Hollo!"));
          Thread th = new Thread(ReceiveMessage);
          th.Start(clientSocket);
        }
      }
      /// <summary>
      /// 接收消息
      /// </summary>
      /// <param name="ClientSocket"></param>
      private static void ReceiveMessage(object ClientSocket)
      {
        Socket myClientSocket = (Socket)ClientSocket;
        while (true)
        {
          try
          {
            //通过 ClientSocket 接收数据
            int ReceiveNumber = myClientSocket.Receive(result);
            Console.WriteLine("接收到客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result));
          }
          catch (Exception)
          {
            Console.WriteLine("获取客户端消息失败!");
            myClientSocket.Shutdown(SocketShutdown.Both);
            myClientSocket.Close();
            break;
          }
        }
      }

  • 相关阅读:
    WPF-模拟动态更换logo的过程(3),图片正在使用中,下载同名图片无法覆盖的问题。
    WPF-模拟动态更换logo的过程(2),如何把网上的图片下载到指定目录。
    WPF-模拟动态更换logo的过程(1),如何获取程序的根目录。
    Prism——Window 必须是树的根目录。不能将 Window 添加为 Visual 的子目录。
    一款常用的截图工具(能够截gif动图)
    WPF-带有GridView的ListView样式
    WPF-自定义实现步骤条控件
    分页总页数计算公式
    FileZilla:425 Can't open data connection for transfer of解决办法
    查看window重启日志
  • 原文地址:https://www.cnblogs.com/wangye520/p/14524133.html
Copyright © 2020-2023  润新知