深入理解Socket API与TCP协议:网络编程基础与字节序解析 长沙seo优化需要做吗
栏目:广告资讯 发布时间:2026-01-15
[] [] 在 TCP/IP 协议里,“IP 地址加上 TCP 或者 UDP 端口号”能够唯一地标识网络通讯里的一个进程,“IP 地址与端口号相结合”就被称作

[]

[]

在 TCP/IP 协议里,“IP 地址加上 TCP 或者 UDP 端口号”能够唯一地标识网络通讯里的一个进程,“IP 地址与端口号相结合”就被称作。

在 TCP 协议里,建立连接的两个进程各自都有一个标识。这两个进程组成的 pair 能够唯一地标识一个连接。“插座”本身就有其特定含义,所以被用来描述网络连接的一对一关系。

TCP/IP 协议最早是在 BSD UNIX 上得以实现的。为 TCP/IP 协议所设计的应用层编程接口被称作。

[]

二、网络字节序

我们已知,内存中的多字节数据对于内存地址存在大端和小端的区别。磁盘文件中的多字节数据对于文件中的偏移地址也有大端小端之分。网络数据流同样具备大端小端之分。那么,怎样去定义网络数据流的地址呢?发送主机一般会把发送缓冲区里的数据依据内存地址从低到高的次序进行发出。接收主机则把从网络上接收到的字节依次存放在接收缓冲区中,同样是按照内存地址从低到高的顺序来保存。所以,对于网络数据流的地址要这样规定:先发出的那些数据对应的是低地址,而后发出的数据对应的是高地址。

TCP/IP 协议规定,网络数据流的字节序应采用大端字节序,也就是说在这种字节序中,低地址对应的字节是高字节。四十五节的 UDP 段格式中,地址 0 到 1 为 16 位的源端口号。若此端口号是 1000(0x3e8),那么地址 0 是 0x03,地址 1 是 0xe8,即先发送 0x03,接着发送 0xe8。在发送主机的缓冲区中,这 16 位也应是低地址存 0x03,高地址存 0xe8。如果发送主机是小端字节序,那么这 16 位会被这样解释,而非 1000。所以,发送主机在把 1000 填到发送缓冲区之前,需要进行字节序的转换。同样地,若接收主机是小端字节序,当接到 16 位的源端口号时,也需要做字节序的转换。而如果主机是大端字节序,无论是发送还是接收,都不需要进行转换。同样地,对于 32 位的 IP 地址,需要考虑网络字节序以及主机字节序方面的问题。

为让网络程序具备可移植性,让相同的 C 代码在大端计算机和小端计算机上编译后都能正常运转,能够调用以下这些库函数来进行网络字节序与主机字节序的转换。

<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="prettyprint"><code class=" hljs actionscript">#<span class="hljs-preprocessor"><span class="hljs-keyword">include</span> <a style='color:#0000CC;font-size:15px;' rpa/inet.h> 定义了一个名为 htonl 的函数,该函数的参数是一个 uint32_t 类型的 hostlong,函数的返回值也是 uint32_t 类型。</span> 这个函数名为 htons,它接收一个 16 位的主机短整型数值作为参数,然后进行相应的网络字节序转换操作,最终返回转换后的网络字节序的 16 位数值。 定义了一个名为 ntohl 的函数,该函数接收一个 uint32_t 类型的参数 netlong,并返回一个 uint32_t 类型的值。 定义一个函数 ntohs,它接收一个无符号 16 位整数类型的参数 netshort,函数返回值也为无符号 16 位整数类型。 h 表示host n 表示network l 表示<span class="hljs-number">32</span>位长整数 s 表示<span class="hljs-number">16</span>位短整数。 如果主机的字节序是小端的,那么这些函数会对参数进行相应的大小端转换之后再返回。如果主机的字节序是大端的,这些函数就不会进行转换,而是将参数原原本本地返回。</code></pre></p>

三、IP地址转换函数

早期使用的是一下函数:

<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="prettyprint"><code class=" hljs vala"><span class="hljs-preprocessor">#include <sys/socket.h></span> <span class="hljs-preprocessor">#include <netinet/in.h></span> <span class="hljs-preprocessor">#include <a style='color:#0000CC;font-size:15px;' rpa/inet.h></span> <span class="hljs-keyword">int</span> inet_aton(<span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *cp, <span class="hljs-keyword">struct</span> in_addr *inp); in_addr_t inet_addr(<span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *cp); <span class="hljs-keyword">char</span> *inet_ntoa(<span class="hljs-keyword">struct</span> in_addr in);

只能处理IPv4的ip地址 不可重入函数 注意参数是<span class="hljs-keyword">struct</span> in_addr</code></pre></p>

现在多使用的是:

<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="prettyprint"><code class=" hljs vala"><span class="hljs-preprocessor">#include <a style='color:#0000CC;font-size:15px;' rpa/inet.h></span> <span class="hljs-keyword">int</span> inet_pton(<span class="hljs-keyword">int</span> af, <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *src, <span class="hljs-keyword">void</span> *dst);  <span class="hljs-comment">//将字符串转换为网络地址</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *inet_ntop(<span class="hljs-keyword">int</span> af, <span class="hljs-keyword">const</span> <span class="hljs-keyword">void</span> *src, <span class="hljs-keyword">char</span> *dst, socklen_t size);  <span class="hljs-comment">//将网络地址转换为字符串</span> 支持IPv4和IPv6 可重入函数</code></pre></p>

其中,它不仅能够转换 IPv4 的相关内容,还能够转换 IPv6 的相关内容,正因如此,其函数接口为 void *。

四、数据结构

很多网络编程函数诞生于 IPv4 协议之前,当时使用的是结构体。为了实现向前兼容,现在这些函数退化成了(void *)的作用,即传递一个地址给函数。而这个函数具体是哪种类型,由地址族来确定。之后,函数内部会再将其强制类型转化为所需的地址类型。

<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword">struct</span> sockaddr { sa_family_t sa_family;  <span class="hljs-comment">地址族,其格式为 AF_xxx 。</span> <span class="hljs-keyword">char</span> sa_data[<span class="hljs-number">14</span>]; <span class="hljs-comment">协议地址为 14 字节。</span> }; <span class="hljs-keyword">struct</span> sockaddr_in { 内核的地址族类型为 sin_family;sin_family 是一个特定的地址族类型;该地址族类型被用于内核相关的操作中;它在网络编程等领域有重要作用。<span class="hljs-comment">/* Address family */</span> __be16 sin_port;<span class="hljs-comment">/* Port number 端口号*/</span> <span class="hljs-keyword">struct</span> in_addr sin_addr; <span class="hljs-comment">/* Internet address IP地址*/</span> <span class="hljs-comment">将其填充至 `struct sockaddr` 的大小。</span> unsigned <span class="hljs-keyword">char</span> __pad[__SOCK_SIZE__ - <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">short</span> <span class="hljs-keyword">int</span>) - <span class="hljs-keyword">sizeof</span>(unsigned <span class="hljs-keyword">short</span> <span class="hljs-keyword">int</span>) - <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">struct</span> in_addr)]; }; <span class="hljs-comment">/* Internet address. */</span> <span class="hljs-keyword">struct</span> in_addr { __be32 s_addr; <span class="hljs-comment">// 32位地址</span> };

<span class="hljs-keyword">struct</span> sockaddr_in6 { unsigned <span class="hljs-keyword">short</span> <span class="hljs-keyword">int</span> sin6_family;<span class="hljs-comment">/* AF_INET6 */</span> __be16 sin6_port;  <span class="hljs-comment">关于运输层的端口号</span> __be32 sin6_flowinfo; <span class="hljs-comment">IPv6 流信息的控制属性。</span> <span class="hljs-keyword">struct</span> in6_addr sin6_addr;  <span class="hljs-comment">/* IPv6 addressip地址128位*/</span> __u32 sin6_scope_id;  <span class="hljs-comment">范围标识(在 RFC2553 中是新的)</span> }; <span class="hljs-keyword">struct</span> in6_addr { union {   __u8u6_addr8[<span class="hljs-number">16</span>]; <span class="hljs-comment">// 可以使用16个8位的地址</span>   __be16 u6_addr16[<span class="hljs-number">8</span>]; <span class="hljs-comment">// 8个16位地址</span>   __be32 u6_addr32[<span class="hljs-number">4</span>]; <span class="hljs-comment">// 4个32位地址</span> } in6_u; <span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> s6_addr in6_u.u6_addr8</span> <span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> s6_addr16 in6_u.u6_addr16</span> <span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> s6_addr32 in6_u.u6_addr32</span> }; <span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> UNIX_PATH_MAX 108</span> <span class="hljs-keyword">struct</span> sockaddr_un { sun_family 属于 __kernel_sa_family_t 类型。<span class="hljs-comment">/* AF_UNIX */</span> <span class="hljs-keyword">char</span> sun_path[UNIX_PATH_MAX];<span class="hljs-comment">/* pathname */</span> };</code></pre></p>

IPv4 的地址格式在 /in.h 中被定义,它用结构体来表示,其中包含 16 位端口号以及 32 位 IP 地址。IPv6 的地址格式也在 /in.h 中被定义,它用结构体来表示,此结构体包含 16 位端口号、128 位 IP 地址和一些控制字段。UNIX 的地址格式在 sys/un.h 中被定义,用 sock-结构体来表示。各种地址结构体的开头是相同的。其前 16 位表示整个结构体的长度,不过并非所有 UNIX 的实现都有长度字段,像 Linux 就没有。而后 16 位表示地址类型。IPv4 的地址类型定义为常数,IPv6 的地址类型定义为常数,Unix 的地址类型也定义为常数。这样,只要能够获取到某种结构体的首地址,并且无需知晓具体属于哪种类型的结构体,就能够依据地址类型字段来确定结构体中的内容。API 能够接受各种类型的结构体指针作为参数,像 bind 等函数就是如此。这些函数的参数需设计为 void 类型,这样就能接受各种类型的指针。然而,sock API 的实现早于 ANSI C 标准化,在那时候还不存在 void 类型,所以这些函数的参数都用 *类型来表示,在传递参数之前需要进行强制类型转换,例如:

<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword">struct</span> sockaddr_in servaddr; <span class="hljs-comment">/* initialize servaddr */</span> bind(listen_fd, (<span class="hljs-keyword">struct</span> sockaddr *)&servaddr, <span class="hljs-keyword">sizeof</span>(servaddr));</code></pre></p>


# 戏曲宣传推广营销  # 放在  # 黄冈抖音营销推广项目  # 宁波seo搜索优化推广  # 郴州关键词排名软件  # 游戏网站广告推广  # 南昌seo夹缝网  # b2b平台整合营销推广  # 宁波知名网站推广有哪些  # 青龙网站推广价格  # seo快速金手指下拉四  # 哪种类型  # 望江网站建设企业  # 网站推广被骗怎么办知乎  # 推广营销的新思路  # 玉溪平台seo优化  # ktv抖音营销推广思路  # 论坛网站建设与维护教材  # 增城平台整合营销推广  # 和平区口碑营销推广公司  # 忻州抖音营销推广招聘  # 绵阳网站制作建设  # 转换为  # 深入理解Socket API与TCP协议  # 网络编程基础与字节序解析  # 的是  # 端口号  # 多字  # 是一个  # 都有  # 相关内容  # 将其  # 一地  # 深入理解Socket API与TCP协议:网络编程基础与字节序解析  # 之分  # 区中  # 它用  # 返回值  # 网络编程  # 网络地址  # 是在  # 也有  # 成了 


相关文章: 徐州网站 *** ,打造专业、高效的在线平台,徐州专业网站定制,构建高效在线服务平台  遵义网站 *** ,打造专业、高效、个性化的企业网站,遵义企业网站定制,专业高效,个性定制服务,遵义企业网站定制,专业高效,个性定制,打造卓越 *** 形象  2025年抖音算法升级影响几何?下拉词优化实战策略揭秘   免费SEO网站诊断,揭秘网站优化中的秘密武器,免费SEO网站诊断,解锁网站优化神秘武器  1月21日微信ios端8.0上线!新表情特效及背后功能揭秘?   微信怎么单独隐藏好友信息?教你3种常用方法,速来了解   柠檬美名众多受欢迎,宁光院长推荐成抢手货,医疗妙用早有记载   大型网站开发的挑战与策略,构建高效、稳定的在线平台,高效稳定在线平台构建,大型网站开发挑战与应对策略  沈阳网站,打造东北地区互联网新地标,沈阳,东北互联网新地标崛起  飞利浦维修网点查询指南,官方网站与移动应用轻松搞定   浙大儿院推出智能就诊小程序,发热就诊时间缩短1/3   青岛网站 *** ,打造专业、高效的在线平台,青岛专业高效网站定制服务  1.76 怀旧版传奇网页版邀你开启新篇章!中年女人微信哪些字暗示动情?   第58届金钟奖主视觉发布:“火星撞地球?”  网站服务器租用,高效稳定的 *** 基石,助力企业数字化转型,高效 *** 基石,网站服务器租用助力企业数字化转型新篇章,网站服务器租用,企业数字化转型的 *** 基石新篇章  郑州网站,城市发展的新引擎——探索郑州 *** 世界的无限可能,郑州 *** 新纪元,网站助力城市腾飞  微信这五个功能设置错啦!三个该关却开着,两个该开却关着?   山东网站 *** ,打造企业 *** 品牌的新引擎,山东企业 *** 品牌重塑,网站 *** 新引擎驱动发展  深圳首批可售性人才住房项目公布,六个项目共4422套房源   中小企业网站建设,提升品牌形象,拓展 *** 市场的关键一步,中小企业网站建设,塑造品牌形象,开拓 *** 市场的核心策略  数字化支付普及下,如何取消微信指纹支付?看这里   微信朋友圈被屏蔽?这些间接查看方法你知道吗?   青岛网站推广,助力企业线上崛起的黄金策略,青岛企业线上腾飞之道,网站推广黄金策略全解析  Win10纯净版64位系统无法连无线WiFi?原因及解决办法来啦   “情绪价值”才是消费驱动力  合肥网站 *** ,打造个性化企业网站,助力企业品牌升级,合肥定制化企业网站建设,助力品牌形象焕新升级  2025年抖音超长知识视频成现象级爆款,你看过吗?   无锡网站推广,助力企业打造线上品牌,抢占市场先机,无锡网站推广,企业线上品牌建设与市场抢占策略  武汉地区专业网站建设公司盘点,助力企业数字化转型,武汉专业网站建设公司榜单,助力企业数字化升级之路  爱秀|直播|:安卓热门分享平台,集多样功能与独特体验于一身   微信有多火?每天超10亿人打开,使用率近80%   用select2实现可搜索下拉框:开发难题与解决之道   地主来了2019微信赢红包版,经典玩法与炫酷特效等你来   手机如何进入抖音网页版?入口位置及|直播|开启方法介绍   Excel表格设置下拉菜单选项的多种方法,你知道几种?   成都网站建设公司,助力企业互联网转型,打造专业品牌形象,成都专业网站建设,赋能企业互联网升级与品牌塑造  南京刘大爷购长虹空调,享高效售后,看长虹如何提升服务质量?   江苏徐州警方破特大网络贩毒案,抓获140余人缴获大量毒品   你喜欢吃柠檬吗?它对健康有5个好处,这2类人要少吃或不吃   长安网站建设,打造专业、高效、个性化的 *** 平台,长安专业定制,高效个性化网站建设服务,长安专业定制,高效个性化网站建设助力企业 *** 腾飞  2月23日网商银行安全检验技术与系统入选国家级项目,有何亮点?   网页版传世新开精选内容!微信神秘信号,判断女人是否想你?   看看今年35℃的立秋品牌海报!  手机功能强大,以识别图片文字为例讲讲具体方法   手机录音怎么轻松传到微信?一步步教你操作方法   从零开始,全面解析如何做网站,零基础入门,网站建设全攻略  抖音网页版使用指南:首次访问提示及登录、播放等注意事项   北海网站建设,助力企业拓展线上市场,抢占发展先机,北海企业线上拓展新引擎,专业网站建设助力抢占市场先机  手机丢失微信聊天记录咋找回?三步操作来帮您   淮南网站建设,助力企业腾飞的新引擎,淮南企业腾飞新动力,专业网站建设服务 


相关栏目: 【 广告资讯90366 】 【 广告推广18483 】 【 广告优化154267 】 【 广告营销46464