“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(下)

Calibre PEX提参实战:如何用hcell和xcell文件精准屏蔽模块(附避坑指南) 本文深入解析Calibre PEX工具中hcell与xcell文件的协同工作机制,提供模块级寄生参数提取方案。通过实战案例和避坑指南,帮助工程师精准屏蔽已验证IP模块,提升仿真效率和数据一致性,适用于65nm以下工艺节点的复杂SoC设计。 阅读详情

“.NET 4.0 网络开发入门之旅系列文章”——

 

IP 知多少?(下)

 

前一部分: IP 知多少?(中)

 

 

 

 

4.  IP 终结点

         现在介绍 .NET 网络开发中最重要的一个概念—— IP 终结点, .NET 基类库中使用 IPEndPoint 类型代表它。

         要想理解它,还得从 TCP/IP 说起。

         前面说过,所有连在网络上的计算机都必须要有一个唯一的 IP 地址,它用于区分开网络上的不同计算机,现在的问题是:一台网络计算机上可能跑着多个 网络应用程序,它们可能会使用同一个网络接口从网络中接收(或发送)数据,因而共享同一个 IP 地址,在这种情况下,你怎么将到达主机的数据包转发给真正的“需求者”?

         为了解决这个问题, TCP/IP 协议设计者引入了“端口( Port )”这个概念,规定每个提供网络服务的应用程序都必须指定一个“端口”,不同的网络应用程序不能使用相同的端口。

         请看以下 TCP 数据包的结构:

 

 

 

 

图 4

 

         每个 TCP 数据包都包容着两个端口信息(每个端口占 2 个字节,是一个 16 位的二进制数值,所以,最大端口值为 2 的 16 次方减 1 ,为 65535 )。 Source port 指明发送此数据包的网络应用程序使用的端口, Destination port 指明接收方网络应用程序使用的端口。

         这样一来,接收方计算机依据 Destination port ,就可以把此数据包转发给真正的网络应用程序。

         在 Windows 平台上,操作系统内核中的 TCP/IP 驱动( /Windows/System32/drivers 文件夹下的 tcpip.sys )负责完成处理 TCP 数据包的工作。

         端口的问题解决了,但我们在 TCP 数据包中没有看到 IP 地址啊?没有这个地址,数据包怎样知道应该被送给哪台计算机?

         方法是这样的。

         由于 TCP 协议建构于 IP 协议之上, TCP 数据包由 IP 数据包承载,(图 5 )。


 

 

 

图 5

 

         图 5 中清晰地展示出 IP 数据包中包容有发送此数据包的主机 IP 地址(即 Source IP Address )和接收此数据包的主机 IP 地址(即 Destination IP Address )信息。

         图 5 中的“数据( Data )”部分,包容的就是 TCP 数据包。

         由此可知, IP 地址与端口唯一地标识了一个网络中的网络应用程序,我们将这个组合称为“ IP 终结点( IP EndPoint )”, IP EndPoint 是一个网络服务的访问点。

        

         提示:

         类似地, WCF 中也有一个服务终结点( ServiceEndpoint ),它代表一个 WCF 服务的访问点。大家看到了软件技术各领域之间的联系了吗?

 

         在 .NET 中,使用 IPEndPoint 类表示一个 IP 终结点(图 6 ),它派生自抽象基类 EndPoint ,注意它的 3 个属性( Address/AddressFamily/Port )所表达的重要信息。


 

 

图 6

 

         在 .NET 网络应用程序中,套接字( Socket )对象必须绑定到一个 IPEndPoint 对象。

         为了方便,我们编写了一个静态方法 GetRemoteMachineIPEndPoint ,并将其添加到前面介绍过的 AddressHelper 静态类中:

 

        /// 以交互方式生成有效的远程主机访问终结点 , 适用于控制台程序

        public static IPEndPoint GetRemoteMachineIPEndPoint()

        {

            IPEndPoint iep = null;

            try

            {

                Console.Write(" 请输入远程主机的 IP 地址: ");

                IPAddress address = IPAddress.Parse(Console.ReadLine());

                Console.Write(" 请输入远程主机打开的端口号: ");

                int port = Convert.ToInt32(Console.ReadLine());

                if (port > 65535 || port < 1024)

                    throw new Exception(" 端口号应该为 [1024,65535] 范围内的整数 ");

                iep = new IPEndPoint(address, port);

            }

            catch (ArgumentNullException)

            {

                Console.WriteLine(" 输入的数据有误! ");

            }

            catch (FormatException)

            {

                Console.WriteLine(" 输入的数据有误! ");

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.Message);

            }

            return iep;

        }

 

         后面的示例将大量使用此方法创建可供 Socket 绑定的 IP 终结点对象。

1.  我可以使用哪个端口?

         在实际开发中,经常需要为某个网络服务动态地指定一个端口,为避免与一些重要的网络服务程序冲突(比如 80 端口固定为 Web 服务器所使用)通常要求这个端口应位于 [1024,65535] 这区间内。

         现在的问题是怎样从中选取一个没有被占用的端口?要知道,某台计算机上运行的网络应用程序可能有多个,而且在不同的时间段内也不一样。

         IPAddress.Any 这个特殊的地址可以派上用场了,当一个套接字对象绑定一个 IPAddress.Any 对象时, Windows 会自动为其分配一个未被占用的端口号,当套接字对象不再使用而可以被回收时,此端口将可以被复用。

         由此我们可以得到以下的思路:

         创建一个套接字对象,让它绑定到 IPAddress.Any 对象,提取出系统分配的端口,然后再销毁掉此套接字对象。

         Socket 对象实现了 IDisposable 接口,所以可以使用 using 关键字来自动回收其占用的资源:

         以下是我们编写的代码片段:

 

public static int GetOneAvailablePortInLocalhost()

{

         IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);

         using (Socket tempSocket = new Socket(AddressFamily.InterNetwork,

                             SocketType.Stream, ProtocolType.Tcp))

         {

                   tempSocket.Bind(ep);

                   IPEndPoint ipep = tempSocket.LocalEndPoint as IPEndPoint;

                   return ipep.Port;

         }

}

 

         提示:

         一个对象实现 IDisposable 接口有许多讲究, .NET 为此设计了一个“ IDisposable 编程模式”,请参看《 .NET 4.0 面向对象编程漫谈》的 5.5 节《与对象销毁相关的话题》

 

         呵呵,现在,我们在应用程序中可以随时调用 AddressHelper. GetOneAvailablePortInLocalhost() 方法获取一个可用端口了,真给力!

         但别高兴得太早!

         你考虑过两个网络应用程序(或同一应用程序的两个线程)同时调用上述方法获取可用端口的情形吗?

         这时,无法保证此方法的两次调用一定返回不同的端口。如果两个 Socket 对象尝试绑定到同一个 IPEndPoint ,将会引发一个 SocketException 异步。

         为此,我们需要一个能跨越进程边界的线程同步手段。

         命名的互斥同步对象 Mutex 可以解决这个问题,修正后的代码如下:

 

// 获取本机当前可用的端口号,此方法是线程安全的

public static int GetOneAvailablePortInLocalhost()

{

         Mutex mtx = new Mutex(false, "MyNetworkLibrary.AddressHelper.GetOneAvailablePort");

         try

         {

                   mtx.WaitOne();

                   IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);

                   using (Socket tempSocket = new Socket(

                            AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))

                   {

                            tempSocket.Bind(ep);

                            IPEndPoint ipep = tempSocket.LocalEndPoint as IPEndPoint;

                            return ipep.Port;

                   }

         }

         finally

         {

                   mtx.ReleaseMutex();

         }

}

 


提示:

         《 .NET 4.0 面向对象编程漫谈 》的 17.3.2 节详细介绍了 Mutex 对象的使用方法, 15.3.5 节介绍了如何活用命名 Mutex 对象实现应用程序的“单例模式”(即此应用程序不允许同时启动两个进程),以及如何利用它来现进程间的“通知机制”。

         建议读者对照学习。

        

         好了,本文就写到这里吧。

         给读者留个作业:

         1 依据本文介绍的内容使用 Visual Studio 创建类库项目 MyNetworkLibrary ,将 GetLocalhostIPv4Addresses() 、 GetRemoteMachineIPEndPoint() 、 GetOneAvailablePortInLocalhost

() 三个方法封装到 AddressHelper 静态类中,后面文章的示例将调用它们。

 

         2 .NET 基类库中提供了一个 Ping 组件用于检测网络连接性,请先通过 MSDN 自学它的使用方法。

 

========================================================

点击查看本系列的下一篇文章

《 .NET 4.0网络开发入门之旅-- 我在“网” 中央》

       

【视频】GStreamer+WebRTC(九):使用NVIDIA硬编解码 2)下载 GStreamer-bad 插件包源码注意要下载和 GStreamer版本对应的插件包3)下载NVIDIA硬编解码SDK最新的SDK下载地址注意 GStreamer 1.24.2 中调用的 NVIDIA Video_Codec_SDK 不是最新的,先使用下面的方法,查看gst-plugins-bad-1.24.2.tar.xz 对应的NVIDIA Video_Codec_SDK 的版本是多少。 阅读详情

相关推荐

KLayout教程(二)编辑不同的形状

首先画一个基础的矩形,然后双击他可以定义他的坐标

集成光电子 1万+

IPEndPoint类的使用方法(C#---网络编程)

IPEndPoint类的使用方法(C#窗体) 1、窗体设计 2、程序设计 using System.Net;   private void button1_Click(object sender, EventArgs e)         {             //实例化IPEndPoint类对象             IPEndPoint IPEPoint =

liyuqian199695的博客 3万+

GEOPHYSICS 投稿避坑指南:从格式规范到双盲评审的实战解析

本文详细解析了GEOPHYSICS期刊投稿的全流程避坑指南,从格式规范、数据声明到双盲评审的实战策略。特别强调了数学公式排版、图表制作标准以及投稿系统的隐藏关卡,帮助作者避免常见错误,提升投稿成功率。

weixin_30606461的博客 236

逐语句执行.NET Framework 4.0源代码

原文出处:http://blogs.microsoft.co.il/blogs/arik/archive/2010/07/12/step-into-net-framework-4-0-source-code.aspx  本文将向你展示如何配置Visual Studio 2010

总结! 4543

基于gem5模拟trace的cache模拟器的实现

在做计算机体系结构的时候,模拟器是一个重要且又有效的工具。其中gem5集成了gem和m5的优点,使用起来比较简单和方便。其中包括了se模式和fs模式,se模式是在gem5运行我们已经编译好的程序,可以获取cache,cpu状态等数据,fs模式下可以模拟操作系统,我们可以将我们自己修改的linux内核加载到哥们上运行。下面介绍了使用gem5的se模式,运行编译好的ARM可执行文件。获取访存的trac

gaoxiang的专栏 8891

双三相电机控制避坑指南:为什么你的SVPWM谐波大?四矢量调制实战解析

本文深入解析双三相电机控制中SVPWM谐波大的问题,并提供四矢量调制实战方案。通过分析谐波来源、四矢量调制原理及工程实现步骤,显著降低电流THD至3-5%,提升系统效率2.3个百分点。特别适合需要优化电机控制的工程师参考。

weixin_30645617的博客 397

c# UDP Socket

    public class UDPSocket { private Socket _client; private string _remoteHost; private int _remotePort; private IPEndPoint _remoteEP; private int _...

清风ai明月的专栏 1626

基于大模型的恶性胸腔积液全周期预测与诊疗方案研究

本研究基于大模型技术构建了恶性胸腔积液全流程预测与诊疗体系,涵盖术前风险评估、术中方案优化、术后恢复预测及并发症预防。通过整合多源医疗数据,实现了手术风险概率预测(准确率80%)、并发症预警(AUC值0.85)及个性化康复方案制定,显著提升诊疗精准度。研究创新性地将Transformer架构与多模态数据融合,在100例临床验证中显示良好性能,但存在数据样本局限、模型可解释性不足等问题。未来将扩大多中心临床验证,优化算法可解释性,探索与基因检测等技术的结合应用,推动恶性胸腔积液的精准诊疗发展。

嵌入式毕设/课设资料清单(速查手册·文档模板·题库,持续更新)→ 见最新文章 1897

C# 网络编程 IP地址转换

IP地址 IP地址:是给每个连接在因特网上的主机(或路由器)分配一个在全世界范围内惟一的标识符。一个IP地址主要由两部分组成:网络地址和主机地址。 网络地址由因特网权力机构分配,主机地址由各个网络的管理员统一分配。 IP地址编制方案有两种:IPV4和IPV6 IPV4:二进制表示共32位(4个字节) IPV6:二进制表示共128位(16个字节) 在IPV4编制方案中,一般使用点分十进制表示法表示IP地址。例如:192.168.3.1 端口 端口:IP地址仅仅能够具体标识到某台主机,而端口则表示与计算机上的哪

imxlw00的专栏 3907

r3live 使用前提 雷达-相机外参标定 livox_camera_lidar_calibration

港科大livox_camera_calib虽然操作方便,但是使用mid360雷达会有视角问题(投影三维点到相机),尝试了很多场景,标定效果都不理想(推荐场景是楼梯间),看来港大的更适合avia之类窄角度的雷达。如果标定效果不好的话,就使用 getExt2节点,getExt1节点只优化外参,而getExt2节点在计算的时候会将一开始计算的内参作为初值和外参一起优化。一般使用getExt1节点即可,如果在外参初值验证过,并且异常值已经剔除后,优化还是有较大的残差,那么可以使用getExt2试一试。

z1872385的博客 2399

关于cefsharp访问iqiyi.com显示403 Forbidden解决办法(2种方法)

cefsharp不加UserAgent的默认值为 (注意126是当前cefsharp的版本)Edge浏览器的UserAgent 为 (edge的版本是128的)说明根据浏览器的不同,UserAgent可能不太一样。

无线智能模块 可视DIY智能专家 1319

IPEndPoint(IPAddress.Any, 0)的意思

IPEndPoint(IPAddress.Any, 0) If creates an IPEndpoint using any available IP address on the local computer, and any available port number. IPAddress.Any代表本机上的所有IP地址,MSDN上说是“一个 IP 地址,指示服务器应侦听所有网络接口

farmer_worker的专栏 2万+

二、CANdelaStudio入门-版本介绍

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio的各个版本,欢迎各位朋友订阅、评论,可以提出宝贵意见,以持续输出更好的作品,同时会根据评论、私信不定期更新文章内容,以及专栏目录。订阅该专栏的朋友可私信小编免费答疑解惑(^U^)ノ~YOCANdelaStudio——诊断需求定义工具,诊断协议开发软件 ①用户以模板概念为导向

诊断协议那些事儿's blog 1308

“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(中)

“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(中)

bitfan(数字世界一凡人)的专栏 5373

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(下)收藏 《 .NET 4.0网络开发入门之旅-- 我在“网” 中央》...

“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(下) 前一部分: IP 知多少?(中) 4. IP 终结点 现在介绍 .NET 网络开发中最重要的一个概念—— IP 终结点, .NET 基类库中使用 IPEndPoint 类型代表它。 要想理解它,还得从 TCP/IP 说起。 ...

爱.NET 133

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?

请访问以下链接看文章: “.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(上)“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(中)“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(下)

bitfan(数字世界一凡人)的专栏 1549

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

“.NET 4.0网络开发入门之旅系列文章”——IP知多少(上)

“.NET 4.0网络开发入门之旅系列文章”——IP知多少(上)

bitfan(数字世界一凡人)的专栏 9163

《.NET 4.0 网络开发入门之旅》系列文章导航

“.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(上) “.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(下) .NET 4.0网络开发入门之旅——我在“网” 中央 .NET 4.0网络开发入门之旅——我在“网” 中央(下) 《.NET 4.0网络开发入门之旅》4:与Socket的第一次“约会” 《.NET 4.0网络开发入门之旅》5:与Socket的...

一切从心开始 748

.NET 4.0网络开发入门之旅-- 我在“网” 中央(上)

.NET 4.0网络开发入门之旅--我在“网” 中央(上)

bitfan(数字世界一凡人)的专栏 1万+
上一篇: “.NET 4.0网络开发入门之旅系列文章”——IP知多少(上)
下一篇: “.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?
bitfan
博客等级 码龄26年 4298粉丝 243原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值