socket的引入是为了解决不同计算机间进程间通讯的问题。
端口是TCP/IP合同中的概念,描述的是TCP合同上的对应的应用,可以理解为基于TCP的服务,或则说系统进程!如右图,FTP就须要占用特定的TCP端口。
而socket呢,是网路编程中的概念,对TCP/IP合同进行了具象和实现,并为应用层提供插口。这儿的应用A,可以是FTP应用,它属于用户进程,通过socket与内核中的网路合同栈进行交互。
socket是核心,是枢纽,是进程与网路构建关系的必经之路!
1.内核是怎样将数据包转发至socket的呢?
网路数据首先抵达网卡,之后步入内核,由网路合同栈去处理,这么内核是怎样进行数据分发的呢?它如何晓得该怎么把数据交给特定的用户进程呢?
这时,就须要socket发挥作用了!
socket中储存了特定的四元组:源ip+port,目的ip+port;
1> bind 到特定 ip 和 port 的socket 对应 [src ip, src port) (*, *)] ; 2> connect 到特定目的ip+port 的 socket 对应 [src ip, src port) (dst ip, dst port)]; 3> accept 返回了的 socket 对应 [src ip, src port) (dst ip, dst port)];
这么内核按照数据包的四元组信息,就可以锁定特定的socket了。并可,系统中所有socket中的四元组信息,必将惟一,不可能重复!
2进程与socket的关系是如何的呢?
每位进程,在内核中都有一个表,保存了该进程申请并占用的所有socket描述符,在进程看来,socket虽然跟文件也没有哪些不同,只不过通过描述符获得的对象不同而已,插口对应的系统调用也不同。
这么进程跟socket是一一对应的吗?
虽然不然,socket是一种资源,如同文件一样,一个进程打开了,另一个进程也可以用,只不过socket比较特殊而已。
理论上,还能通过sendmsg将socket描述符传递给其他进程,这样其他进程就可以调用该描述符的插口了。这些场景确实不如何会用到,也没有进行实际验证。
其实,母子进程间,还有线程间,进行socket的共享,是比较常见的。
3进程与端口
进程与端口,虽然并没有哪些直接或必然的关系,关键还是socket!
wireshark抓包查看tcp合同数据包详情:
总结
socket的本质是一种资源linux内核中网络协议的设计与实现,它包含了端到端的四元组信息,拿来标示数据包的归属。为此,虽然tcp合同的端标语只有65535个,而且进程可拥有的socket数据却不限于此(受限于进程最大文件描述符数据);
PS:一、端口简介
随着计算机网路技术的发展,原先数学上的插口(如鼠标、鼠标、网卡、显示卡等输入/输出插口)已不能满足网路通讯的要求,TCP/IP合同作为网路通讯的标准合同就解决了这个通讯困局。TCP/IP合同集成到操作系统的内核中,这就相当于在操作系统中引入了一种新的输入/输出插口技术,由于在TCP/IP合同中引入了一种称之为Socket(套接字)应用程序插口。有了这样一种插口技术,一台计算机就可以通过软件的形式与任何一台具有Socket插口的计算机进行通讯。端口在计算机编程上也就是Socket插口。
有了这种端口后,这种端口又是怎样工作呢?诸如一台服务器为何可以同时是Web服务器,也可以是FTP服务器,还可以是短信服务器等等呢?其中一个很重要的缘由是各类服务采用不同的端口分别提供不同的服务,例如:一般TCP/IP合同规定Web采用80号端口,FTP采用21号端口等,而电邮服务器是采用25号端口。这样,通过不同端口,计算机就可以与外界进行互不干扰的通讯。
据专家们剖析,服务器端口数最大可以有65535个,然而实际上常用的端口才几十个,由此可以看出未定义的端口相当多。这是这么多黑客程序都可以采用某种方式,定义出一个特殊的端口来达到入侵的目的的诱因所在。为了定义出这个端口,就要借助某种程序在计算机启动之前手动加载到显存,强行控制计算机打开那种特殊的端口。这个程序就是侧门程序linux内核中网络协议的设计与实现,这种侧门程序就是常说的木马程序。简单的说,这种木马程序在入侵前是先通过某种手段在一台个人计算机中植入一个程序,打开某个(些)特定的端口,也称侧门(BackDoor),使这台计算机弄成一台开放性极高(用户拥有极高权限)的FTP服务器,之后从侧门就可以达到侵入的目的。
二、端口的分类
端口的分类依据其参考对象不同有不同界定方式,倘若从端口的性质来分,一般可以分为以下三类:
(1)公认端口(WellKnownPorts):这类端口也常称之为常用端口。这类端口的端标语从0到1024,它们紧密绑定于一些特定的服务。一般这种端口的通讯明晰表明了某种服务的合同,这些端口是不可再重新定义它的作用对象。诸如:80端口实际上总是HTTP通讯所使用的,而23号端口则是Telnet服务专用的。这种端口一般不会像木马这样的黑客程序借助。
(2)注册端口(RegisteredPorts):端标语从1025到49151。它们松散地绑定于一些服务。也是说有许多服务绑定于这种端口,这种端口同样用于许多其他目的。这种端口多数没有明晰的定义服务对象,不同程序可依照实际须要自己定义,如前面要介绍的远程控制软件和木马程序中就会有这种端口的定义的。记住那些常见的程序端口在木马程序的防护和查杀上是十分有必要的。常见木马所使用的端口在前面将有详尽的列表。
(3)动态和/或私有端口(Dynamicand/orPrivatePorts):端标语从49152到65535。理论上,不应把常用服务分配在这种端口上。实际上,有些较为特殊的程序,非常是一些木马程序就特别喜欢用这种端口,由于这种端口往往不被引发注意,容易隐蔽。
倘若依照所提供的服务形式的不同,端口又可分为TCP合同端口和UDP合同端口两种。由于计算机之间相互通信通常采用这两种通讯合同。上面所介绍的联接方法是一种直接与接收方进行的联接,发送信息之后,可以确认信息是否抵达,这些方法大多采用TCP合同;另一种是不是直接与接收方进行联接,只管把信息放到网上发出去,而不管信息是否抵达,也就是上面所介绍的无联接形式。这些方法大多采用UDP合同,IP合同也是一种无联接形式。对应使用以上这两种通讯合同的服务所提供的端口,也就分为TCP合同端口和UDP合同端口。
使用TCP合同的常见端口主要有以下几种:
(1)FTP:定义了文件传输合同,使用21端口。常说某甲计算机开了FTP服务便是启动了文件传输服务。下载文件,上传主页,都要用到FTP服务。
(2)Telnet:它是一种用于远程登录的端口,用户可以以自己的身分远程联接到计算机上,通过这些端口可以提供一种基于DOS模式下的通讯服务。如先前的BBS是纯字符界面的,支持BBS的服务器将23端口打开,对外提供服务。
(3)SMTP:定义了简单电邮传送合同,如今好多电邮服务器都用的是这个合同,用于发送短信。如常见的免费短信服务中用的就是这个短信服务端口,所以在电子电邮设置中常见到有如此SMTP端口设置这个栏,服务器开放的是25号端口。
socket介绍
socket为内核对象,由操作系统内核来维护其缓冲区,引用计数,而且可以在多个进程中使用。至于称它为“句柄”“文件描述符”都是一样的,它只不过是内核开放给用户进程使用的整数而已。
socket()创建了一个socket内核对象。accept或则connect后,才可以对socket句柄读写。由于只有在connect或则bind,listen,accept后就会设置好socket内核对象上面的ip和端口。
在使用socket编程时,我们都晓得在网路通讯曾经首先要完善联接,而联接的完善是通过对socket的一些操作来完成的。这么,构建联接的过程大致可以分为以下几步:
1)构建socket套接字。
2)给套接字赋于地址,这个地址不是一般的网路地址的概念。
3)构建socket联接。
以下详尽解释1.构建socket套接字。
使用socket构建套接字的时侯,我们实际上是构建了一个数据结构。这个数据结构最主要的信息是指定了联接的种类和使用的合同,再者还有一些关于联接队列操作的结构数组(这儿就先不涉及她们了)。
当我们使用socket函数之后,假如成功的话会返回一个int型的描述符,它指向后面那种被维护在内核里的socket数据结构。我们的任何操作都是通过这个描述符而作用到哪个数据结构上的。这如同是我们在构建一个文件后得到一个文件描述符一样,对文件的操作都是通过文件描述符来进行的,而不是直接作用到inode数据结构上。我之所以用文件描述符举例,是由于socket数据结构也是和inode数据结构密切相关,它不是独立存在于内核中的,而是坐落一个VFSinode结构中。所以,有一些比较具象的特点linux系统,我们可以用文件操作来不恰当的进行类比以加深理解。
如前所述,当构建了这个套接字之后,我们可以获得一个象文件描述符那样的套接字描述符。就像我们对文件进行操作那样linux学习,我们可以通过向套接字上面写数据将数据传送到我们指定的地方,这个地方可以是远端的主机,也可以是本地的主机。假如你有兴趣的话,还可以用socket机制来实现IPC,不过效率比较低,试试也就行了(没有试过)。
2.给套接字赋于地址。
根据构建套接字的目的不同,赋于套接字地址的方法有两种:服务器端使用bind,顾客端使用connetc。
Bind:
我们都晓得,只要使用IP,prot就可以分辨一个tcp/ip联接(其实这个联接指的是一个联接通道,假如要分辨特定的主机间的联接,还须要第三个属性hostname)。
我们可以使用bind函数来为一个使用在服务器端类库中的套接字赋于通讯的地址和端口。
在这儿我们称通讯的IP地址和端口合上去构成了一个socket地址,而指定一个socket使用特定的IP和port组合来进行通行的过程就是赋于这个socket一个地址。要赋于socket地址,就得使用一个数据结构来指明特定的socket地址,这个数据结构就是structsockaddr。对它的使用我就不说了,由于这篇文档的目的是澄清概念而不是说明使用方式。Bind函数的作用就是将这个特定的标明有socket地址信息的数据结构和socket套接字联系上去,即赋于这个套接字一个地址。并且在具体实现上,她们两个是如何联系在一起的,我还不晓得。
一个特定的socket的地址的生命期是bind成功之后到联接断掉前。你可以构建一个socket数据结构和socket地址的数据结构,并且在没有bind原先她们两个是没有关系的,在bind之后她们两个才有了关系。这些关系仍然维持到联接的结束,当一个联接结束时,socket数据结构和socket地址的数据结构还都存在,而且她们两个早已没有关系了。假如你要是用这个套接字在socket地址上重新进行联接时,需重新bind她们两个。再标明一次,我说的这个联接是一个联接通道,而不是特定的主机之间的联接。
Bind指定的IP一般是本地IP(通常不非常指定,而使用INADDR_ANY来申明),而最主要的作用是指定端口。在服务器端的socket进行了bind之后就是用listen来在这个socket地址上打算进行联接。
connect:
对于顾客端来说,是不会使用bind的(并不是不能用,但没哪些意义),她们会通过connet函数来构建socket和socket地址之间的关系。其中的socket地址是它想要联接的服务器端的socket地址。在connect构建socket和socket地址三者关系的同时,它也在尝试着完善远端的联接。
3.构建socket联接。
对于打算构建一个联接,服务器端要两个步骤:bind,listen;顾客端一个步骤:connct。假如服务器端accept一个connect,而顾客端得到了这个accept的确认,这么一个联接就完善了。
本文原创地址://q13zd.cn/jcywljlgxdbj.html编辑:刘遄,审核员:暂无