Java中套接字(socket)以及有关概念入门

目录

socket的理解

 epoll的原理解析

从网卡接收数据的过程

真正的接收了数据

当我们监控一个socket时

 阻塞时发生了什么

 如何唤醒线程一

多个socket连接时(引出Select)

解决Select缺点(引出epoll)

 措施二

epoll原理

根据以下文章学习


socket的理解

Socket编程基本就是listen,accept以及send,write等几个基本的操作。

我们还知道TCP和UDP,前者可以保证数据的正确和可靠性,后者则允许数据丢失。

在TCP和UDP同属于传输层,共同架设在IP层(网络层)之上。而IP层主要负责的是在节点之间(End to End)的数据包传送,IP层只负责把数据送到节点,而不能区分上面的不同应用。所以TCP和UDP协议在其基础上加入了端口的信息,端口于是标识的是一个节点上的一个应用。除了增加端口信息,UDP基本就没有对IP层的数据进行任何的处理了。而TCP协议还加入了更加复杂的传输控制,比如滑动的数据发送窗口(Slice Window),以及接收确认和重发机制,以达到数据的可靠传送。

TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。TCP/IP也必须对外提供编程接口,这就是Socket编程

总结:

  • 如果一个程序创建了一个socket,并让其监听80端口,其实是向TCP/IP协议栈声明了其对80端口的占有。
  • 所谓accept,其实抽象的是TCP的连接建立过程。accept可以产生多个不同的socket,而这些socket里包含的宿IP和宿端口是不变的,变化的只是源IP和源端口。

套接字套(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

 epoll的原理解析

从网卡接收数据的过程

网卡收到网线传来的数据————在硬件电路的传输————将数据写入到内存中的某个地址上

总结:网卡会把接收到的数据写入内存

真正的接收了数据

由硬件产生的信号需要 CPU 立马做出回应,不然数据可能就丢失了,所以它的优先级很高。(比如:当计算机收到断电信号时,它应立即去保存数据,保存数据的程序具有较高的优先级(电容可以保存少许电量,供 CPU 运行很短的一小段时间))

CPU 理应中断掉正在执行的程序,去做出响应;当 CPU 完成对硬件的响应后,再重新执行用户程序。

当网卡把数据写入到内存后,网卡向 CPU 发出一个中断信号,操作系统便能得知有新数据到来,再通过网卡中断程序去处理数据。

当我们监控一个socket时

进程一是一个连接。recv 是个阻塞方法,当程序运行到 recv 时,它会一直等待,直到接收到数据才往下执行。

Java中套接字(socket)以及有关概念入门_第1张图片

 阻塞时发生了什么

操作系统为了支持多任务,实现了进程调度的功能,会把进程分为“运行”和“等待”等几种状态(比如上述程序运行到 recv 时,程序会从运行状态变为等待状态接收到数据后又变回运行状态)。

当线程一创建socket时操作系统会创建一个由文件系统管理的 Socket 对象。这个 Socket 对象包含了发送缓冲区、接收缓冲区与等待队列等成员。当程序执行到 recv 时,操作系统会将进程 一 从工作队列移动到该 Socket 的等待队列中。

这时候线程一被阻塞,线程二正常执行,以至于阻塞不占用cpu资源

Java中套接字(socket)以及有关概念入门_第2张图片

 如何唤醒线程一

当对socket写入数据,数据经由网卡传送到内存,网卡通过中断信号通知 CPU 有数据到达,CPU 执行中断程序。中断执行时,数据写入缓冲区唤醒线程一并放入工作队列

这大致就是单个socket连接的流程。

多个socket连接时(引出Select)

recv 只能监视单个 Socket。先出现一种不太高效的方法——select。

如果我们监控三个socket,就把线程一放到三个socket对象的等待队列。如图

Java中套接字(socket)以及有关概念入门_第3张图片

 举例说明,当socket2收到数据时,进程一移出三个socket,加入工作队列(和一个socket时类似)。

缺点:每次调用 Select 都需要将进程加入到所有监视 Socket 的等待队列,每次唤醒都需要从每个队列中移除。这里涉及了两次遍历。进程被唤醒后,程序并不知道哪些 Socket 收到数据,还需要遍历一次。

解决Select缺点(引出epoll)

select将阻塞和添加等待队列放在一起,但是epoll拆分了他们的功能。先用 epoll_ctl 维护等待队列,再调用 epoll_wait 阻塞进程。显而易见地,效率就能得到提升。

Java中套接字(socket)以及有关概念入门_第4张图片

 措施二

解决不知道哪个socket收到消息的问题。

维护了一个rdlist,当有socket收到数据就被rdlist(eventpoll的就序列表)引用,当进程被唤醒时,就知道哪个socket收到了信息。

epoll原理

当进程创建epoll时,内核会创建一个 eventpoll 对象。和 Socket 一样,它也会有等待队列。

Java中套接字(socket)以及有关概念入门_第5张图片

假如有三个socket进入时,情况是eventpoll注入到三个socket中,socket收到数据后,中断程序会操作 eventpoll 对象,而不是直接操作进程。

当收到数据后,中断会给eventpoll的就绪列表添加socket的引用。

eventpoll 对象相当于 Socket 和进程之间的中介,Socket 的数据接收并不直接影响进程,而是通过改变 eventpoll 的就绪列表来改变进程状态。

也因为 Rdlist 的存在,进程 一(创建连接的进程) 可以知道哪些 Socket 发生了变化。

根据以下文章学习

关于我对socket的理解,不知道正确与否? - 知乎看了很多关于socket的文章,也整合了不同文章的描述,对于它有一个自己的认识,不知道对不对,想请教一下…https://www.zhihu.com/question/64316083icon-default.png?t=M0H8https://www.zhihu.com/question/64316083Epoll原理解析_~~ LINUX ~~-CSDN博客_epoll从事服务端开发,少不了要接触网络编程。Epoll 作为 Linux 下高性能网络服务器的必备技术至关重要,Nginx、Redis、Skynet 和大部分游戏服务器都使用到这一多路复用技术。Epoll 很重要,但是 Epoll 与 Select 的区别是什么呢?Epoll 高效的原因是什么?网上虽然也有不少讲解 Epoll 的文章,但要么是过于浅显,或者陷入源码解析,很少能有通俗易懂的。...https://blog.csdn.net/armlinuxww/article/details/92803381icon-default.png?t=M0H8https://blog.csdn.net/armlinuxww/article/details/92803381

你可能感兴趣的:(面试,java,udp,tcp/ip,socket)