Socket快速简要了解
本文致力于快速了解Socket是什么以及简洁地说明几个比较重要的点。但是获得系统完备的知识体系是很重要的,需要深入了解原理和具体细节(其实很有意思),以后有时间我会慢慢补充(更新的形式补坑,所以一些坑和扩展可以跳过)。
本文都只是我现阶段的了解!以及,参考的一些内容会尽量给出链接。
Socket一般译作套接字,从不同角度来看Socket的定义有多个。
定义1:Socket是传输层连接的端点,传输层实现的是端到端通信,端点就是套接字。
插播:我一直觉得Socket应该分为两类(有这种说法)。因为从java.net这个包中可以看到ServerSocket这个类的说明是:
即:服务器套接字等待网络请求传入,基于请求执行一些操作(可能会返回结果给请求者)。可以称之为监听Socket。
用法:
//创建监听Socket,等待接收连接Socket。
ServerSocket server=new ServerSocket(port);
//accept()接收到连接Socket,用于读写
Socket socket=server.accept();
//获取输入流,之后可以读到缓冲区等。
InputStream inputStream=socket.getInputStream();
Socket类的说明是:
即:两台机器之间通信的端点。可以称之为连接Socket。
用法是:
//创建连接Socket,获得输出流,之后可以向输出流写入数据。
Socket socket=new Socket(host,port);
OutputStream ops=socket.getOutputStream();
这里再扩展一下:一条连接可以由一个通信五元组标识(一条TCP连接则是四元组确定)
服务器端的端口一般需要我们自己指定(根据应用层协议不同,FTP用20控制21传数据,SSH:22, Telnet: 23 HTTP常用80,HTTPs常用443)。客户端的端口默认是用native方法由操作系统随机bind一个(也可以指定)。
服务器端Socket可能只监听一个端口,但是和不同的客户端组合就形成了很多的Socket连接。
这里可以扩展到IO多路复用(IO multiplexing)select/epoll,单个进程/线程处理多个网络连接IO,socket设置为非阻塞状态non_blocking(Socket IO没有被block,但是进程是被select这个函数block的)。epoll方式1G内存大约能监听10万个Socket连接。
注意如果连接数不是很高的话,用select/epoll的web server未必比multi-threading+blocking IO 的web server性能更好。
对于UDP的Socket,要使用DatagramSocket这个类。
本段部分参考自https://blog.csdn.net/a78270528/article/details/80318571 有更详细全面的代码。
定义二:Socket是传输层上抽象出来的编程接口,使用这个抽象编程接口可以进行一些TCP/IP协议栈的操作。监听,读写等。
从下图来看,Socket连接是抽象连接,使用TCP协议的话,就相当于一条抽象TCP连接,可以编程操作。
这两个定义并不冲突,只是一个从传输层通信端点角度来看,一个从编程接口角度来看。
连接Socket(不是监听Socket)的输入输出流可以读写内核中的一个对应文件,这个文件有唯一的文件描述符fd(File Descriptor)。