有没有SOCKET,网卡都会接收数据。网卡工作在数据链路层,它只认识链路上邻近的点。它甚至不认识它隔壁的隔壁,它又怎么可能知道传输层的信息呢(起点与终点,是传输层的信息)?。。。传输层的信息,只能由传输层来处理!
IP层存在同样的问题。因为它也“活(动)”在网络层。它也不处理,同样地它也不能处理本来位于第四层即传输层的与传输相关的信息。。当然,如果一个网络节点硬要处理它,当然也是可以的。因为高层的信息是被低层的信息所包裹着的。只是恐怕一般的机构没有这样的实力来做这个事情。因为那么多人的信息,凭一己之力,怎么可能或者什么时候才能读得完?!
由此可见,SOCKET只是整个网络系统的附属品。它并没有任何主“动”的能力。主“动”的能力全部把握在第三层以下。第四层及其以上各层,都不具有“动”的能力。。。。一个数据包,如果被传到了第四层,其实也就失去了其的动力,停止了其在网络上的旅行。因为它已经到了。
这意味着,如果从网络上随处给某个“SOCKET”发一个数据包,不管这个SOCKET是否真实存在,即:不管在内存中是否已经建立其对应的SOCKET对象,这个包都会被如期送达(如果至少这个“半相关”存在,并且假设网络通畅的话)。也就是说,以任一SOCKET地址为目标的数据包的到达与否,与在主机中是否建立相关的SOCKET对象是没有关系的。
当然没有关系!
一个SOCKET对象只是活在本地内存中的对象,而真正的数据包却是来自于网络层I/O操作。网络I/O工作在传输层以下,这就决定了网络I/O工作在SOCKET对象所在层即传输层以前,这就决定了与SOCKET工作有关的任何系统级或用户级操作,都是发生在包到达以后(在接收的时候)。
真正的发送工作更与SOCKET对象基本上没有任何关系。因为操作系统只要随便往一个IP包中填入一个地址与端口都可以把包给发出去(也许不填也可以。。。因为源地址显然地并不是路由所需要的必要信息)。
。。。
意思是,SOCKET并不是动者。通信能力的提供者是操作系统。操作系统提供所有的协议服务。这种服务,通过SOCKET暴露给应用程序的开发者。首先,在机器级别是不存在对象这个概念的。机器只知道两样事情:数据与指令。在运行时,SOCKET的代码是不存在的。存在的是SOCKET的代码的编译后指令。方法或函数在二进制世界其实只是指令集的界符。函数的概念其实只是为了区分运行时的指令集。机器需要这样的信息对运行时指令集进行划分。否则机器就只能执行顺序程序了(在原语言不提供其它的代码边界或标识的情况下)。源码的价值也在于其的二进制代表。否则其就不可能具有任何意义。这是可以使用SOCKET API来讨论网络通信的原因。因为它拥有真正的二进制代表。当我使用API这个词的时候,它的背后其实是它所代表的机器级指令。。。但是无论如何,SOCKET的API并不是通信的执行者。通信的执行者是操作系统的协议层。SOCKET API只是应用程序与操作系统的协议层之间的一座桥梁。它可以被看作应用程序与操作系统的通信服务之间的协议。即操作系统的通信服务协议。应用程序通过这种协议调用操作系统的通信服务。这显然意味着SOCKET并不是真正的通信者。真正的通信者是OS。另一个证据是, SOCKET并不执行任何TCP协议操作。所有的协议操作都是操作系统完成的。而应用程序则使用SOCKET调用这些服务。另一种说法它是一种机制,就是这个意思。因为机制意味着手段,渠道,中间者。是一样的意思。操作系统通过这种机制向外提供通信服务。
动者是操作系统(的协议层)。
因此, 说使用SOCKET进行通信是错误的。应该说使用SOCKET调用通信。因为它并不完成真正的通信。它的确通信,但是这种通信是为了与OS的真正通信服务进行通信以告诉OS为之提供服务。另一个方面,它只是个API,所做的全部只是在内存中的一些操作,这些操作如何能够完成任何真正的通信工作?真正的通信工作要求的是端口管理,分配,侦听,以及网络层即IP地址的管理,分配,安全等服务,还有按协议组装数据,路由,寻址及响应服务,和与网卡进行真正的I/O通信以将数据放至网络上传播。。。。。。所有这些工作,SOCKET一点都没有做。
因此,SOCKET,不管是“半相关”还是“全相关”,都只是内存里面的概念。这些概念存在的目的是为了构建整个调用机制。它们是为调用而存在的。它们只活在API里面。调用的目标则是系统的通信服务。 也可以认为这些是对OS服务的封装。但是如JDBC并不进行真正的数据库操作一样,必须清醒地意识到SOCKET只是个API,它也不进行任何真正的通信操作。如果它能进行,那么它就不会存在于JAVA语言中了。因为JAVA语言甚至不能提供对内存的直接存取,更何况对I/O设备(网卡)的直接存取呢?
SOCKET意思是,这么多的程序都要通信。你要插一脚,那好,就给你一个SOCKET。SOCKET在这里的意思是,插孔。槽。当用它来接收信息的时候,它用来区分具体的收信程序;用来发送信息的时候,它就只是个句柄。
如果绑定了地址,那么系统应该会尽可能在进行真正的通信工作时使用这个地址。比如,如果为服务端SOCKET绑定了地址,那么系统将尝试在这个地址上而不是别的地址上进行侦听(对操作系统来说,它将形成一个资源占用------也就是说,一旦绑定成功,其它的程序将不能绑定在相同的地址(网络地址---人为的,虚有的,自称的地址)上)。
原文地址:https://www.cnblogs.com/LewisAAA/p/9248312.html