第一步:调用socket函数创建套接字
domain:套接字使用的协议族(Protocol Family)信息;
type:套接字数据传输类型信息;
protocol:计算机间通信中使用的协议信息;
协议族(Protocol Family)
套接字类型(Type):是指套接字的传输方式
面向连接的套接字(SOCK_STREAM)
传输过程中数据不会消失
按序传输数据
传输的数据不存在数据边界(Boundary):调用了三次write传递了100字节,接受者仅一次read接收了全部
面向消息的套接字(SOCK_DGRAM)
强调快速传输而非传输顺序
传输的数据可能丢失也可能损毁
传输的数据有数据边界
限制每次传输的数据大小
协议的最终选择
第二步:调用bind函数分配IP地址和端口号
__fd:要分配地址信息(IP地址和端口号)的套接字文件表述符。
__addr:存有地址信息的结构体变量地址值
__len:第二个结构体变量的长度
第三步:调用listen函数转为可接收请求状态
__fd:希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数成为服务器端套接字(监听套接字)。
__n:连接请求等待队列的长度。
第四步:调用accept函数受理连接请求
__fd:服务器套接字的文件描述符。
__addr:保存发起连接请求的客户端地址信息地变量地址值,调用函数后向传递来的地址变量参数填充客户端的地址信息。
__addr_len:第二个参数__addr结构体的长度,但是存有长度的变量地址。函数调用完后,该变量即被填入客户端地址长度。
第二步:调用socket函数向服务器端发送连接请求
__fd:客户端套接字文件表述符。
__addr:保存目标服务器端地址信息的变量地址值。
__len:以字节为单位传递已传递给第二个结构体参数__addr地址变量长度。
客户端调用connect函数后服务端接收连接请求(记录到等待队列)或发生断网等异常情况而中断连接请求才会返回(完成函数调用)。客户端的IP地址和端口号在调用connect函数时由内核自动分配,无需调用标记的bind函数进行分配。
总体流程就是:服务器端创建套接字后联系调用bind、listen函数进入等待状态,客户端通过调用connect函数发起连接请求,需要注意的是,客户端只能等到服务器端调用listen函数后才能调用connect函数。同时要清楚,客户端调用connect前,服务器端可能先调用了accept函数。当然,此时服务器端在调用accept函数时进入了阻塞状态,直到客户端调用connect函数为止。
I/O缓冲在每个TCP套接字中单独存在;
I/O缓冲在创建套接字时自动生成;
即使关闭套接字也会继续传递输出缓冲中遗留的数据;
关闭套接字将丢失输入缓冲中的数据;
echosrv.c
echocli.c