linux TCP 通信流程 套接字函数

发布时间 2023-10-12 12:28:00作者: 廿陆

TCP 和 UDP   ->  传输层的协议

  UDP: 用户数据报协议,面向无连接,可以单播,多播,广播,面向数据报(类似战争中无线电的广播),不可靠。

  TCP: 传输控制协议,面向连接的,可靠的,基于字节流,仅支持单播传输(点对点)。

              UDP              TCP  

  是否创建连接      无连接              面向连接

  是否可靠        不可靠              可靠的

  连接的对象个数     一对一/多、多对一/多      支持一对一

  传输的方式       面向数据报          面向字节流

  首部开销        8个字节             最少20个字节 ~ 60字节

  适用场景        实时应用(视频会议、直播)       可靠性高的应用(文件传输)

TCP通信流程:

服务器端(被动接受连接的角色):

  1. 创建一个用于监听的套接字(fd)
    - 监听:监听有客户端的连接
    - 套接字:一个文件描述符
  2. 将这个监听的 文件描述符 和 本地的IP 和 端口 绑定(IP 和 端口 就是服务器的地址信息)
    - 客户端连接服务器的时候,使用的就是这个 IP 和 端口
  3. 设置监听,监听的 fd 开始工作
  4. 阻塞等待,当有客户端发起连接,解除阻塞,接受客户端的连接,会得到一个和客户端通信的套接字(fd)
  5. 通信
      - 接收数据
      - 发送数据
  6. 通信结束,断开连接

客户端:

  1. 创建一个用于通信的套接字(fd)
  2. 连接服务器,需要指定连接的服务器的 IP 和 端口
  3. 连接成功了,客户端可以直接和服务器通信
      - 接收数据
      - 发送数据
  4. 通信结束,断开连接

套接字函数:

 1 #include <sys/types.h>
 2 #include <sys/socket.h>
 3 #include <arpa/inet.h>   //包含了这个头文件, 上面两个就可以省略
 4 
 5 int socket(int domain, int type, int protocol);
 6     - 功能: 创建一个套接字
 7     - 参数:
 8         - domain: 协议族
 9             AF_INET: IPv4
10             AF_INET6: IPv6
11             AF_UNIX,AF_LOCAL: 本地套接字(进程通信)
12         - type: 通信过程中使用的协议类型
13             SOCK_STREAM: 流式协议
14             SOCK_DGRAM: 报式协议
15         - protocol: 具体的协议,一般写 0
16             - SOCK_STREAM: 流式协议默认使用TCP
17             - SOCK_DGRAM:  报式协议默认使用UDP
18         - 返回值:
19             - 成功: 返回文件描述符, 操作的就是内核缓冲区
20             - 失败: -1
21 
22 int bind(int sockfd, const struct  sockaddr * addr, socklen_t addrlen);//socket命名
23     - 功能: 绑定,将fd和 本地的IP +端口 进行绑定
24     - 参数:
25         - sockfd: 通过socket函数得到的文件描述符
26         - addr: 需要绑定的socket地址, 这个地址封装了ip和端口号信息
27         - addrlen: 第二个参数结构体占的内存大小
28 
29 int listen(int sockfd, int backlog);//两个队列 未连接 和 已经连接  cat /proc/sys/net/core/somaxconn: 4096
30     - 功能: 监听这个socket上的连接
31     - 参数: 
32         - sockfd: 通过 socket()函数得到的文件描述符
33         - backlog: 未连接 和 已经连接 的和的最大值  一般指定为5 or 128  小于4096
34 
35 int accept(int sockfd, struct sockaddr * addr, socklen_t *addrlen);
36     - 功能: 接收客户端连接, 默认是一个阻塞的函数, 阻塞等待客户端的连接
37     - 参数:
38         - sockfd: 用于监听的文件描述符
39         - addr: 传出参数, 记录了连接成功后客户端的地址信息(IP, port)
40         - addrlen: 指定第二个参数的对应的内存大小
41     - 返回值:
42         - 成功: 用于通信的文件描述符
43         - 失败: -1
44 
45 int connect(int sockfd, const struct  sockaddr *addr, socklen_t addrlen);
46     - 功能: 客户端连接服务器
47     - 参数: 
48         - sockfd: 用于通信的文件描述符
49         - addr: 客户端要连接的服务器的地址信息
50         - addrlen: 第二个参数的内存大小
51     - 返回值:
52         - 成功: 0
53         - 失败: -1    
54 
55 ssize_t write(int fd, const void *buf, size_t count);   //写数据
56 ssize_t read(int fd, void *buf, size_t count);          //读数据