开放的编程资料库

当前位置:我爱分享网 > C#教程 > 正文

C#套接字

在本文中,我们展示了如何在C#中使用套接字。

网络协议

TCP/IP是设备用来通过Internet和大多数本地网络进行通信的一套协议。TCP更可靠,具有广泛的错误检查,并且需要更多资源。它由HTTP、SMTP或FTP等服务使用。UDP的可靠性低得多,错误检查有限,并且需要的资源较少。它被VoIP等服务使用。

套接字

在编程中,套接字是网络上运行的两个程序之间通信的端点。在.NET中,Socket类为网络通信提供了一组丰富的方法和属性。它允许我们执行同步和异步数据传输。

C#UDP套接字示例

UDP是一种通过网络传输独立数据包的通信协议,不保证到达且不保证交付顺序。使用UDP的一项服务是每日报价(QOTD)。

using System.Text;
using System.Net;
using System.Net.Sockets;

string server = "djxmmx.net";
int port = 17;

byte[] data = new byte[0];
IPHostEntry hostEntry = Dns.GetHostEntry(server);

var ipe = new IPEndPoint(hostEntry.AddressList[0], port);
using var socket = new Socket(AddressFamily.InterNetworkV6,
    SocketType.Dgram, ProtocolType.Udp);

socket.ReceiveTimeout = 5000;
socket.SendTimeout = 2000;

socket.SendTo(data, ipe);

byte[] data2 = new byte[1024];
EndPoint remote = (EndPoint)ipe;

int n = socket.ReceiveFrom(data2, ref remote);

Console.WriteLine($"Message size: {n}");
Console.WriteLine($"Messaged received from: {remote}");
Console.WriteLine(Encoding.ASCII.GetString(data2, 0, n));

该程序创建一个连接到QOTD服务的客户端程序。

string server = "djxmmx.net";
int port = 17;

这是可以找到QOTD服务的服务器和端口。请注意,此类服务通常是短暂的。

byte[] data = new byte[0];

我们向服务器发送一条空消息。

IPHostEntry hostEntry = Dns.GetHostEntry(server);

Dns.GetHostEntry将主机名或IP地址解析为IPHostEntry实例。这是Internet主机地址信息的.NET容器类。

using var socket = new Socket(AddressFamily.InterNetworkV6,
    SocketType.Dgram, ProtocolType.Udp);

Socket被创建。我们传递寻址方案、套接字类型和协议类型。

socket.ReceiveTimeout = 5000;
socket.SendTimeout = 2000;

我们设置接收发送数据的超时。

socket.SendTo(data, ipe);

我们使用SendTo将数据(在本例中为空)发送到端点。

byte[] data2 = new byte[1024];

我们将在此处存储响应消息。

int n = socket.ReceiveFrom(data2, ref remote);

ReceiveFrom方法将数据报接收到数据缓冲区中并存储端点。它返回接收到的字节数。

Console.WriteLine($"Message size: {n}");
Console.WriteLine($"Messaged received from: {remote}");
Console.WriteLine(Encoding.ASCII.GetString(data2, 0, n));

我们打印消息大小、删除地址和接收到的数据。

$ dotnet run
Message size: 73
Messaged received from: [2001:470:e312:10::10]:17
"Take what you can, give nothing back..."
         - Pirates Of The Caribbean

C#套接字HTTPHEAD请求

HEAD请求是没有消息正文的HTTPGET请求。请求/响应的标头包含元数据,例如HTTP协议版本或内容类型。

using System.Text;
using System.Net;
using System.Net.Sockets;

string server = "webcode.me";
int port = 80;

var request = "HEAD / HTTP/1.0\r\n\r\n";

byte[] bReq = Encoding.ASCII.GetBytes(request);
byte[] bRec = new byte[8192];

IPHostEntry hostEntry = Dns.GetHostEntry(server);

var ipe = new IPEndPoint(hostEntry.AddressList[0], port);
using var socket = new Socket(AddressFamily.InterNetwork,
    SocketType.Stream, ProtocolType.Tcp);

socket.Connect(ipe);

if (socket.Connected)
{
    Console.WriteLine("Connection established");
}
else
{
    Console.WriteLine("Connection failed");
    return;
}

socket.Send(bReq, bReq.Length, 0);

int n = socket.Receive(bRec, bRec.Length, 0);
Console.WriteLine(Encoding.ASCII.GetString(bRec, 0, n));

在代码示例中,我们向webcode.me发送了一个HEAD请求。

string server = "webcode.me";
int port = 80;

这是服务器名称和端口号。

string request = "HEAD / HTTP/1.0\r\n\r\n";

head请求是通过HEAD命令发出的,后跟资源URL和HTTP协议版本。请注意,\r\n字符是通信过程的必需部分。RFC7231文档中描述了详细信息。

using var socket = new Socket(AddressFamily.InterNetwork,
    SocketType.Stream, ProtocolType.Tcp);

HTTP协议(​​HTTP/0.9到HTTP/2)是基于TCP的。

if (socket.Connected)

我们可以通过Connected属性检查我们是否连接成功。

socket.Send(bReq, bReq.Length, 0);

我们使用Send发送数据。

int n = socket.Receive(bRec, bRec.Length, 0);
Console.WriteLine(Encoding.ASCII.GetString(bRec, 0, n));

我们接收并打印标题数据。

$ dotnet run
Connection established
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Wed, 21 Sep 2022 17:43:39 GMT
Content-Type: text/html
Content-Length: 394
Last-Modified: Sun, 23 Jan 2022 10:39:25 GMT
Connection: close
ETag: "61ed305d-18a"
Accept-Ranges: bytes

C#套接字HTTPGET请求

HTTPGET方法请求指定资源的表示。使用GET的请求应该只检索数据。

using System.Text;
using System.Net;
using System.Net.Sockets;

string server = "webcode.me";
int port = 80;

string request = $"GET / HTTP/1.1\r\nHost: {server} \r\nConnection: Close\r\n\r\n";

Byte[] bReq = Encoding.ASCII.GetBytes(request);
Byte[] bRec = new Byte[1024];

IPHostEntry hostEntry = Dns.GetHostEntry(server);

var ipe = new IPEndPoint(hostEntry.AddressList[0], port);
using var socket = new Socket(AddressFamily.InterNetwork,
    SocketType.Stream, ProtocolType.Tcp);

socket.Connect(ipe);

if (socket.Connected)
{
    Console.WriteLine("Connection established");
}
else
{
    Console.WriteLine("Connection failed");
    return;
}

socket.Send(bReq, bReq.Length, 0);

int n = 0;
var sb = new StringBuilder();

do
{
    n = socket.Receive(bRec, bRec.Length, 0);
    sb.Append(Encoding.ASCII.GetString(bRec, 0, n));
}
while (n > 0);

Console.WriteLine(sb);

该示例使用GET请求读取webcode.me的主页。

string request = $"GET / HTTP/1.1\r\nHost: {server} \r\nConnection: Close\r\n\r\n";

我们向套接字写入一个简单的GET请求。

do
{
    n = socket.Receive(bRec, bRec.Length, 0);
    sb.Append(Encoding.ASCII.GetString(bRec, 0, n));
}
while (n > 0);

由于我们无法确定响应的大小,因此我们使用do/while循环来分块读取响应。

在本文中,我们使用了C#中的套接字。

列出所有C#教程。

未经允许不得转载:我爱分享网 » C#套接字

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏