Accept是又产生一个Socket端口吗? -程序员宅基地

技术标签: 服务端  socket  

Accept是又产生一个Socket端口吗?

      要写网络程序就必须用Socket,这是程序员都知道的。而且,面试的时候,我们也会问对方会不会Socket编程?一般来说,很多人都会说,Socket编程基本就是listen,accept以及send,write等几个基本的操作。是的,就跟常见的文件操作一样,只要写过就一定知道。

 

      对于网络编程,我们也言必称TCP/IP,似乎其它网络协议已经不存在了。对于TCP/IP,我们还知道TCP和UDP,前者可以保证数据的正确和可靠性,后者则允许数据丢失。最后,我们还知道,在建立连接前,必须知道对方的IP地址和端口号。除此,普通的程序员就不会知道太多了,很多时候这些知识已经够用了。最多,写服务程序的时候,会使用多线程来处理并发访问。

 

我们还知道如下几个事实:

     1.一个指定的端口号不能被多个程序共用。比如,如果IIS占用了80端口,那么Apache就不能也用80端口了。

     2.很多防火墙只允许特定目标端口的数据包通过。

     3.服务程序在listen某个端口并accept某个连接请求后,会生成一个新的socket来对该请求进行处理。

 

     于是,一个困惑了我很久的问题就产生了。如果一个socket创建后并与80端口绑定后,是否就意味着该socket占用了80端口呢?如果是这样的,那么当其accept一个请求后,生成的新的socket到底使用的是什么端口呢(我一直以为系统会默认给其分配一个空闲的端口号)?如果是一个空闲的端口,那一定不是80端口了,于是以后的TCP数据包的目标端口就不是80了--防火墙一定会阻止其通过的!实际上,我们可以看到,防火墙并没有阻止这样的连接,而且这是最常见的连接请求和处理方式。我的不解就是,为什么防火墙没有阻止这样的连接?它是如何判定那条连接是因为connet80端口而生成的?是不是TCP数据包里有什么特别的标志?或者防火墙记住了什么东西?

 

      后来,我又仔细研读了TCP/IP的协议栈的原理,对很多概念有了更深刻的认识。比如,在TCP和UDP同属于传输层,共同架设在IP层(网络层)之上。而IP层主要负责的是在节点之间(End to End)的数据包传送,这里的节点是一台网络设备,比如计算机。因为IP层只负责把数据送到节点,而不能区分上面的不同应用,所以TCP和UDP协议在其基础上加入了端口的信息,端口于是标识的是一个节点上的一个应用。除了增加端口信息,UPD协议基本就没有对IP层的数据进行任何的处理了。而TCP协议还加入了更加复杂的传输控制,比如滑动的数据发送窗口(Slice Window),以及接收确认和重发机制,以达到数据的可靠传送。不管应用层看到的是怎样一个稳定的TCP数据流,下面传送的都是一个个的IP数据包,需要由TCP协议来进行数据重组。

 

      所以,我有理由怀疑,防火墙并没有足够的信息判断TCP数据包的更多信息,除了IP地址和端口号。而且,我们也看到,所谓的端口,是为了区分不同的应用的,以在不同的IP包来到的时候能够正确转发。

 

     TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。就像操作系统会提供标准的编程接口,比如Win32编程接口一样,TCP/IP也必须对外提供编程接口,这就是Socket编程接口--原来是这么回事啊!

 

在Socket编程接口里,设计者提出了一个很重要的概念,那就是socket。这个socket跟文件句柄很相似,实际上在BSD系统里就是跟文件句柄一样存放在一样的进程句柄表里。这个socket其实是一个序号,表示其在句柄表中的位置。这一点,我们已经见过很多了,比如文件句柄,窗口句柄等等。这些句柄,其实是代表了系统中的某些特定的对象,用于在各种函数中作为参数传入,以对特定的对象进行操作--这其实是C语言的问题,在C++语言里,这个句柄其实就是this指针,实际就是对象指针啦。

 

现在我们知道,socket跟TCP/IP并没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以,socket的出现只是可以更方便的使用TCP/IP协议栈而已,其对TCP/IP进行了抽象,形成了几个最基本的函数接口。比如create,listen,accept,connect,read和write等等。

 

现在我们明白,如果一个程序创建了一个socket,并让其监听80端口,其实是向TCP/IP协议栈声明了其对80端口的占有。以后,所有目标是80端口的TCP数据包都会转发给该程序(这里的程序,因为使用的是Socket编程接口,所以首先由Socket层来处理)。所谓accept函数,其实抽象的是TCP的连接建立过程。accept函数返回的新socket其实指代的是本次创建的连接,而一个连接是包括两部分信息的,一个是源IP和源端口,另一个是宿IP和宿端口。所以,accept可以产生多个不同的socket,而这些socket里包含的宿IP和宿端口是不变的,变化的只是源IP和源端口。这样的话,这些socket宿端口就可以都是80,而Socket层还是能根据源/宿对来准确地分辨出IP包和socket的归属关系,从而完成对TCP/IP协议的操作封装!而同时,放火墙的对IP包的处理规则也是清晰明了,不存在前面设想的种种复杂的情形。

 

明白socket只是对TCP/IP协议栈操作的抽象,而不是简单的映射关系,这很重要!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kenkao/article/details/84231392

智能推荐

【drawio笔记】更改文字书写的方向_drawio竖排文本-程序员宅基地

文章浏览阅读2.3w次,点赞13次,收藏3次。介绍在drawio中如何更改文字书写的方向,还有垂直与水平的切换。更改书写方向在绘图画布上选择形状。在右侧格式面板的 Text 选项卡中,单击 Writing Direction 下拉列表,然后选择另一个方向。要在垂直和水平之间切换,请单击 Vertical切换按钮。本文章翻译自https://www.diagrams.net/doc/faq/writing-direction-change..._drawio竖排文本

TI-BLE协议栈的GATT学习笔记-1_gatt_client_charac_cfg_uuid-程序员宅基地

文章浏览阅读6k次。由于还没有看具体的代码,难免会有理解错误的地方,本着共同学习的态度和大家交流探讨;在BLE中;GATT是焦点;在链路层(LL),可以把设备分为主机和从机,从机广播,主机发起连接;在GAP层, 可以把设备分为中心设备和外围设备; 在GATT层, 可以把设备分为服务端和客户端;我们需要记住一点就是,这些划分相互是不受影响的;在说GATT之前_gatt_client_charac_cfg_uuid

Java可变参数Varargs-程序员宅基地

文章浏览阅读85次。J2SE 1.5中提供了Varargs机制,“Varargs”是“variable number of arguments”的意思,允许直接定义能和不定个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。只要在参数定义的括号里写上一个形参的“类型”与“参数名”之间加上三个连续的“.”(即“...”,英文里的句中省略号),就可以让它和不确定个实参相匹配。而一个带有这样..._java中集合怎么转为varargs(可变参数)

【面经笔记】STL库的介绍_c++stl库的面经-程序员宅基地

文章浏览阅读533次。STL库的介绍STL**六大组件**简介1、容器(Containers):各种数据结构,如Vector,List,Deque,Set,Map,用来存放数据,STL容器是一种类模板。2、算法(Algorithms):各种常用算法如Sort,Search,Copy,Erase,从实现的角度来看,STL算法是一种函数模板。3、迭代器(Iterators):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,_c++stl库的面经

【蓝桥杯选拔赛真题56】Scratch画笔涂色 少儿编程scratch图形化编程 蓝桥杯选拔赛真题讲解_scratch 做一支笔,红黄蓝三种颜色-程序员宅基地

文章浏览阅读1.4k次。scratch画笔涂色第十四届青少年蓝桥杯scratch编程选拔赛Stema比赛真题一、题目要求画笔涂色编程实现1). 运行程序,角色、背景如图所示;_scratch 做一支笔,红黄蓝三种颜色

Qt for winrt结合Winrt API开发_qt winrt-程序员宅基地

文章浏览阅读1.5k次。Qt for winrt结合Winrt API开发Qt for winrt开发的程序即是windows应用商店程序,可以转换成vs2013能加载的项目,随即可以调用winrt api控制系统设备、资源。 Vs2013加载了Qt项目后,还需配置项目属性使用windows运行时库扩展,随后才能调用winrt api。 一、调用摄像头要调用摄像头可用到Windows::M_qt winrt

随便推点

在PlatformIO使用标准库开发STM32(解决冲突)_platformio stm32标准库-程序员宅基地

文章浏览阅读3.7k次,点赞7次,收藏16次。在PlatformIO使用CMSIS标准库开发STM32(解决冲突)博主也是刚开始学stm32,觉得keil不好看,想用更加熟悉的VS Code来开发STM32。我学的教材用的是标准库,可是网上大部分教程都是针对HAL库的。终于找到一篇教程之后,发现复制进去的库在链接时会和PlatformIO自带的库冲突。这是我参考的文章:STM32F103 在VSCode下使用Platform IO 基于CMSIS标准库函数开发 - Zennn - 博客园 (cnblogs.com)研究一番之后,是因为syst_platformio stm32标准库

Nagios系统监控的基本安装和配置过程_nagios配置-程序员宅基地

文章浏览阅读111次。现在这篇文章中,我们详细介绍了Nagios系统监控的基本安装和配置过程。首先,我们安装了Nagios的核心组件,包括必要的依赖软件包。接下来,我们启动了Apache服务器和Nagios服务,并配置了防火墙以允许访问。Nagios是一款强大的开源系统监控工具,可以帮助管理员实时监测服务器和网络设备的状态。如果您的服务器开启了防火墙,需要允许Nagios和Apache的访问。首先,我们需要安装Nagios的核心组件。一旦您成功登录到Nagios的Web界面,您可以开始添加要监控的主机和服务。_nagios配置

内存自建自动测试:Memory BIST(Built-inSelfTest)-程序员宅基地

文章浏览阅读1.4w次,点赞9次,收藏83次。参考链接:https://www.cnblogs.com/uiojhi/p/9430505.htmlhttps://www.docin.com/p-1653581041.htmlhttp://www.docin.com/p-1825745255.htmlATE:ATE是Automatic Test Equipment的缩写,根据客户的测试要求、图纸及参考方案,采用MCU、PLC、PC基于VB、VC开发平台,利用TestStand&am..._memory bist

HTTP状态 404 - 未找到 类型 状态报告 描述 源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示。_http状态 404 - 未找到 类型 状态报告 描述 源服务器未能找到目标资源的表示或者-程序员宅基地

文章浏览阅读1.9w次。​ <form action="/login" method="post">​去掉"/"即可_http状态 404 - 未找到 类型 状态报告 描述 源服务器未能找到目标资源的表示或者

中小学创客教室建设规划_中小学航空航天科技创客教室建设-程序员宅基地

文章浏览阅读807次。何为创客教室对于很多中小学教育来说并不陌生,传统教育内教室是只提供黑板、电子白板、幻灯片等多媒体器材设施,而中小学创客教室的出现改变了原本效率不高的课堂教学模式,格物斯坦机器人关心每位中小学热爱机器人编程以及传授机器人编程课的创客老师,创客教室里因为有了这样的师生而精彩。中小学创客教室既要注重硬件设施的建设,又要注重软性课程资源的开发和打造,所以中小学创客教室应具备普适性的创新教育职能。通过引入先进科学教具,整合校内外课程资源,研发专业课程体系,引进优质课程资源,确保建设模式与课程内容相匹配,能够满足教学_中小学航空航天科技创客教室建设

latex学习 day2_elsarticle-num-程序员宅基地

文章浏览阅读1.1k次。C:\Users\Administrator>texdoc texdocC:\Users\Administrator>texdoc article第一句代码直接打开了文件texdoc.pdf, 路径D:\texlive\2019\texmf-dist\doc\support\texdoc,这里还有编译生成texdoc.pdf文件的源码texdoc.tex第二句代码直接打开了cl..._elsarticle-num