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;
      }
    }
  }

原文地址:https://www.cnblogs.com/wangye520/p/14524133.html