《TCP/IP 网络编程》 阅读笔记(二)

91 阅读5分钟

基于TCP的服务端/客户端

链路层: 链路层是物理链接领域标准化的结果,定义LAN,WAN,MAN等网络标准 IP层:IP本身是面向消息、不可靠的协议。解决数据传输中的路径选择问题,只需要照此路径传输数据即可 TCP/UDP层:TCP和UDP层以IP层提供的路径信息为基础完成实际的数据传输。 应用层:。。。

TCP服务器端的默认函数调用顺序

image.png bind函数给套接字分配了网络地址后,接下来就需要通过listen函数进入等待连接请求的状态。只有调用了listen函数,客户端才能进入可发出连接请求的状态。换而言之,这时客户端才能调用connect函数

#include<sys/socket.h>
int listen(int sock,int backlog);
// sock 希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数成为服务器端套接字
// backlog 连接请求等待队列(Queue)的长度,若为5,则队列长度为5,表示最多使5个连接请求进入队列。

受理客户端连接请求

调用listen函数后,若有新的连接请求,则应按序受理。

#include<sys/sockt.h>
int accept(int sock,struct sockaddr *addr, socklen_t * addrlen);
成功时返回创建的套接字,失败时返回 -1 。
sock 服务器套接字的文件描述符
addr 保存发起连接请求的客户端地址信息的变量地址值,调用函数后向传递来的地址变量参数填充客户端地址信息。
addrlen 第二个参数addr结构体的长度,但是存有长度的变量地址。函数调用完成后,该变量即被填入客户端地址长度

accept函数受理连接请求等待队列中待处理的客户端连接请求。函数调用成功时,accept函数内部将产生用于数据I/O的套接字,并返回其文件描述符。 套接字是自动创建的,并自动与发起连接请求的客户端建立连接。

TCP客户端的默认函数调用顺序

image.png

与服务器端相比,区别就在于"请求连接",它是创建客户端套接字后向服务端发起的请求连接。服务器端调用完listen函数后创建连接请求等待队列,之后客户端即可请求连接

#include<sys/socket.h>
int connect(int sock,struct sockaddr * servaddr,socklen_t addrlen);
sock 客户端套接字文件描述符
servaddr 保存目标服务器端地址信息的变量地址值 
addrlen  字节为单位 .seraddr的长度.

客户端调用connect函数后,发生以下情况之一才会返回(完成函数调用)

  1. 服务器接受连接请求 2.发生断网等异常情况而中断连接请求 客户端的IP地址和端口在调用connect函数时自动分配,无需调用标记的bind函数进行分配。

image.png

实验迭代服务器端/客户端

回声(echo) 服务器端/客户端,服务端将客户端传输的字符串数据原封不动地传回客户端。

迭代服务器端

image.png

TCP套接字的I/O缓冲 1.I/O缓冲在每个TCP套接字中单独存在 2.I/O缓冲在创建套接字时自动生成 3.即使关闭套接字也会继续传递输出缓冲中遗留的数据 4.关闭套接字将丢失输入缓冲中的数据。

TCP 套接字以全双工的方式工作 : SEQ: 数据包序列号 ACK: 确认号

UDP的服务端和客户端

UDP中只有创建套接字的过程和数据交换的过程
UDP 服务端和客户端仅需要一个套接字,仅需要一个UDP套接字就能和多台主机通信

填写地址并传递数据时调用的UDP相关函数
发送函数
#include<sys/socket.h>
ssize_t sendto(int sock,void *buff,size_t nbytes,int flags,struct sockaddr *to,socklen_t addrlen);// 
成功返回传输的字节数,失败返回-1
sock 用于传输数据的UDP套接字文件描述符
buff 保存待传输数据的缓冲地址值 
nbytes 待传输的数据长度,以字节为单位
flags 可选参数,若没有则传递0 
to 存有目标地址信息的sockaddr结构体变量的地址值
addrlen 传递给参数to的地址值结构体变量长度
UDP的接收函数
   #include<sys/socket.h>
    ssize_t recvfrom(int sock,void *buff,size_t nbytes,int flags,struct sockaddr *from,socklen_t addrlen);// 
    成功返回接收的字节数,失败返回-1
    sock 用于接收数据的UDP套接字文件描述符
    buff 保存接收数据的缓冲地址值 
    nbytes 可接收的最大字节数,无法超过参数buff所指的缓冲大小 
    flags 可选参数,若没有则传递0 
    from 存有发送端地址信息的sockaddr结构体变量的地址值     
    addrlen 保存参数from的结构体变量长度的变量地址值。

UDP使用过程中,如果发现调用sendto函数时尚未分配地址信息,首次调用sendto函数时会给相应的套接字自动分配IP和端口号。

UDP的数据传输特性和调用connect函数

TCP 数据传输不存在边界,这表示"数据传输过程中调用I/O函数的次数不具有任何意义" UDP是具有数据边界的协议,传输中调用I/O函数的次数非常重要。因此,输入和输出函数的调用的次数要完全一致,才能保证接收全部已发送的数据。