当前位置: 首页 > news >正文

C#网络编程(Socket编程)

文章目录

  • 0、写在前面的话
  • 1、Socket 介绍
    • 1.1 Socket是什么
    • 1.2 Socket在网络中的位置
  • 2、C# 中的Socket参数
    • 2.1 超时控制参数
    • 2.2 缓冲区参数
    • 2.3 UDP专用参数
  • 3、C# 中的Socket API
    • 3.1 Socket(构造函数)
      • 3.1.1 SocketType
      • 3.1.2 ProtocolType
      • 3.1.3 AddressFamily
    • 3.2 Bind()
    • 3.3 Connect()
    • 3.4 Listen() (TCP)
    • 3.5 Accept() (TCP)
    • 3.6 Receive() 与 Send()
    • 3.7 ReceiveFrom()与SendTo()
    • 3.8 Shutdown()和Close()
  • 4、IPAddress 和 IPEndPoint
    • 4.1 IPAddress
    • 4.2 IPEndPoint

0、写在前面的话

我创建的Unity、C#交流群,有兴趣可加入大家一起学习:952914223

1、Socket 介绍

1.1 Socket是什么

Socket的英文原意是“插座”,的意思,通常在计算机编程中称作套接字,是对对于TCP/IP的封装,我们可以将Socket联想成是由两个Socket对象搭建的成的一根通信管道,管道的两端是这两个Socket对象,而这根管道的连接的是两台主机的应用进程(通过IP地址和端口号确定进程)
请添加图片描述

1.2 Socket在网络中的位置

在这里插入图片描述

2、C# 中的Socket参数

2.1 超时控制参数

  1. ReceiveTimeout:接收超时
socket.ReceiveTimeout = 5000; // 5秒(单位:毫秒)
// 超时抛出SocketException,ErrorCode为10060 (TimedOut)
  1. SendTimeout:发送超时
socket.SendTimeout = 3000; // 3秒
// 影响Send/SendTo操作
  1. BeginConnect:连接超时
// 通过Connect方法的异步版本实现
socket.BeginConnect(remoteEP, null, null);
if(!socket.Connected) {
    // 自定义超时逻辑
}

2.2 缓冲区参数

  1. ReceiveBufferSize:接收缓冲区大小
socket.ReceiveBufferSize = 65536; // 64KB
// 影响内核网络栈的接收缓冲区
  1. SendBufferSize:发送缓冲区大小
socket.SendBufferSize = 32768; // 32KB
// 影响内核网络栈的发送缓冲区

2.3 UDP专用参数

  1. EnableBroadcast:启用广播
udpSocket.EnableBroadcast = true;
// 允许发送到广播地址(如255.255.255.255)
  1. 多播设置
// 加入多播组
udpSocket.SetSocketOption(SocketOptionLevel.IP,
                        SocketOptionName.AddMembership,
                        new MulticastOption(IPAddress.Parse("224.0.0.1")));

// 设置多播TTL
udpSocket.SetSocketOption(SocketOptionLevel.IP,
                        SocketOptionName.MulticastTimeToLive,
                        2); // 最多跨越2个路由器

3、C# 中的Socket API

3.1 Socket(构造函数)

public Socket(SocketInformation socketInformation);
public Socket(SocketType socketType, ProtocolType protocolType);
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

常见的 Socket 对象创建实例:

// 监控 ip4 地址,套接字类型为 TCP ,协议类型为 TCP
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

3.1.1 SocketType

指定 Socket 类的实例表示的套接字类型。

SocketType对应的ProtocolType描述
UnknownUnknown指定未知的 Socket 类型
Stream(使用字节流)Tcp支持可靠、双向、基于连接的字节流
Dgram(使用数据报)Udp面向无连接
RawIcmp、lgmp支持对基础传输协议的访问
Rdm支持无连接、面向消息、以可靠方式发送的消息,
Seqpacket在网络上提供排序字节流的面向连接且可靠的双向传输

3.1.2 ProtocolType

表示协议类型,是一个 enum 类型。
其中枚举重复值,常见用途:

  • 为旧值提供别名
  • 向后兼容
  • 提供更清晰的命名选择
枚举值协议说明
Unknown-1未知协议类型
Unspecified0未指定的协议
IP0Internet 协议 (IP) - 原始 IP 数据包
IPv6HopByHopOptions0IPv6 逐跳选项头
Icmp1Internet 控制消息协议 (ICMP)
Igmp2Internet 组管理协议 (IGMP)
Ggp3网关到网关协议 (GGP)
IPv44IPv4 协议
Tcp6传输控制协议 (TCP)
Pup12PARC 通用数据包协议 (PUP)
Udp17用户数据报协议 (UDP)
Idp22Internet 数据报协议 (IDP)
IPv641IPv6 协议
IPv6RoutingHeader43IPv6 路由头
IPv6FragmentHeader44IPv6 分片头
IPSecEncapsulatingSecurityPayload50IPv6 封装安全负载 (ESP) 头
IPSecAuthenticationHeader51IPv6 认证头 (AH)
IcmpV658ICMP for IPv6
IPv6NoNextHeader59IPv6 无下一个头
IPv6DestinationOptions60IPv6 目的选项头
ND77Net Disk 协议 (非正式)
Raw255原始 IP 数据包
Ipx1000Internet 数据包交换协议 (IPX)
Spx1256顺序数据包交换协议 (SPX)
SpxII1257SPX 版本 2

3.1.3 AddressFamily

表示使用的网络寻址方案

枚举值协议说明使用场景
Unknown-1未知地址族保留值
Unspecified0未指定的地址族通用情况
Unix1Unix本地通信Unix域Socket
InterNetwork2IPv4地址族最常用的IPv4网络
ImpLink3ARPANET IMP地址历史遗留
Pup4PUP协议地址Xerox PUP网络
Chaos5MIT CHAOS协议历史遗留
NS6Xerox NS协议Xerox网络系统
Ipx6IPX/SPX地址Novell网络
Iso7ISO协议OSI协议族
Osi 7OSI协议同Iso
Ecma8ECMA协议欧洲计算机制造商协会
DataKit9Datakit协议AT&T Datakit
Ccitt 10CCITT协议TU-T协议
Sna11IBM SNA地址IBM系统网络架构
DecNet12 DECnet地址Digital Equipment Corporation网络
DataLink13直接数据链路接口数据链路层访问
Lat14LAT地址Local Area Transport
HyperChannel15NSC HyperchannelNetwork Systems Corporation
AppleTalk16AppleTalk地址Apple网络协议
NetBios17NetBios地址Windows网络基本输入输出系统
VoiceView18VoiceView地址VoiceView音频协议
FireFox19FireFox协议非标准协议
Banyan21Banyan VINESBanyan虚拟网络系统
Atm22本机ATM服务异步传输模式
InterNetworkV623IPv6地址族IPv6网络
Cluster24Microsoft WolfpackMicrosoft集群服务
Ieee1284425IEEE 1284.4工作组打印机共享协议
Irda26IrDA地址红外数据协会
NetworkDesigners28Network Designers OSI网关网络设计者协议
Max29最大地址族保留值

3.2 Bind()

绑定本地IP和端口,你将在在本地创建 IPEndPoint 对象,拥有此 ip:post 的访问权限。目的是绑定本地机器的某个端口,所有经过此端口的数据就归你管了。

public void Bind (System.Net.EndPoint localEP);

使用实例:

Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress iP = IPAddress.Parse("127.0.0.1");

serverSocket.Bind(new IPEndPoint(iP, 2300))

3.3 Connect()

与远程主机建立连接。Connect() 有四个重载方法,不必关注,只需知道,必需提供 IP 和 Post 两个值。

IPAddress iP = IPAddress.Parse("127.0.0.1");
IPEndPoint iPEndPoint = new IPEndPoint(iP, 2300);
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        //创建与远程主机的连接
serverSocket.Connect(iPEndPoint);

3.4 Listen() (TCP)

监控所有发送到此主机的、特定端口的连接请求。服务端使用,客户端不需要。

public void Listen (int backlog);

使用 Bind() 后,使用 Listen() 方法进行监控,backlog 参数指定可排队等待接受的传入连接的数量,即挂起的连接队列的最大长度。

3.5 Accept() (TCP)

Accept() 以同步方式监听套接字,在连接请求队列中提取第一个挂起的连接请求,然后创建并返回一个新的 Socket 对象。

//创建终结点(EndPoint)
IPAddress ip = IPAddress.Any;             
IPEndPoint ipe = new IPEndPoint(ip, 8000);

//创建 socket 并开始监听
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(ipe);
serverSocket.Listen(10);//开始监听

//接受到client连接,为此连接建立新的socket,并接受信息
Socket temp = serverSocket.Accept();//为新建连接创建新的socket

注意的是,每次建立连接是一个 Accept() 对象,如果你要进行 服务器-客户端互相通讯,应使用同一个 Accept() 对象。每个 Accept 对象都是 从客户端请求建立开始的,期间只要使用同一个 Accept 对象,都可以进行数据传输。

3.6 Receive() 与 Send()

  • Receive() :接收信息
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = socket.Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息
recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
  • Send() :发送信息
string str = "hello";
byte[] a = Encoding.UTF8.GetBytes(str);
send = socket.Send(a, 0);

3.7 ReceiveFrom()与SendTo()

  • ReceiveFrom()
特性ReceiveReceiveFrom
连接要求需要已建立连接 (面向连接)无需预先连接 (无连接)
适用协议TCP UDP
来源获取无法获取发送方信息可获取发送方的端点信息
方法签名int Receive(byte[] buffer)int ReceiveFrom(byte[] buffer, ref EndPoint remoteEP)
典型用途可靠数据流传输数据报接收,特别是需要回复的场景
  • SendTo()
特性SendSendTo
连接要求需要已建立连接 (面向连接)无需预先连接 (无连接)
适用协议TCPUDP
目标指定在Connect时指定目标每次发送时指定目标
性能略高 (连接已建立)略低 (每次需解析地址)
可靠性高 (TCP保证送达和顺序)低 (UDP不保证送达和顺序)
方法签名Send(byte[] buffer)SendTo(byte[] buffer, EndPoint remoteEP)

3.8 Shutdown()和Close()

释放资源,有 Accept 释放和 Socket 的释放。

  • Shutdown()
    1. 向对方发送FIN包,启动TCP的正常关闭握手流程
    2. 非破坏性操作,Socket对象仍然有效
    3. 允许完成正在进行的数据传输
    4. 遵循TCP协议的四次挥手过程
    5. 对方应用会收到EOF(Receive返回0)
public void Shutdown (System.Net.Sockets.SocketShutdown how);

SocketShutdown:

描述
Send禁止对此发送Socket
Receive禁用对此接收Socket
Both禁用发送和接收对此Socket
  • Close()
    1. 破坏性操作,Socket对象不再可用
    2. 可能丢失发送/接收缓冲区中的数据
    3. 对方可能收到ConnectionReset错误
    4. 立即释放系统资源
  • 最佳实践
void SafeClose(Socket socket)
{
    try
    {
        // 1. 先优雅关闭通信通道
        if(socket.Connected)
        {
            socket.Shutdown(SocketShutdown.Both);
        }
        
        // 2. 设置linger选项确保数据发送
        socket.LingerState = new LingerOption(true, 5); // 等待5秒
        
        // 3. 最终释放资源
        socket.Close();
    }
    catch(Exception ex)
    {
        // 记录日志
        Debug.WriteLine($"关闭Socket异常: {ex.Message}");
        
        // 确保资源释放
        socket?.Close(); 
    }
}

4、IPAddress 和 IPEndPoint

4.1 IPAddress

用来处理IP地址、转换IP地址
IPAddress.Parse() 方法可以把以小数点隔分的十进制 IP 表示转化成 IPAddress 类。

IPAddress ip = IPAddress.Parse("127.0.0.1");//把ip地址字符串转换为IPAddress类型的实例

IPAddress提供4个只读字段:

  • Any 用于代表本地系统可用的任何IP地址
  • Broadcase用于代表本地网络的IP广播地址
  • Loopback用于代表系统的回送地址
  • None用于代表系统上没有网络接口

4.2 IPEndPoint

表示IPAddress对象与端口的绑定

IPAddress ip = IPAddress.Any;              //把ip地址字符串转换为IPAddress类型的实例
IPEndPoint ipe = new IPEndPoint(ip, 8000);//用指定的端口和ip初始化IPEndPoint类的新实例

相关文章:

  • 镜舟科技亮相 2025 中国移动云智算大会,展示数据湖仓一体创新方案
  • 面试之《websocket》
  • BusyBox 与 Toybox:嵌入式 Linux 的轻量工具集对比与解析
  • OCR API识别对比
  • AI比人脑更强,因为被植入思维模型【54】混沌与秩序思维模型
  • 浅层神经网络:从数学原理到实战应用的全面解析
  • 【C++初学】C++核心编程(一):内存管理和引用
  • 2025.4.9 华为机考 第1题-补丁版本升级
  • 学术分享:基于 ARCADE 数据集评估 Grounding DINO、YOLO 和 DINO 在血管狭窄检测中的效果
  • 机器学习十大算法全解析机器学习,作为人工智能的基石,涵盖了众多高效的算法。今天,我们就来深入探讨其中的十大核心算法!
  • C#的反射机制
  • vue3循环表单【以el-form组件为例】,如何校验所有表单,所有表单校验通过后提交
  • 如何使用AI辅助开发R语言
  • 软件项目交付体系-项目部署方案(Word原件)
  • mujoco graspnet 仿真项目的复现记录
  • AI 代码生成工具如何突破 Java 单元测试效能天花板?
  • iOS 上的内存管理是如何处理的?
  • Vue3+Vite+TypeScript+Element Plus开发-14.路由守卫
  • 重学 Android 自定义 View 系列(十二):环形SeekBar剖析
  • [蓝桥杯 2023 国 Python A] 整数变换
  • html5+css3网站模板/seo课程培训要多少钱
  • java做网站教程/百度广告推广收费标准
  • 西安网站推广招聘网/做关键词推广
  • 建设二手网站的建设费用包括/北京网站优化效果
  • 文成做网站/网站关键词优化系统
  • 深圳营销网站建设公司/360网站推广怎么做