VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 计算机网络基础(OSI七层模型、TCP/IP四层模型)

第一部分:网络编程基础
第1章 网络编程核心概念
1.1 计算机网络基础(OSI七层模型、TCP/IP四层模型)
一、为什么要学网络模型?
之前做TCP服务器时,客户端连接后发送数据总是乱序,排查了3天才发现是路由器的分片重组出了问题——如果早懂网络模型,就能立刻定位到是传输层以下的问题,不用在应用层瞎折腾。网络模型是网络编程的“地图”,不懂模型就像开车不认路,全靠瞎vb.net教程C#教程python教程SQL教程access 2010教程撞。这节就带你把OSI七层模型和TCP/IP四层模型掰碎了讲,结合C#代码实战,让你不仅“背下来”,更能“用起来”。
二、OSI七层模型:从物理网线到应用程序
OSI(Open Systems Interconnection)是国际标准化组织制定的网络通信标准,把网络通信分成7层,每层只做一件事,上层依赖下层,下层为上层提供服务。

层级 名称 核心功能 常用协议/设备 类比生活场景
7 应用层 直接为用户提供服务 HTTP、HTTPS、FTP、SMTP 快递收件人(用户)
6 表示层 数据格式转换、加密解密 SSL/TLS、JPEG、JSON 快递打包/拆包(格式转换)
5 会话层 建立、管理、终止会话 RPC、NetBIOS 快递取件码(会话标识)
4 传输层 端到端的可靠传输 TCP、UDP 快递员(负责点对点配送)
3 网络层 路由选择、跨网络传输 IP、ICMP、OSPF 快递中转站(路由转发)
2 数据链路层 物理地址寻址、帧同步 Ethernet、ARP、PPP 快递分拣中心(按地址分拣)
1 物理层 二进制数据的物理传输 网线、光纤、WiFi 快递运输车(物理介质)
  1. 物理层:电信号的“搬运工”
    核心功能:把二进制数据(0和1)转换成电信号、光信号或无线信号,通过物理介质(网线、光纤、WiFi)传输。
    你需要知道:
    物理层不关心数据含义,只负责“搬砖”;
    常见物理介质:双绞线(网线)、光纤、WiFi(2.4G/5G);
    常见标准:以太网(Ethernet)、WiFi 802.11。
    C#实战:检测物理网络状态
    csharp
	using System.Net.NetworkInformation;
	
	// 获取所有网络接口
	var interfaces = NetworkInterface.GetAllNetworkInterfaces();
	foreach (var iface in interfaces)
	{
	// 只显示物理网络接口(排除虚拟网卡)
	if (iface.NetworkInterfaceType != NetworkInterfaceType.Loopback && 
	iface.OperationalStatus == OperationalStatus.Up)
	{
	Console.WriteLine($"网卡名称:{iface.Name}");
	Console.WriteLine($"物理地址:{iface.GetPhysicalAddress()}"); // 数据链路层MAC地址
	Console.WriteLine($"网络类型:{iface.NetworkInterfaceType}");
	Console.WriteLine($"状态:{iface.OperationalStatus}");
	Console.WriteLine("------------------------");
	}
	}

代码逐行讲:
1.NetworkInterface.GetAllNetworkInterfaces():获取系统所有网络接口,包括物理网卡、虚拟网卡、Loopback网卡;
2.NetworkInterfaceType.Loopback:排除回环网卡(127.0.0.1),只看物理网络;
3.OperationalStatus.Up:只显示已连接的网络接口;
4.GetPhysicalAddress():获取数据链路层的MAC地址(物理地址),这是物理层和数据链路层的标识。
2. 数据链路层:给数据“贴地址标签”
核心功能:把物理层的二进制数据封装成“帧”,添加源MAC地址和目标MAC地址,实现同一局域网内的通信。
你需要知道:
MAC地址:每个网卡的唯一标识,由12位十六进制数组成(如00-1A-2B-3C-4D-5E);
ARP协议:通过IP地址查找MAC地址(地址解析协议);
PPP协议:拨号上网的链路层协议(如ADSL)。
C#实战:获取MAC地址与IP地址映射
csharp

	using System.Net;
	using System.Net.NetworkInformation;
	
	// 获取ARP缓存表(IP地址与MAC地址的映射)
	var arpEntries = ArpCache.GetArpEntries();
	foreach (var entry in arpEntries)
	{
	Console.WriteLine($"IP地址:{entry.IpAddress}");
	Console.WriteLine($"MAC地址:{entry.MacAddress}");
	Console.WriteLine($"接口索引:{entry.InterfaceIndex}");
	Console.WriteLine("------------------------");
	}
	
	// 自定义ARP缓存读取类
	public static class ArpCache
	{
	public static List<ArpEntry> GetArpEntries()
	{
	var entries = new List<ArpEntry>();
	// 调用Windows API读取ARP缓存(需要管理员权限)
	var buffer = new byte[1024];
	int length = buffer.Length;
	if (NativeMethods.GetIpNetTable(buffer, ref length, false) == 0)
	{
	int offset = 0;
	int count = BitConverter.ToInt32(buffer, offset);
	offset += 4;
	for (int i = 0; i < count; i++)
	{
	var ipAddress = new IPAddress(BitConverter.ToInt32(buffer, offset));
	offset += 4;
	var macBytes = new byte[6];
	Array.Copy(buffer, offset, macBytes, 0, 6);
	offset += 6;
	var macAddress = string.Join("-", macBytes.Select(b => b.ToString("X2")));
	entries.Add(new ArpEntry { IpAddress = ipAddress, MacAddress = macAddress });
	}
	}
	return entries;
	}
	}
	
	public class ArpEntry
	{
	public IPAddress IpAddress { get; set; } = null!;
	public string MacAddress { get; set; } = null!;
	public int InterfaceIndex { get; set; }
	}
	
	// 导入Windows API
	internal static class NativeMethods
	{
	[System.Runtime.InteropServices.DllImport("iphlpapi.dll")]
	public static extern int GetIpNetTable(byte[] pIpNetTable, ref int pdwSize, bool bOrder);
	}

代码逐行讲:
1.GetIpNetTable:调用Windows系统API读取ARP缓存表,需要管理员权限;
2.ArpEntry:存储IP地址与MAC地址的映射关系;
3.BitConverter.ToInt32:解析API返回的二进制数据,转换成IP地址和MAC地址;
4.为什么要学这个?当你做局域网通信(如UDP广播)时,需要通过MAC地址定位设备,ARP缓存是关键。
3. 网络层:跨网络的“导航员”
核心功能:把数据链路层的“帧”封装成“数据包”,添加源IP地址和目标IP地址,通过路由选择实现跨网络传输。
你需要知道:
IP地址:网络层的逻辑地址,分为IPv4(32位,如192.168.1.1)和IPv6(128位,如2001:0db8:85a3:0000:0000:8a2e:0370:7334);
ICMP协议:网络层控制协议,用于检测网络连通性(如ping命令);
路由选择:通过路由器选择最优路径,把数据包从源IP发送到目标IP。
C#实战:实现简单的ping功能
csharp

	using System.Net;
	using System.Net.NetworkInformation;
	
	public static bool PingHost(string ipAddress, int timeout = 1000)
	{
	try
	{
	using var ping = new Ping();
	// 发送ICMP请求包
	var reply = ping.Send(ipAddress, timeout);
	// 判断是否连通
	return reply.Status == IPStatus.Success;
	}
	catch (PingException ex)
	{
	Console.WriteLine($"ping失败:{ex.Message}");
	return false;
	}
	}
	
	// 调用示例
	bool isReachable = PingHost("www.baidu.com");
	Console.WriteLine($"百度是否可达:{isReachable}");

代码逐行讲:
1.Ping类:.NET内置的ICMP客户端,用于发送ping请求;
2.Send方法:发送ICMP请求包,返回PingReply对象;
3.IPStatus.Success:判断目标主机是否可达;
4.底层原理:ping命令基于ICMP协议,网络层协议,不涉及传输层和应用层,所以ping通不代表应用服务能访问(比如对方服务器禁了ICMP,但HTTP服务正常)。
4. 传输层:端到端的“快递员”
核心功能:把网络层的“数据包”封装成“段”(TCP)或“数据报”(UDP),添加源端口和目标端口,实现端到端的可靠传输。
你需要知道:
端口:传输层的标识,范围0-65535,其中0-1023是知名端口(如HTTP用80,HTTPS用443);
TCP协议:面向连接、可靠传输、有序、重传(适合文件传输、网页浏览);
UDP协议:无连接、不可靠、无序、不重传(适合实时通信、视频通话)。
C#实战:获取本地端口占用情况
csharp

	using System.Net;
	using System.Net.NetworkInformation;
	using System.Net.Sockets;
	
	// 获取所有TCP连接
	var tcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections();
	foreach (var connection in tcpConnections)
	{
	if (connection.LocalEndPoint is IPEndPoint localEp && 
	connection.RemoteEndPoint is IPEndPoint remoteEp)
	{
	Console.WriteLine($"本地地址:{localEp}");
	Console.WriteLine($"远程地址:{remoteEp}");
	Console.WriteLine($"连接状态:{connection.State}");
	Console.WriteLine("------------------------");
	}
	}
	
	// 获取所有UDP监听端口
	var udpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners();
	foreach (var listener in udpListeners)
	{
	Console.WriteLine($"UDP监听端口:{listener}");
	}

代码逐行讲:
1.GetActiveTcpConnections:获取当前系统所有活跃的TCP连接;
2.GetActiveUdpListeners:获取当前系统所有监听的UDP端口;
3.IPEndPoint:包含IP地址和端口号,是传输层的核心标识;
4.为什么要学这个?当你启动TCP服务器提示“端口被占用”时,用这段代码就能找到占用端口的进程。
5. 会话层、表示层、应用层:用户能摸到的“服务”
会话层:负责建立、管理和终止会话(比如你登录微信到退出微信的整个过程),常用协议有RPC、NetBIOS;
表示层:负责数据格式转换和加密解密(比如把JSON转换成二进制,把明文加密成密文),常用协议有SSL/TLS、JPEG;
应用层:直接为用户提供服务(比如浏览器、微信、FTP客户端),常用协议有HTTP、HTTPS、FTP、SMTP。
C#实战:用HttpClient发送HTTP请求(应用层)
csharp

	using System.Net.Http;
	using System.Threading.Tasks;
	
	public static async Task<string> GetHttpResponse(string url)
	{
	using var client = new HttpClient();
	// 发送HTTP GET请求(应用层协议)
	var response = await client.GetAsync(url);
	// 确保请求成功
	response.EnsureSuccessStatusCode();
	// 读取响应内容
	return await response.Content.ReadAsStringAsync();
	}
	
	// 调用示例
	string html = await GetHttpResponse("https://www.baidu.com");
	Console.WriteLine(html.Substring(0, 1000)); // 输出前1000个字符

代码逐行讲:
1.HttpClient:.NET内置的HTTP客户端,封装了应用层的HTTP协议;
2.GetAsync:发送HTTP GET请求,底层会自动处理传输层的TCP连接、网络层的IP路由、数据链路层的MAC寻址;
3.EnsureSuccessStatusCode:如果HTTP状态码不是200-299,抛出异常;
4.为什么要学这个?应用层是网络编程的“最终战场”,你写的大部分代码都在应用层,但不懂下层原理,遇到问题就只能“重启试试”。
三、TCP/IP四层模型:工业界的“事实标准”
OSI七层模型是“理论标准”,而TCP/IP四层模型是工业界的“事实标准”,把OSI七层模型合并成四层,更简洁、更实用。

TCP/IP四层模型 对应OSI七层模型 核心协议
应用层 应用层+表示层+会话层 HTTP、HTTPS、FTP、SMTP
传输层 传输层 TCP、UDP
网际层 网络层 IP、ICMP
网络接口层 数据链路层+物理层 Ethernet、ARP、PPP

你需要知道:
TCP/IP是一个协议族,包含IP、TCP、UDP、HTTP等上百个协议;
我们常说的“TCP/IP协议”其实是指TCP/IP协议族;
几乎所有互联网通信都基于TCP/IP四层模型。
四、数据在网络模型中的“旅行”
以你用浏览器访问www.baidu.com为例,数据的传输过程是这样的:
1.应用层:浏览器生成HTTP请求(包含请求头、请求体);
2.传输层:把HTTP请求封装成TCP段,添加源端口(如12345)和目标端口(80);
3.网络层:把TCP段封装成IP数据包,添加源IP(如192.168.1.100)和目标IP(如110.242.68.3);
4.网络接口层:把IP数据包封装成以太网帧,添加源MAC(如00-1A-2B-3C-4D-5E)和目标MAC(如11-22-33-44-55-66);
5.物理层:把以太网帧转换成电信号,通过网线传输到路由器;
6.路由器转发:路由器根据目标IP选择最优路径,把数据包转发到百度服务器;
7.服务器接收:百度服务器从物理层到应用层逐层解封装,最终得到HTTP请求,处理后返回HTTP响应;
8.客户端接收:浏览器从物理层到应用层逐层解封装,得到HTTP响应,渲染成网页。
五、基础知识拓展

  1. 为什么TCP是可靠的,UDP是不可靠的?
    TCP有三次握手(建立连接)、四次挥手(断开连接)、滑动窗口(流量控制)、拥塞控制(避免网络拥堵)、重传机制(丢失的数据包重新发送);
    UDP没有这些机制,发送数据后不管对方有没有收到,也不管数据有没有乱序,适合实时性要求高的场景(如视频通话、游戏)。
  2. IP地址和MAC地址的区别?
    IP地址是逻辑地址,可以手动修改,用于跨网络传输;
    MAC地址是物理地址,出厂时固化在网卡上,不能修改,用于同一局域网内的通信;
    类比:IP地址是“家庭地址”,MAC地址是“身份证号”,快递员(传输层)用家庭地址找你,分拣中心(数据链路层)用身份证号确认你的身份。
  3. 端口的作用是什么?
    一台电脑可以同时运行多个网络程序(如浏览器、微信、QQ),端口就是用来区分这些程序的;
    类比:IP地址是“小区地址”,端口是“门牌号”,快递员(传输层)根据门牌号把快递送到对应的住户(程序)。
  4. 为什么需要分层?
    解耦:每层只做一件事,修改一层不影响其他层(比如把网线换成光纤,只需要修改物理层,应用层完全不用变);
    标准化:不同厂商的设备只要遵守同一层的标准,就能互相通信(比如华为的路由器和思科的路由器,只要都遵守IP协议,就能互相转发数据包);
    易调试:出问题时可以逐层排查(比如ping不通,先查物理层有没有插网线,再查数据链路层有没有获取到MAC地址,再查网络层有没有获取到IP地址)。
    六、总结:网络模型不是“背题”,是“解题工具”
    OSI七层模型是“理论教科书”,帮你理解网络通信的完整流程;
    TCP/IP四层模型是“实战手册”,帮你快速定位问题和编写代码;
    分层的核心是“各司其职”,上层依赖下层,下层为上层提供服务;
    学习网络模型的目的不是“背下来每层的名称”,而是“遇到问题时能快速定位到哪一层出了问题”。
    比如你用C#写的TCP客户端连不上服务器,按照网络模型排查:
    1.物理层:插网线了吗?WiFi连了吗?
    2.数据链路层:能ping通服务器吗?ARP缓存有服务器的MAC地址吗?
    3.网络层:服务器的IP地址对吗?有没有防火墙禁了IP?
    4.传输层:服务器的端口对吗?有没有被占用?防火墙禁了端口吗?
    5.应用层:服务器的应用程序启动了吗?协议格式对吗?
    按照这个流程排查,90%的问题都能在10分钟内解决——这就是网络模型的价值。下一节我们就用C#实战TCP和UDP编程,把传输层的理论落地成代码。

 本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49508.html


相关教程