VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • C#中关于网络通信原理(IP地址、端口、协议)

第一部分:网络编程基础
第1章 网络编程核心概念
1.2 网络通信原理(IP地址、端口、协议)
一、为什么要懂这三个概念?
之前做C# TCP服务器时,客户端总是连不上,查了半天发现是把“127.0.0.1”写成了“127.0.0.2”——这就是不懂IP地址的坑。还有一次,服务器监听端口“80”,结果被系统的HTTP服务占用了,导致启动失败——这就是不懂端口的坑。IP地址、端口、协议是网络通信的“三要素”,就像寄快递需要“收件人地址”“门牌号”“快递类型”,缺一个都不行。这节就带你把这三个概vb.net教程C#教程python教程SQL教程access 2010教程念掰碎了讲,结合C#代码实战,让你不仅“知道是什么”,更能“知道怎么用”。
二、IP地址:网络世界的“门牌号”
IP地址是网络设备在网络中的唯一标识,就像你家的地址,别人只有知道你的地址才能给你寄快递。IP地址分为IPv4和IPv6两种。

  1. IPv4:32位的“老门牌”
    核心结构:32位二进制数,分成4个8位段,用十进制表示(如192.168.1.100)。
    你需要知道:
    范围:0.0.0.0到255.255.255.255,共约43亿个地址(已经用完了);
    分类:A类(0.0.0.0-127.255.255.255)、B类(128.0.0.0-191.255.255.255)、C类(192.0.0.0-223.255.255.255);
    特殊地址:127.0.0.1(回环地址,用于本地测试)、0.0.0.0(表示所有本地地址)、255.255.255.255(广播地址)。
    C#实战:解析IPv4地址
    csharp
	using System.Net;
	
	// 字符串转IPAddress
	string ipStr = "192.168.1.100";
	if (IPAddress.TryParse(ipStr, out IPAddress? ipAddress))
	{
	Console.WriteLine($"IP地址:{ipAddress}");
	Console.WriteLine($"是否IPv4:{ipAddress.AddressFamily == AddressFamily.InterNetwork}");
	Console.WriteLine($"二进制表示:{Convert.ToString(ipAddress.Address, 2).PadLeft(32, '0')}");
	// 输出:11000000101010000000000101100100
	}
	
	// 获取本地IPv4地址
	var localIpv4 = Dns.GetHostEntry(Dns.GetHostName())
	.AddressList
	.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
	Console.WriteLine($"本地IPv4地址:{localIpv4}");

代码逐行讲:
1.IPAddress.TryParse:把字符串转换成IPAddress对象,避免无效IP地址抛出异常;
2.AddressFamily.InterNetwork:判断是否为IPv4地址(InterNetworkV6是IPv6);
3.Convert.ToString(ipAddress.Address, 2):把IPv4地址转换成32位二进制字符串,直观展示IP地址的底层结构;
4.Dns.GetHostEntry:通过主机名获取本地IP地址,避免硬编码127.0.0.1。
2. IPv6:128位的“新门牌”
核心结构:128位二进制数,分成8个16位段,用十六进制表示(如2001:0db8:85a3:0000:0000:8a2e:0370:7334)。
你需要知道:
范围:几乎无限(约3.4×10³⁸个地址),解决了IPv4地址耗尽的问题;
简化写法:连续的0可以省略,用::代替(如2001:db8::8a2e:370:7334);
特殊地址:::1(回环地址,对应IPv4的127.0.0.1)、::(表示所有本地地址)。
C#实战:解析IPv6地址
csharp

	using System.Net;
	
	// 字符串转IPAddress
	string ipv6Str = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
	if (IPAddress.TryParse(ipv6Str, out IPAddress? ipv6Address))
	{
	Console.WriteLine($"IPv6地址:{ipv6Address}");
	Console.WriteLine($"是否IPv6:{ipv6Address.AddressFamily == AddressFamily.InterNetworkV6}");
	Console.WriteLine($"简化写法:{ipv6Address.ToString()}");
	// 输出:2001:db8:85a3::8a2e:370:7334
	}
	
	// 获取本地IPv6地址
	var localIpv6 = Dns.GetHostEntry(Dns.GetHostName())
	.AddressList
	.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetworkV6);
	Console.WriteLine($"本地IPv6地址:{localIpv6}");

代码逐行讲:
1.IPAddress.TryParse:同样支持IPv6地址解析,自动处理简化写法;
2.AddressFamily.InterNetworkV6:判断是否为IPv6地址;
3.ipv6Address.ToString():自动输出简化后的IPv6地址,避免手动处理连续的0。
3. 子网掩码与网关:IP地址的“配套设施”
子网掩码:用于区分IP地址的“网络部分”和“主机部分”(如255.255.255.0表示前24位是网络部分,后8位是主机部分);
网关:连接不同网络的“出入口”(如你家路由器的IP地址192.168.1.1,就是你家网络和互联网的网关)。
C#实战:获取子网掩码与网关
csharp
using System.Net;
using System.Net.NetworkInformation;

var interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var iface in interfaces)
{
if (iface.NetworkInterfaceType != NetworkInterfaceType.Loopback && 
iface.OperationalStatus == OperationalStatus.Up)
{
var properties = iface.GetIPProperties();
foreach (var unicast in properties.UnicastAddresses)
{
if (unicast.Address.AddressFamily == AddressFamily.InterNetwork)
{
Console.WriteLine($"网卡名称:{iface.Name}");
Console.WriteLine($"IP地址:{unicast.Address}");
Console.WriteLine($"子网掩码:{unicast.IPv4Mask}");
Console.WriteLine($"网关:{properties.GatewayAddresses.FirstOrDefault()?.Address}");
Console.WriteLine("------------------------");
}
}
}
}

代码逐行讲:
1.GetIPProperties:获取网络接口的IP属性,包括子网掩码、网关、DNS服务器;
2.UnicastAddresses:获取单播IP地址(区别于广播、组播地址);
3.IPv4Mask:获取IPv4的子网掩码,IPv6没有子网掩码,用前缀长度表示(如/64);
4.GatewayAddresses:获取网关地址,通常是路由器的IP地址。
三、端口:网络程序的“门牌号”
端口是传输层的标识,用于区分同一台设备上的不同网络程序。就像你家的“房间号”,快递员(传输层)根据房间号把快递送到对应的房间(程序)。

  1. 端口的基本概念
    范围:0-65535,共65536个端口;
    分类:
    o知名端口(0-1023):预留给常用服务(如HTTP用80,HTTPS用443,FTP用21);
    o注册端口(1024-49151):用于用户程序(如Tomcat默认用8080,MySQL默认用3306);
    o动态端口(49152-65535):系统自动分配给临时网络连接(如浏览器访问网页时的本地端口);
    特点:同一台设备上,同一协议(TCP/UDP)的端口不能重复使用。
    C#实战:检测端口是否被占用
    csharp
	using System.Net;
	using System.Net.Sockets;
	
	public static bool IsPortInUse(int port, AddressFamily addressFamily = AddressFamily.InterNetwork)
	{
	try
	{
	// 尝试绑定端口,如果绑定失败说明端口被占用
	using var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
	socket.Bind(new IPEndPoint(addressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, port));
	return false;
	}
	catch (SocketException ex)
	{
	// 错误码10048表示端口被占用
	if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
	{
	return true;
	}
	// 其他错误(如权限不足)
	throw;
	}
	}
	
	// 调用示例
	bool is80InUse = IsPortInUse(80);
	Console.WriteLine($"端口80是否被占用:{is80InUse}");

代码逐行讲:
1.Socket.Bind:尝试绑定指定端口,如果端口已被占用,会抛出SocketException;
2.SocketError.AddressAlreadyInUse:错误码10048表示端口被占用,这是最常见的情况;
3.IPAddress.Any:表示绑定所有本地IPv4地址,IPAddress.IPv6Any表示绑定所有本地IPv6地址;
4.为什么用Socket而不是TcpListener?因为Socket更底层,能同时检测TCP和UDP端口(把SocketType.Stream改成SocketType.Dgram,ProtocolType.Tcp改成ProtocolType.Udp即可)。
2. 端口的常见问题
端口被占用:解决方法是换一个端口,或者关闭占用端口的程序(用netstat -ano | findstr :80命令找到占用端口的进程ID,再用taskkill /pid 1234 /f杀死进程);
权限不足:绑定知名端口(0-1023)需要管理员权限,普通用户只能绑定1024以上的端口;
端口耗尽:如果设备上有大量临时网络连接,可能会耗尽动态端口,解决方法是调整动态端口范围(Windows下用netsh int ipv4 set dynamicport tcp start=49152 num=16384命令)。
四、协议:网络通信的“规则手册”
协议是网络设备之间通信的“规则手册”,规定了数据的格式、传输方式、错误处理等。就像你和外国人说话需要用同一种语言(协议),否则对方听不懂。

  1. 协议的基本概念
    分层设计:协议是分层的,每层协议只负责自己的功能(如IP协议负责网络层路由,TCP协议负责传输层可靠传输);
    协议族:一组相关的协议组成协议族(如TCP/IP协议族包含IP、TCP、UDP、HTTP等);
    知名协议:HTTP(网页浏览)、HTTPS(安全网页浏览)、TCP(可靠传输)、UDP(实时传输)、IP(路由)、ICMP(网络检测)。
    C#实战:解析HTTP协议(应用层协议)
    csharp
	using System;
	using System.Net.Sockets;
	using System.Text;
	
	public static async Task ParseHttpProtocol(string host, int port = 80)
	{
	using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
	await socket.ConnectAsync(host, port);
	
	// 发送HTTP GET请求(严格按照HTTP协议格式)
	string request = $"GET / HTTP/1.1
Host: {host}
Connection: close

";
	byte[] requestBytes = Encoding.ASCII.GetBytes(request);
	await socket.SendAsync(requestBytes, SocketFlags.None);
	
	// 接收HTTP响应
	byte[] buffer = new byte[4096];
	int bytesRead = await socket.ReceiveAsync(buffer, SocketFlags.None);
	string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
	Console.WriteLine("HTTP响应:");
	Console.WriteLine(response);
	
	// 解析HTTP响应头
	string[] lines = response.Split(new[] { "
" }, StringSplitOptions.RemoveEmptyEntries);
	string statusLine = lines[0];
	Console.WriteLine($"
状态行:{statusLine}");
	foreach (string line in lines.Skip(1))
	{
	if (line.Contains(":"))
	{
	string[] parts = line.Split(new[] { ":" }, 2);
	Console.WriteLine($"响应头:{parts[0]} = {parts[1].Trim()}");
	}
	}
	}
	
	// 调用示例
	await ParseHttpProtocol("www.baidu.com");

代码逐行讲:
1.Socket.ConnectAsync:根据主机名和端口号建立TCP连接(传输层协议);
2.HTTP请求格式:严格按照HTTP协议要求,第一行是方法 路径 协议版本,然后是请求头,最后是两个换行( )表示请求头结束;
3.Socket.SendAsync:发送HTTP请求(应用层协议),底层自动处理TCP协议的可靠传输;
4.解析HTTP响应:把响应内容按 分割,第一行是状态行(如HTTP/1.1 200 OK),后面是响应头,最后是响应体。
2. 协议的核心要素
数据格式:规定了数据的结构(如HTTP请求的状态行、请求头、请求体);
传输方式:规定了数据的传输方式(如TCP是面向连接的,UDP是无连接的);
错误处理:规定了错误的处理方式(如TCP的重传机制,HTTP的状态码);
交互流程:规定了通信的交互流程(如TCP的三次握手,HTTP的请求-响应)。
五、三要素的关系:网络通信的“铁三角”
IP地址、端口、协议是网络通信的“三要素”,缺一不可:
IP地址:确定通信的“目标设备”;
端口:确定设备上的“目标程序”;
协议:确定通信的“规则方式”。
类比:你要给朋友发快递,IP地址是“朋友家的地址”,端口是“朋友家的房间号”,协议是“快递类型(如顺丰、京东)”。只有同时知道这三个信息,快递才能准确送到朋友手里。
六、基础知识拓展

  1. 为什么需要NAT(网络地址转换)?
    IPv4地址耗尽后,NAT技术应运而生,它能把多个私有IP地址转换成一个公网IP地址,让多个设备共享一个公网IP地址上网。
    私有IP地址范围:10.0.0.0-10.255.255.255、172.16.0.0-172.31.255.255、192.168.0.0-192.168.255.255;
    公网IP地址:全球唯一的IP地址,能直接访问互联网。
  2. 为什么HTTPS比HTTP安全?
    HTTP是明文传输,数据在传输过程中可能被窃听、篡改;HTTPS在HTTP基础上添加了SSL/TLS加密层,数据在传输过程中是加密的,只有客户端和服务器能解密,防止窃听和篡改。
  3. TCP和UDP的选择依据?
    TCP:适合对可靠性要求高的场景(如文件传输、网页浏览、电商支付);
    UDP:适合对实时性要求高的场景(如视频通话、游戏、实时监控);
    记住一句话:可靠用TCP,实时用UDP。
    七、总结:三要素是网络编程的“地基”
    IP地址:找到目标设备,分为IPv4和IPv6,要懂子网掩码和网关;
    端口:找到设备上的目标程序,分为知名端口、注册端口、动态端口,要懂端口占用的解决方法;
    协议:遵守通信规则,分为应用层、传输层、网络层、数据链路层、物理层协议,要懂常见协议的用途;
    三要素缺一不可,就像盖房子需要地基,网络编程的所有代码都是基于这三个要素的。
    比如你用C#写TCP服务器,需要指定IP地址(0.0.0.0表示所有本地地址)、端口(如8888)、协议(TCP);写TCP客户端,需要指定服务器的IP地址、端口、协议,才能建立连接。下一节我们就用C#实战TCP和UDP编程,把这三个要素落地成代码。

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


相关教程