原理
套接字,计算机之间通信的一种约定 或 方式
通信基石 支持TCP/IP 协议的路通信的基本操作单元
标识主机问题: TCP/IP 协议簇解决 网络层的IP地址可以唯一标识网络中的主机
标识唯一进程问题: 传输层 协议加端口 唯一标识主机中的应用程序(进程)
三元组(ip地址 协议 端口)就可以标识网络的进程
socket 利用三元组解决网络通信的中间件工具
TCP/IP 协议连接的建立
即用connect()进行连接时,客户端与服务端都可以互相发送三个数据包 即三次握手
连接建立过程
1.客户端调用connect函数 TCP协议生成数据包 设置SYN位表示数据包用来建立同步连接 生成数字a 填充seq字段表示数据包信号 并发送给服务器端数据包 2.服务器端收到数据包 检测到syn位 开始组建数据包 设置syn ack 标志位 syn用来建立连接 ack确认收到 生成随机数b 填充seq 将a+1填充ack 并发送给客户端数据包 3.客户端收到数据包 检测syn ack标志位 syn为a+1 则连接建立成功 将b+1 填充ack 并发送数据包给服务器端 进入到ESABLISED状态 4.服务器收到数据包 检测ack 为b+1 进入ESTABLISED状态
连接断开过程
1.客户端调用close函数 发送设置了FIN的数据包给服务器端 自身进入FIN_WAIT_1状态 2.服务器收到数据包 检测到FIN 进入CLOSE_WAIT状态 发送确认包给客户端 3.客户端收到数据包 进入FIN_WAIT_2 状态 等待服务器准备好再次发送数据包 4. 服务器准备完毕 再次向客户端发送FIN包 进入LAST_ACK状态 5. 客户端收到FIN包 再向服务器发送ACK包 进入TIM_WAIT状态 6. 服务器收到ACK包 断开连接 关闭套接字 进入CLOSED状态
socket常用函数接口及其原理
socket()函数创建套接字
int socket(int af,int type,int protocol);
af 是地址族 就是IP地址类型 type是数据传输方式 protocol 表示传输协议 常用IPPROTO_TCP和IPPTOTO_UDP分别表示TCP传输协议 和 UDP传输协议
bind() 和 connect()函数
创建套接字后 确定了套接字的属性 bind函数将特定的IP地址和端口绑定起来 客户端用connect函数建立连接
int bind(int sock,struct sockaddr *addr,socklen_t addrlen);
int connect(int sock,struct sockaddr *aerv_addr,socklen_t addrlen);
listen() 和 accept()
listen()函数让套接字进入被动监听状态 再调用accept()函数 可随时响应客户端请求
int listen(int sock,int backlog);
int accept(int sock,struct sockaddr *addr,socklen_t *addrlen);
listen()只是让socket进入监听状态 并未真正接收客户端请求 listen() 后面的代码继续执行 直到遇到accept() accept()会阻塞程序执行 直到有新的请求道路
socket 数据接收与发送
在服务器端用write()向socket写入数据 客户端就能收到 然后再使用read()函数从socket中读取出来 就完成了一次通信
ssize_t write(int fd,const void *buf,size_t nbytes);
ssize_t read(int fd,void*buf,size_t nbytes);
socket缓冲区
socket创建后 都会被分配两个缓冲区,输入缓冲区输出缓冲区
write()/send()函数不立即向网络中传输数据 而是将数据 写入缓冲区中 再由TCP协议将数据从缓冲区发送到目标 一旦数据写入缓冲区 数据即可成功返回
TCP协议独立于函数
I/O缓冲区特性
1)在每个TCP套接字中单独存在 2)在创建套接字时自动生成 3)即使关闭套接字也会继续传送输出缓冲区中遗留的数据 4)关闭套接字将丢失输入缓冲区中的数据
缓冲区大小一般都是8K 可以通过getsockopt()函数获取:
阻塞模式
TCP socket 使用write()/send()发送数据时 首先检查缓冲区 不足的话函数暂停执行 直到空间足够才被唤醒 若TCP协议正在向网络传输数据 那么输出缓冲区就会被锁定 不允许写入 函数被锁定 直到数据发送完毕 缓冲区解锁 若写入数据大于缓冲区最大长度 将分批写入 直到所有的数据被写入缓冲区 write()/send()函数才返回
使用read()/recv()读取数据时 首先检查缓冲区 若有数据则读取 否则阻塞 直到数据到来唤醒 读取数据小于缓冲区中数据长度 就不能一次性将缓冲区的所有数据读出 剩余数据将不断积压 直到函数再次读取。
NIC
网络接口卡 是被设计用来允许计算机在计算机网络上进行通讯的计算机硬件 其拥有独一无二的48位串行号的MAC地址 写在ROM中
MAC地址
MEDIA ACCESS CONTROL ADDRESS 媒体存储控制位址 也称为局域网地址、MAC位址、以太网地址或物理地址 MAC地址在网络中唯一标识一个网卡
|