UN2L1——Socket的重要API

本章代码关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
System.Net.Sockets                //Socket所在命名空间
Socket //套接字类,用于网络通信
AddressFamily //网络寻址枚举类型,决定寻址方案
AddressFamily.InterNetwork //IPv4寻址
AddressFamily.InterNetwork6 //IPv6寻址
SocketType //套接字枚举类型,决定使用的套接字类型
SocketType.Dgram //支持数据报,最大长度固定的无连接、不可靠的消息(主要用于UDP通信)
SocketType.Stream //支持可靠、双向、基于连接的字节流(主要用于TCP通信)
ProtocolType //协议类型枚举类型,决定套接字使用的通信协议
ProtocolType.Udp //TCP传输控制协议
ProtocolType.Tcp //UDP用户数据报协议
//常用属性
socket.Connected //套接字的连接状态
socket.SocketType //获取套接字的类型
socket.ProtocolType //获取套接字的协议类型
socket.AddressFamily //获取套接字的寻址方案
socket.Available //获取从网络中获取准备读取的数据数据量
socket.LocalEndPoint //获取本机EndPoint对象
socket.RemoteEndPoint //获取远程EndPoint对象
//服务端常用方法
socket.Bind() //绑定IP和端口,服务端socket设置
socket.Listen() //设置客户端连接的最大数量
socket.Accept() //等待客户端连入,会阻塞线程
//客户端常用方法
socket.Connect() //连接远程服务端
//同步收发消息相关
socket.Send() //同步发送消息,会阻塞线程
socket.Receive() //同步接收消息,会阻塞线程
//关闭Socket相关
sockets.Shutdown() //停用socket连接,在Close前需要调用,需要传入SocketShutdown枚举
SocketShutdown.Send //停用socket的发送
SocketShutdown.Receive //停用socket的接收
SocketShutdown.Both //停用socket的发送和接收
socket.Close() //关闭并释放socket

//TCP流套接字的声明
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
//UDP数据报套接字的声明
new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)

Socket套接字

它是C#提供给我们用于网络通信的一个类(在其它语言当中也有对应的Socket类)
类名:Socket
命名空间:System.Net.Sockets

TCP和UDP两种长连接通信方案都是基于Socket套接字的
我们之后只需要使用其中的各种方法,就可以进行网络连接和网络通信了
这里必须掌握的内容就是如何声明TCP和UDP的Socket​套接字

Socket套接字是支持TCP/IP网络通信的基本操作单位,一个套接字对象包含以下关键信息:

  1. 本机的IP地址和端口
  2. 对方主机的IP地址和端口
  3. 双方通信的协议信息

一个Socket​对象表示一个本地或者远程套接字信息,它可以被视为一个数据通道
这个通道连接与客户端和服务端之间,数据的发送和接受均通过这个通道进行

一般在制作长连接游戏时,我们会使用Socket套接字作为我们的通信方案,我们通过它连接客户端和服务端,通过它来收发消息
你可以把它抽象的想象成一根管子,插在客户端和服务端应用程序上,通过这个管子来传递交换信息

Socket的类型

Socket​套接字有3种不同的类型

  1. 流套接字

    主要用于实现TCP通信,提供了面向连接、可靠的、有序的、数据无差错且无重复的数据传输服务

  2. 数据报套接字

    主要用于实现UDP通信,提供了无连接的通信服务,数据包的长度不能大于32KB,不提供正确性检查,不保证顺序,可能出现重发、丢失等情况

  3. 原始套接字(不常用,不深入讲解)

    主要用于实现IP数据包通信,用于直接访问协议的较低层,常用于侦听和分析数据包

通过Socket​的构造函数,我们可以申明不同类型的套接字,Socket​的构造函数有三种,我们主要使用第三种重载

1
2
3
public Socket(SocketInformation socketInformation);
public Socket(SocketType socketType, ProtocolType protocolType);
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType); //主要使用该方法
  • 参数一:AddressFamily​:网络寻址 枚举类型,决定寻址方案

    • 常用:

      1. InterNetwork​ —— IPv4寻址
      2. InterNetwork6​ —— IPv6寻址
    • 做了解:

      1. UNIX​ —— UNIX本地到主机地址
      2. ImpLink​ —— ARPANETIMP地址
      3. Ipx​ —— IPX或SPX地址
      4. Iso​ —— ISO协议的地址
      5. Osi​ —— OSI协议的地址
      6. NetBios​ —— NetBios地址
      7. Atm​ —— 本机ATM服务地址
  • 参数二:SocketType​:套接字枚举类型,决定使用的套接字类型

    • 常用:

      1. Dgram​ —— 支持数据报,最大长度固定的无连接、不可靠的消息(主要用于UDP通信)
      2. Stream​ —— 支持可靠、双向、基于连接的字节流(主要用于TCP通信)
    • 做了解:

      1. Raw​ —— 支持对基础传输协议的访问
      2. Rdm​ —— 支持无连接、面向消息、以可靠方式发送的消息
      3. Seqpacket​ —— 提供排序字节流的面向连接且可靠的双向传输
  • 参数三:ProtocolType​:协议类型枚举类型,决定套接字使用的通信协议

    • 常用:

      1. TCP​ —— TCP传输控制协议
      2. UDP​ —— UDP用户数据报协议
    • 做了解:

      1. IP​ —— IP网际协议
      2. Icmp​ —— Icmp网际消息控制协议
      3. Igmp​ —— Igmp网际组管理协议
      4. Ggp​ —— 网关到网关协议
      5. IPv4​ —— Internet协议版本4
      6. Pup​ —— PARC通用数据包协议
      7. Idp​ —— Internet数据报协议
      8. Raw​ —— 原始IP数据包协议
      9. Ipx​ —— Internet数据包交换协议
      10. Spx​ —— 顺序包交换协议
      11. IcmpV6​ —— 用于IPv6的Internet控制消息协议

2、3参数的常用搭配:

  • SocketType.Dgram​ + ProtocolType.Udp​ = UDP协议通信(常用,主要学习)
  • SocketType.Stream​ + ProtocolType.Tcp​ = TCP协议通信(常用,主要学习)
  • SocketType.Raw​ + ProtocolType.Icmp​ = Internet控制报文协议(了解)
  • SocketType.Raw​ + ProtocolType.Raw​ = 简单的IP包通信(了解)

我们必须要掌握:

  • TCP流套接字

    1
    Socket socketTcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  • UDP数据报套接字

    1
    Socket socketUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

Socket的常用属性

  1. 套接字的连接状态

    1
    if(socketTcp.Connected) { }
  2. 获取套接字的类型

    1
    print(socket.SocketType);
  3. 获取套接字的协议类型

    1
    print(socket.ProtocolType);
  4. 获取套接字的寻址方案

    1
    print(socket.AddressFamily);
  5. 从网络中获取准备读取的数据数据量

    返回的是当前有多少字节准备读取

    1
    print(socket.Available);
  6. 获取本机EndPoint​对象(注意 :IPEndPoint​继承EndPoint​)

    1
    IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
  7. 获取远程EndPoint​对象

    1
    IPEndPoint RemoteEndPoint = socket.RemoteEndPoint as IPEndPoint;

Socket的常用方法

  1. 主要用于服务端

    1. 绑定IP和端口

      1
      socket.Bind(ipPoint);
    2. 设置客户端连接的最大数量

      1
      socket.Listen(10);
    3. 等待客户端连入

      执行该方法会阻塞线程,直到有客户端连入
      客户端连入后会返回与该客户端连接的socket​对象,通过该对象来收发该客户端数据

      1
      socket.Accept();
  2. 主要用于客户端

    1. 连接远程服务端

      执行该方法会阻塞线程,直到连接超时或失败

      1
      socket.Connect(IPAddress.Parse("118.12.123.11"), 8080);
  3. 客户端服务端都会用的

    1. 同步发送和接收数据

      • TCP同步发送数据

        传入字节数组byte[]​​​形式的数据,该方法会阻塞线程

        1
        socket.Send()
      • TCP同步接收数据

        返回字节数组byte[]​​​形式的数据,该方法会阻塞线程

        1
        socket.Receive()
      • UDP同步接受发送数据

        详细请见:UDP同步收发消息API

    2. 异步发送和接收数据

      详细请见:TCP异步通信常用方法

    3. 释放连接并关闭Socket,先于Close​​​调用

      该方法不可逆转,一旦关闭就不能重新开启,传入SocketShutdown​​​枚举,枚举各个类型含义如下:

      • SocketShutdown.Send​​​:停用在此 socket 上发送数据。
      • SocketShutdown.Receive​​​:停用在此 socket 上接收数据。
      • SocketShutdown.Both​​​:停用在此 socket 上发送和接收数据。
      1
      sockets.Shutdown(SocketShutdown.Both)
    4. 关闭连接,释放所有Socket关联资源

      1
      socket.Close()