C#Socket编程笔记,Socket 详解,入门简单

简介: 目录一,网络基础二,Socket 对象三,Bind() 绑定与 Connect() 连接四,Listen() 监听请求连接 和 Accept() 接收连接请求五,Receive() 与 Send()六,释放资源七,IPAddress 和 IPEndPoint

文章按照 Socket 的 创建、连接、传输数据、释放资源的过程来写。给出方法、参数的详细信息。


微信图片_20220501145510.gif


一,网络基础


说到 Socket,需要学习一下TCP/IP的知识,了解一下OSI 网络模。

推荐别人的文章,可以很快地了解这些。

https://www.cnblogs.com/ysyn/p/3399351.html

https://www.cnblogs.com/wangcq/p/3520400.html


二,Socket 对象


无论是服务器还是客户端,都要创建一个 SOCKET 对象,创建方法一致。

以下是常见的 Socket 对象创建实例


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


其有三个构造函数


public Socket(SocketInformation socketInformation);


public Socket(SocketType socketType, ProtocolType protocolType);


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


第一个构造函数,SocketInformation 对象保存的是


Socket(SocketType, ProtocolType)


实质上跟第二个构造函数是一样的。就好像你可以直接把( 一个苹果 , 一个梨)直接放进篮子,也可以先给 水果包装好 再放进篮子里。

下面将解释所有参数的意义。


SocketType

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

TCP 用主机的IP地址加上主机上的端口号作为 TCP 连接的端点,这种端点就叫做套接字(socket)或插口。 套接字用(IP地址:端口号)表示。

SocketType enum 类型,其字段如下


 

SocketType

  值 

对应的ProtocolType

描述

Unknown

-1

  Unknown              

指定未知的 Socket 类型。

Stream(使用字节流)

1

Tcp

支持可靠、双向、基于连接的字节流

Dgram(使用数据报)

2

Udp

面向无连接

Raw

3

Icmp、lgmp

支持对基础传输协议的访问

Rdm

4

 

支持无连接、面向消息、以可靠方式发送的消息,

并保留数据中的消息边界

Seqpacket

5

 

在网络上提供排序字节流的面向连接且可靠的双向传输


如需了解更详细的资料,请查阅Microsoft文档

地址: https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.sockettype?view=netframework-4.7.2


ProtocolType

表示协议类型,是一个 enum 类型。

其所有字段如下


协议类型

描述

Ggp 3

网关到网关协议。

Icmp 1

Internet 控制消息协议。

IcmpV6 58

IPv6 的 Internet 控制消息协议。

Idp 22

Internet 数据报协议。

Igmp 2

Internet 组管理协议。

IP 0

Internet 协议。

IPSecAuthenticationHeader 51

IPv6 身份验证标头。有关详细信息,请参阅https://www.ietf.org 上的 RFC 2292,第 2.2.1 节。

IPSecEncapsulatingSecurityPayload 50

IPv6 封装安全负载标头。

IPv4 4

Internet 协议版本 4。

IPv6 41

Internet 协议版本 6 (IPv6)。

IPv6DestinationOptions 60

IPv6 目标选项标头。

IPv6FragmentHeader 44

IPv6 片段标头。

IPv6HopByHopOptions 0

IPv6 逐跳选项标头。

IPv6NoNextHeader 59

IPv6 无下一个标头。

IPv6RoutingHeader 43

IPv6 路由标头。

Ipx 1000

Internet 数据包交换协议。

ND 77

网络磁盘协议(非正式)。

Pup 12

PARC 通用数据包协议。

Raw 255

原始 IP 数据包协议。

Spx 1256

顺序包交换协议。

SpxII 1257

顺序包交换版本 2 协议。

Tcp 6

传输控制协议。

Udp 17

用户数据报协议。

Unknown -1

未知的协议。

Unspecified 0

未指定的协议。


AddressFamily

表示使用的网络寻址方案,是一个 enum 类型。


地址类型

描述

AppleTalk 16

AppleTalk 地址。

Atm 22

本机 ATM 服务地址。

Banyan 21

Banyan 地址。

Ccitt 10

CCITT 协议(如 X.25)的地址。

Chaos 5

MIT CHAOS 协议的地址。

Cluster 24

Microsoft 群集产品的地址。

DataKit 9

Datakit 协议的地址。

DataLink 13

直接数据链接接口地址。

DecNet 12

DECnet 地址。

Ecma 8

欧洲计算机制造商协会 (ECMA) 地址。

FireFox 19

FireFox 地址。

HyperChannel 15

NSC Hyperchannel 地址。

Ieee12844 25

IEEE 1284.4 工作组地址。

ImpLink 3

ARPANET IMP 地址。

InterNetwork 2

IP 版本 4 的地址。

InterNetworkV6 23

IP 版本 6 的地址。

Ipx 6

IPX 或 SPX 地址。

Irda 26

IrDA 地址。

Iso 7

ISO 协议的地址。

Lat 14

LAT 地址。

Max 29

MAX 地址。

NetBios 17

NetBios 地址。

NetworkDesigners 28

支持网络设计器 OSI 网关的协议的地址。

NS 6

Xerox NS 协议的地址。

Osi 7

OSI 协议的地址。

Pup 4

PUP 协议的地址。

Sna 11

IBM SNA 地址。

Unix 1

Unix 本地到主机地址。

Unknown -1

未知的地址族。

Unspecified 0

未指定的地址族。

VoiceView 18

VoiceView 地址。


Socket 官方文档地址

https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.socket?redirectedfrom=MSDN&view=netframework-4.7.2


三,Bind() 绑定与 Connect() 连接


Bind() 用于绑定 IPEndPoint 对象,在服务端使用。

Connect() 在客户端使用,用于连接服务端。

创建 Socket 对象后,接着 绑定本地Socket / 连接服务端

Bind()


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");
        //上面不重要,看下面
    //IPEndPoint iPEndPoint = new IPEndPoint(iP, 2300);
    //serverSocket.Bind(iPEndPoint);
serverSocket.Bind(new IPEndPoint(iP, 2300))


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

 

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


四,Listen() 监听请求连接 和 Accept() 接收连接请求


Listen()

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


public void Listen (int backlog);


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

示例


serverSocket.Listen(10);    //开始监听


Accept()

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


//关闭连接
temp.Close();

 

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


五,Receive() 与 Send()


  • Receive() 接收信息
  • Send() 发送信息

在服务端和客户端都使用这两个方法。

Receive()

使用示例


string recvStr = "";
            byte[] recvBytes = new byte[1024];
            int bytes;
            bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息
            recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);


直接从微软那复制来的。


Receive(Byte[], Int32, Int32, SocketFlags, SocketError)

使用指定的 Socket,从绑定的 SocketFlags 接收数据,将数据存入接收缓冲区。

Receive(Byte[], Int32, Int32, SocketFlags)

使用指定的 Socket,从绑定的 SocketFlags 接收指定的字节数,存入接收缓冲区的指定偏移量位置。

Receive(IList<ArraySegment<Byte>>, SocketFlags, SocketError)

使用指定的 Socket,从绑定的 SocketFlags 接收数据,将数据存入接收缓冲区列表中。

Receive(Byte[], Int32, SocketFlags)

使用指定的 Socket,从绑定的 SocketFlags 接收指定字节数的数据,并将数据存入接收缓冲区。

Receive(Byte[], SocketFlags)

使用指定的 Socket,从绑定的 SocketFlags 接收数据,将数据存入接收缓冲区。

Receive(IList<ArraySegment<Byte>>, SocketFlags)

使用指定的 Socket,从绑定的 SocketFlags 接收数据,将数据存入接收缓冲区列表中。

Receive(IList<ArraySegment<Byte>>)

从绑定的 Socket 接收数据,将数据存入接收缓冲区列表中。

Receive(Byte[])

从绑定的 Socket 套接字接收数据,将数据存入接收缓冲区。


参数

Byte[] buffer

Byte 类型的数组,它是存储接收到的数据的位置。

Int32 offset

buffer 参数中的位置,用于存储所接收的数据。

Int32 size

要接收的字节数。

SocketFlags socketFlags

SocketFlags 值的按位组合。

SocketError errorCode

一个 SocketError 对象,它存储套接字错误。

socketFlags 默认值为 0 None ,笔者没有搞懂 socketFlags 的应用场景。

返回

返回已成功读取的字节数。

Send()

send()跟Receive()用法相似,

示例代码如下


string str = "hello";
            byte[] a = Encoding.UTF8.GetBytes(str);
            send = socket.Send(a, 0);

 

发送/接收 都是使用 byte[] 字节流,所以接收时要进行转换。


六,释放资源


Accept 释放和 Socket 的释放。

Accept 是连接对象,一个 Socket 可能有数十个 Accept 连接。

使用 Shutdown( ) 方法可以 禁止 Asscpt 对象的操作(禁用某个 Socket 对象 的发送和接收)。


public void Shutdown (System.Net.Sockets.SocketShutdown how);


SocketShutdown 是一个 enum 类型。

实例

           

temp.Shutdown(SocketShutdown.Receive);
            //禁止接收


使用 描述
发送 Send 禁止对此发送Socket
接收 Receive 禁用对此接收Socket
消息和传送 Both 禁用发送和接收对此Socket


close()

会直接释放资源,AcceptSocket 对象都可以使用。使用后对象将彻底释放。


七,IPAddress 和 IPEndPoint


//引入
using System.Net;


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用于代表系统上没有网络接口

关于其类型的使用和全部方法、构造函数等,请查看文档Microsoft文档。

地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.net.ipaddress?view=netframework-4.7.2

IPEndPoint 表示IPAddress对象与端口的绑定

         

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


上面的代码,创建一个监控点,端口是 8000,对象是 本地所有IP

另外,此类能够获取查看端口的值范围,除此外,此类没有太大意义。

Microsoft 文档地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.net.ipendpoint?view=netframework-4.7.2

 

SocketType

相关文章
|
12天前
|
设计模式 C# 开发者
C#设计模式入门实战教程
C#设计模式入门实战教程
|
1天前
|
安全 数据库连接 API
C#一分钟浅谈:多线程编程入门
在现代软件开发中,多线程编程对于提升程序响应性和执行效率至关重要。本文从基础概念入手,详细探讨了C#中的多线程技术,包括线程创建、管理及常见问题的解决策略,如线程安全、死锁和资源泄露等,并通过具体示例帮助读者理解和应用这些技巧,适合初学者快速掌握C#多线程编程。
10 0
|
12天前
|
开发框架 .NET Java
C#/.NET/.NET Core自学入门指南
C#/.NET/.NET Core自学入门指南
|
19天前
|
图形学 C# 开发者
全面掌握Unity游戏开发核心技术:C#脚本编程从入门到精通——详解生命周期方法、事件处理与面向对象设计,助你打造高效稳定的互动娱乐体验
【8月更文挑战第31天】Unity 是一款强大的游戏开发平台,支持多种编程语言,其中 C# 最为常用。本文介绍 C# 在 Unity 中的应用,涵盖脚本生命周期、常用函数、事件处理及面向对象编程等核心概念。通过具体示例,展示如何编写有效的 C# 脚本,包括 Start、Update 和 LateUpdate 等生命周期方法,以及碰撞检测和类继承等高级技巧,帮助开发者掌握 Unity 脚本编程基础,提升游戏开发效率。
32 0
|
19天前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
42 0
|
19天前
|
开发者 iOS开发 C#
Uno Platform 入门超详细指南:从零开始教你打造兼容 Web、Windows、iOS 和 Android 的跨平台应用,轻松掌握 XAML 与 C# 开发技巧,快速上手示例代码助你迈出第一步
【8月更文挑战第31天】Uno Platform 是一个基于 Microsoft .NET 的开源框架,支持使用 C# 和 XAML 构建跨平台应用,适用于 Web(WebAssembly)、Windows、Linux、macOS、iOS 和 Android。它允许开发者共享几乎全部的业务逻辑和 UI 代码,同时保持原生性能。选择 Uno Platform 可以统一开发体验,减少代码重复,降低开发成本。安装时需先配置好 Visual Studio 或 Visual Studio for Mac,并通过 NuGet 或官网下载工具包。
24 0
|
2月前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
27 4
|
2月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
50 2
|
2月前
|
网络协议 程序员 视频直播
|
2月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
22 3