C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨
简介
本文主要介绍使用C#进行Socket网络编程时,涉及到的TCP/IP协议中的各个层次模型、端口以及报文等内容,并提供两个基本示例进行说明。
TCP/IP协议层次模型
TCP/IP协议是网络通信的基础,它将网络通信分为许多层,每一层负责不同的任务。这些层从下往上分别是:物理层、数据链路层、网络层、传输层、应用层。
下面是这些层级及其任务的简单描述:
-
物理层:定义网络的物理布局以及底层数据传输,如电流、电压等。
-
数据链路层:负责在物理层上,根据MAC地址,完成节点之间的通信;将从网络层接收到的IP数据报组成帧,在物理层上传输。
-
网络层:为数据通信提供路由、寻址、分包等服务,负责网间的数据传输,通过IP地址来唯一标识不同的设备。
-
传输层:为上层协议提供可靠的端到端通信,并提供差错检测和重传等机制,常用的协议有TCP和UDP。
-
应用层:我们编写的程序所用的协议,如HTTP、FTP、SMTP等。
Socket端口
在TCP/IP协议中,每个设备都有一个IP地址,但这个地址只是标识了设备,而没有标识一个应用程序。为了实现设备与设备之间的通信,需要一个能够分辨应用程序的标识,这个标识就是端口。
端口是一个16位的整数,范围从0到65535,其中0到1023是被保留的,一般作为著名的端口使用,如HTTP协议的80端口、FTP协议的21端口等;1024到65535是动态端口,由操作系统分配给应用程序使用。
Socket报文
Socket报文是进行网络通信时所传输的数据单元,可以理解为一段二进制数据流。在TCP/IP协议中,Socket报文主要有三部分组成:
-
IP头部:包含了发送方和接收方的IP地址,IP协议版本,以及一些与IP协议相关的控制字段。
-
TCP头部:包含了TCP协议的各种控制字段,如端口号、序列号和确认号等。
-
数据段:将应用程序的数据流发送给TCP层,并分段传输。
示例一:Socket服务端及其客户端
下面是一个简单的Socket服务端和客户端程序实例,适用于 TCP/IP 协议:
- 服务端:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Program
{
static void Main(string[] args)
{
try
{
IPAddress ipAd = IPAddress.Parse("127.0.0.1");
TcpListener myList=new TcpListener(ipAd, 8001);
myList.Start();
Console.WriteLine("等待客户端连接......");
while(true)
{
TcpClient client = myList.AcceptTcpClient();
Console.WriteLine("客户端已连接...");
NetworkStream netStream = client.GetStream();
byte[] bytes = new byte[1024];
int i = netStream.Read(bytes, 0, bytes.Length);
string data = Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("收到客户端消息: {0}", data);
string response = "谢谢连接我们,再见!";
byte[] message = Encoding.ASCII.GetBytes(response);
netStream.Write(message, 0, message.Length);
client.Close();
}
myList.Stop();
}
catch (Exception e)
{
Console.WriteLine("出现异常: {0}", e.ToString());
}
}
}
- 客户端:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Program
{
static void Main(string[] args)
{
try
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("向服务端发送连接请求......");
tcpclnt.Connect("127.0.0.1", 8001);
byte[] bytes = Encoding.ASCII.GetBytes("客户端发送的数据......");
NetworkStream stream = tcpclnt.GetStream();
stream.Write(bytes, 0, bytes.Length);
Console.WriteLine("向服务端发送消息: {0}", Encoding.ASCII.GetString(bytes, 0, bytes.Length));
bytes = new byte[1024];
int i = stream.Read(bytes, 0, bytes.Length);
Console.WriteLine("从服务端收到消息: {0}", Encoding.ASCII.GetString(bytes, 0, i));
tcpclnt.Close();
}
catch (Exception e)
{
Console.WriteLine("出现异常: {0}", e.ToString());
}
}
}
示例二:Socket异步通信
下面的示例演示一个异步的Socket服务器,它可以同时处理多个请求。
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Program
{
static int port = 8001;
static TcpListener listener = new TcpListener(IPAddress.Any, port);
static void Main(string[] args)
{
listener.Start();
Console.WriteLine("等待客户端连接...");
var state = new StateObject();
while(true)
{
listener.BeginAcceptTcpClient(AcceptTcpClientCallback, state);
Console.WriteLine("正在等待下一个客户端连接...");
}
}
static void AcceptTcpClientCallback(IAsyncResult ar)
{
Console.WriteLine("客户端连接成功...");
var state = (StateObject)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
state.Client = client;
NetworkStream stream = state.Client.GetStream();
byte[] buffer = new byte[1024];
stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, state);
}
static void ReadCallback(IAsyncResult ar)
{
var state = (StateObject)ar.AsyncState;
NetworkStream stream = state.Client.GetStream();
int length = stream.EndRead(ar);
string data = Encoding.ASCII.GetString(state.Buffer, 0, length);
Console.WriteLine("收到客户端消息:{0}", data);
byte[] responseBytes = Encoding.ASCII.GetBytes("谢谢友善的客户端!");
stream.BeginWrite(responseBytes, 0, responseBytes.Length, WriteCallback, state);
}
static void WriteCallback(IAsyncResult ar)
{
var state = (StateObject)ar.AsyncState;
NetworkStream stream = state.Client.GetStream();
stream.EndWrite(ar);
stream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallback, state);
}
}
class StateObject
{
public TcpClient Client { get; set; }
public byte[] Buffer = new byte[1024];
}
上面的代码中,异步通信主要通过BeginXXX和EndXXX方法进行,回调函数则负责对数据进行处理和响应数据。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨 - Python技术站