网络通讯对象
通常一台主机上总是有很多个进程需要网络资源进行网络通讯。网络通讯对象准确的讲不是主机,而是主机中运行的进程
确定一个进程
确定一个进程:ip地址+端口号
套接字
套接字:socket也称作套接字,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”想网络发出请求或者应答网络请求。
套接字工作原理
通过互联网进行通信,至少需要一对套接字,其中一个运行与客户机端,我们称之为 clientSocket,另一个运行于服务器端,我们称之为ServerSocket。
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听: 服务器端套接字并不定位具体的客户端套接字,而是出于等待连接状态,试试监控网络状态。
客户端请求: 由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。因此:客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端提出连接请求。
连接确认: 当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发送给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
套接字connect函数
如果是tcp套接字,调用connect函数将激发TCP三次握手过程,而且仅在连接建立成功或出错时才返回。注意:connect是在接受到服务端响应的SYN+ACK时返回的,也就是三次握手的第二次动作之后
UDP是可以调用connect函数的,但是UDP的connect函数和TCP的connect函数调用确实大相径庭的,这里没有三次握手过程。内核只是检查是否存在立即可知的错误(比如目的地不可达),记录对端的IP和端口号,然后立即返回调用进程。使用了connect的UDP编程就可不必使用sendto函数了,直接使用write/read即可。
内核: 是一个操作系统的核心。是基于硬件的第一层软件扩充,提供操作系统的最基本的功能,是操作系统工作的基础,他负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
套接字 listen函数
socket创建一个套接字时,它被假设为一个主动套接字,也就是说,它是一个将调用connect发起连接的一个客户套接字。listen函数把一个未连接的套接字转换为一个被动套接字,指示内核应该接受指向该套接字的连接请求,调用listen函数将导致套接字从close状态转换到listen状态。
未完成连接队列: 每一个这样的SYN分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的TCP三次握手过程。这些套接字处于SYN_RCVD状态。
已完成连接队列: 每个完成TCP三次握手的客户对应其中一项,这些套接字处于ESTABLISHED状态。
服务器 客户端交互流程图
TCP状态转换图
TCP四元组
Client_IP1:Client_Port1 <------>Server_IP:Server_Port fd1
Client_IP2:Client_Port2 <------>Server_IP:Server_Port fd2
Client_IP3:Client_Port3 <------>Server_IP:Server_Port fd3
TCP无法仅仅通过查看目的端口来确定数据报应发送给哪个套接字。它必须查看套接字对的所有4个元素才能确定由哪个端点接受达到的数据包。
fd 是服务端用来区别套接字描述符