服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#中的Socket编程详解

C#中的Socket编程详解

2022-12-20 14:42痴者工良 C#

本文详细讲解了C#中的Socket编程,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

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

C#中的Socket编程详解

一,网络基础

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

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

http://www.tuohang.net/article/259906.html

http://www.tuohang.net/article/258328.html

二,Socket 对象

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

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

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

其有三个构造函数

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

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

?
1
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 类型。

其所有字段如下

SocketType

  值 

对应的ProtocolType

描述

Unknown

-1

  Unknown              

指定未知的 Socket 类型。

Stream(使用字节流)

1

Tcp

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

Dgram(使用数据报)

2

Udp

面向无连接

Raw

3

Icmp、lgmp

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

Rdm

4

 

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

并保留数据中的消息边界

Seqpacket

5

 

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

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

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

使用方法

?
1
2
3
4
5
6
7
8
    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 两个值。

使用方法

?
1
2
3
4
5
6
    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()

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

?
1
public void Listen (int backlog);

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

示例

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

Accept()

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

代码示例

?
1
2
3
4
5
6
7
8
9
10
11
//创建终结点(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
?
1
2
//关闭连接
temp.Close();

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

五,Receive() 与 Send()

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

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

Receive()

使用示例

?
1
2
3
4
5
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()用法相似,

示例代码如下

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

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

六,释放资源

有 Accept 释放和 Socket 的释放。

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

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

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

SocketShutdown 是一个 enum 类型。

实例

?
1
2
temp.Shutdown(SocketShutdown.Receive);
            //禁止接收
使用 描述
发送 Send 禁止对此发送Socket
接收 Receive 禁用对此接收Socket
消息和传送 Both 禁用发送和接收对此Socket

close()

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

七,IPAddress 和IPEndPoint

?
1
2
//引入
using System.Net;

IPAddress 用来处理IP地址、转换IP地址

IPAddress.Parse() 方法可以把以小数点隔分的十进制 IP 表示转化成 IPAddress 类。

?
1
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对象与端口的绑定

?
1
2
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

到此这篇关于C#中的Socket编程详解的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/whuanle/p/10375526.html

延伸 · 阅读

精彩推荐
  • C#C#使用FileSystemWatcher控件实现的文件监控功能示例

    C#使用FileSystemWatcher控件实现的文件监控功能示例

    这篇文章主要介绍了C#使用FileSystemWatcher控件实现的文件监控功能,结合实例形式分析了C# FileSystemWatcher组件的功能及监控文件更改情况的具体使用技巧,需要...

    dodo-yufan8252022-01-19
  • C#C#算法之无重复字符的最长子串

    C#算法之无重复字符的最长子串

    这篇文章介绍了C#算法之无重复字符的最长子串,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考...

    痴者工良6182022-12-20
  • C#C#基础知识之GetType与typeof的区别小结

    C#基础知识之GetType与typeof的区别小结

    在比较对象时,需要了解他们的类型,才能决定他们的值是否能比较。所有的类都从System.Object中继承了GetType()方法,常常与typeo()运算符一起使用。这篇文...

    陈大宝5632022-11-21
  • C#C#8.0 中开启默认接口实现方法

    C#8.0 中开启默认接口实现方法

    这篇文章主要介绍了C#8.0 中开启默认接口实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧的相关资料...

    walterlv7212022-07-22
  • C#C#怎么实现手机短信发送功能

    C#怎么实现手机短信发送功能

    为了个人信息的安全,很多网站都有短信发送的功能,究竟是怎么实现的呢?对于个人站长来说的话,通过使用sms短信通知api接口相对比较简单,下面小编...

    J灬叶小超7142021-11-05
  • C#C#编程获取资源文件中图片的方法

    C#编程获取资源文件中图片的方法

    这篇文章主要介绍了C#编程获取资源文件中图片的方法,涉及C#针对项目中资源文件操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    我心依旧11972021-10-22
  • C#C#多线程编程详解

    C#多线程编程详解

    C#提供了丰富的多线程操作,为编程带来了极大的便利,但如果使用不当也会带来各种各样的麻烦。本篇文章主要介绍了C#多线程,有需要的可以了解一下。...

    阿凡卢5352021-12-10
  • C#C# WebApi 接口传参详解

    C# WebApi 接口传参详解

    这篇文章主要介绍了C# WebApi 接口传参详解,本篇打算通过get、post、put、delete四种请求方式分别谈谈基础类型(包括int/string/datetime等)、实体、数组等类型...

    懒得安分9972022-02-25