C# Socket编程 笔记,Socket 详解,入门简单
目录
一,网络基础
二,Socket 对象
三,Bind() 绑定与 Connect() 连接
四,Listen() 监听请求连接 和 Accept() 接收连接请求
五,Receive() 与 Send()
六,释放资源
七,IPAddress 和 IPEndPoint
2019-2-14 晚上第一次写,后面会不断修改、更新。
文章按照 Socket 的 创建、连接、传输数据、释放资源的过程来写。给出方法、参数的详细信息。
一,网络基础
说到 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 官方文档地址
三,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, ))
你将在在本地创建 IPEndPoint 对象,拥有此 ip:post 的访问权限。目的是绑定本地机器的某个端口,所有经过此端口的数据就归你管了。
Connect()
与远程主机建立连接。Connect() 有四个重载方法,不必关注,只需知道,必需提供 IP 和 Post 两个值。
使用方法
IPAddress iP = IPAddress.Parse("127.0.0.1");
IPEndPoint iPEndPoint = new IPEndPoint(iP, );
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(); //开始监听
Accept()
Accept() 以同步方式监听套接字,在连接请求队列中提取第一个挂起的连接请求,然后创建并返回一个新的 Socket 对象。
代码示例
//创建终结点(EndPoint)
IPAddress ip = IPAddress.Any;
IPEndPoint ipe = new IPEndPoint(ip, ); //创建 socket 并开始监听
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(ipe);
serverSocket.Listen(1);//开始监听 //接受到client连接,为此连接建立新的socket,并接受信息
Socket temp = serverSocket.Accept();//为新建连接创建新的socket
//关闭连接
temp.Close();
注意的是,每次建立连接是一个 Accept() 对象,如果你要进行 服务器-客户端互相通讯,应使用同一个 Accept() 对象。每个 Accept 对象都是 从客户端请求建立开始的,期间只要使用同一个 Accept 对象,都可以进行数据传输。
五,Receive() 与 Send()
- Receive() 接收信息
- Send() 发送信息
在服务端和客户端都使用这两个方法。
Receive()
使用示例
string recvStr = "";
byte[] recvBytes = new byte[];
int bytes;
bytes = temp.Receive(recvBytes, recvBytes.Length, );//从客户端接受信息
recvStr += Encoding.ASCII.GetString(recvBytes, , 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, );
发送/接收 都是使用 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()
会直接释放资源,Accept 和 Socket 对象都可以使用。使用后对象将彻底释放。
七,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, );//用指定的端口和ip初始化IPEndPoint类的新实例
上面的代码,创建一个监控点,端口是 8000,对象是 本地所有IP。
另外,此类能够获取查看端口的值范围,除此外,此类没有太大意义。
Microsoft 文档地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.net.ipendpoint?view=netframework-4.7.2
SocketType
C# Socket编程 笔记,Socket 详解,入门简单的更多相关文章
- C++游戏服务器编程笔记 IP详解
C++游戏服务器编程笔记 IP详解 IP详解 INTERNET的历史 上世纪60年底起源于美国 1992年,Internet上的主机超过了100万台 现在已经是现代文明人的必需品 TCP/IP的 ...
- Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制
Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...
- C# Socket编程笔记(转)
C# Socket编程笔记 http://www.cnblogs.com/stg609/archive/2008/11/15/1333889.html TCP Socket:Server 端连接步骤: ...
- Java网络编程和NIO详解6:Linux epoll实现原理详解
Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...
- Redis详解入门篇
Redis详解入门篇 [本教程目录] 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介 ...
- Java网络编程和NIO详解开篇:Java网络编程基础
Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...
- Java网络编程和NIO详解8:浅析mmap和Direct Buffer
Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ...
- Java网络编程和NIO详解9:基于NIO的网络编程框架Netty
Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...
- Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...
- Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO
Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...
随机推荐
- Markdown编辑器-图形化
SELECT * from yffee_favourable_detail yfd LEFT JOIN yffee_favourable yf on yfd.minor_id = yf.major_i ...
- 设计模式学习--面向对象的5条设计原则之依赖倒置原则--DIP
一.DIP简介(DIP--Dependency Inversion Principle): 1.高层模块不应该依赖于低层模块,二者都应该依赖于抽象.2.抽象不应该依赖于细节,细节应该依赖于抽象. ...
- springcloud-feign的hystrix支持
关于hystrix的介绍,可以看我的上篇博客:springcloud-断路器hystrixs 本文主要介绍在feign中,如何使用hystrix 1.pom依赖 <dependency> ...
- @Resource和@Autowired区别
@Resource和@Autowired都是做bean的注入时使用 历史: @Autowired 属于Spring的注解 org.springframework.beans.facto ...
- [PHP] Yaf框架的简单安装使用
PHP开发组鸟哥惠新宸开发的php扩展框架 安装 windows下载扩展:https://pecl.php.net/package/yaf/2.2.9/windows 根据自己的电脑系统和php的版本 ...
- 【转】JUC下面线程池介绍
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
- windows多线程窗口程序设计
掌握windows基于消息驱动的窗口应用程序设计的基本方法,掌握窗口程序资源的概念与设计,掌握常用的消息的程序处理方法,掌握文字图形输出相关函数编程.掌握设计的基本方法(选项),掌握时钟消息设计动画程 ...
- win10 安装 oracle 11g 时遇到 [INS-13001] 环境不满足最低要求 的问题
前言:自己系统上安装 oracle 时报错,故记录下来. 环境: win10 x64 oracle 11g 安装包 出错: 解决方案:同 https://www.cnblogs.com/yuxiaol ...
- HDU2181(KB2-C)
哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- echarts 点亮中国插件研究
echarts 真的是个神奇的东西,最近做了一个需要点亮中国的移动端项目,前期就怎样点亮中国做了调研,发现微博当初炫酷的点亮效果就是用echarts做的,于是研究了一下. 一连研究了一堆demo,不管 ...