当前位置:   article > 正文

UNIX高级编程【深入浅出】 网络编程 UDP/TCP_unix udp抓包指令

unix udp抓包指令

 

目录

UDP

创建 UDP 套接字

server端

client端(主动端)

示例代码

需要注意的是

UDP支持组播(群发)

示例代码(组播)

UDP支持广播

TCP

创建 TCP 套接字

server(被动端)

client(主动端)

示例代码

需要注意的是

三次握手与四次挥手

创建连接的三次握手过程

连接断开四次挥手过程

IO多路复用在TCP服务器中的应用

示例代码

UDP与TCP 协议格式​


  1. UDP

    1. SOCK_DGRAM报式套接字
      1. 全双工,无连接,不可靠(这不是缺点)
      2. 传输协议就是UDP
      3. 收发两端,通常client和server端
    2. 创建 UDP 套接字

      1. server端
        1. socket(2)创建报式套接字
        2. connect(2) / listen(2) / accept(2)都是与连接相关的,所有报式套接字都用不到
        3. 被动端,准备好接受包的条件
          1. bind(2)地址
        4. recvfrom(2)接受数据包(得到对端地址)
        5. close(2)关闭套接字
      1. client端(主动端)
        1. socket(2)创建报式套接字
        2. 主动端,第一个动作式发送数据包
          1. bind(2)可以省略的,如果省略了内核会为进程bind一个空闲的地址
        3. sendto(2)发送数据包
        4. close(2)关闭套接字
      2. server和client需要遵循相同的协议
        1. server的地址(ip+port)
        2. 数据格式(数据类型)
  2. 示例代码
    1. #ifndef __PORT_H__
    2. #define __PORT_H__
    3. #include <stdint.h>
    4. #define SERVERIP "x.x.x.x"
    5. #define SERVERPORT 1999
    6. #define MSGSIZE 1024
    7. #define handler_error(msg)\
    8. do {perror(msg); exit(EXIT_FAILURE);} while(0)
    9. struct __msg{
    10. int8_t id;
    11. char msg[MSGSIZE];
    12. }__attribute__((packed));
    13. typedef struct __msg msg_t;
    14. #endif
    1. // Date:2023.09.14 19:51:14
    2. #include <stdio.h>
    3. #include <stdlib.h>
    4. #include <unistd.h>
    5. #include <sys/types.h>
    6. #include <sys/socket.h>
    7. #include <arpa/inet.h>
    8. #include <netinet/in.h>
    9. #include <netinet/ip.h>
    10. #include <string.h>
    11. #include "port.h"
    12. /* 客户端 */
    13. int main(int argc, char *argv[])
    14. {
    15. int cnt;
    16. int udp_socket;
    17. struct sockaddr_in addr_in;
    18. msg_t sendbuf;
    19. socklen_t addr_len;
    20. if (argc < 3)
    21. exit(1);
    22. // 创建报式套接子
    23. if(-1 == (udp_socket = socket(AF_INET, SOCK_DGRAM, 0)))
    24. handler_error("socket()");
    25. // bind可省略
    26. // 发送的数据
    27. sendbuf.id = atoi(argv[1]);
    28. strncpy(sendbuf.msg, argv[2], MSGSIZE);
    29. // server地址
    30. addr_in.sin_family = AF_INET;
    31. addr_in.sin_port = htons(SERVERPORT);
    32. addr_in.sin_addr.s_addr = inet_addr(SERVERIP);
    33. //inet_aton(SERVERIP, &addr_in.sin_addr);
    34. if(-1 == sendto(udp_socket, &sendbuf, sizeof(sendbuf.id)+strlen(sendbuf.msg)+1, 0,\
    35. (struct sockaddr *)&addr_in, sizeof(addr_in))){
    36. close(udp_socket); handler_error("sendto()");
    37. }
    38. memset(sendbuf.msg, '\0', MSGSIZE);
    39. if(-1 == recvfrom(udp_socket, &sendbuf, sizeof(sendbuf), 0, NULL, NULL)){
    40. close(udp_socket); handler_error("recvfrom()");
    41. }
    42. // 请求后得到服务器反馈
    43. printf("%d , %s \n", sendbuf.id, sendbuf.msg);
    44. close(udp_socket);
    45. return 0;
    46. }
    1. // Date:2023.09.14 19:51:14
    2. #include <stdio.h>
    3. #include <stdlib.h>
    4. #include <unistd.h>
    5. #include <sys/types.h>
    6. #include <sys/socket.h>
    7. #include <arpa/inet.h>
    8. #include <netinet/in.h>
    9. #include <netinet/ip.h>
    10. #include <string.h>
    11. #include "port.h"
    12. /* 服务端 */
    13. int main(void)
    14. {
    15. int cnt;
    16. int udp_socket;
    17. struct sockaddr_in addr_in, client_addr;
    18. msg_t rcvbuf;
    19. socklen_t client_addr_len;
    20. if(-1 == (udp_socket = socket(AF_INET, SOCK_DGRAM, 0)))
    21. handler_error("socket()");
    22. // 绑定地址
    23. addr_in.sin_family = AF_INET;
    24. addr_in.sin_port = htons(SERVERPORT);
    25. // 点分十进制ip转换为ip结构体
    26. //addr_in.sin_addr.s_addr = inet_addr(SERVERIP);
    27. inet_aton(SERVERIP, &addr_in.sin_addr);
    28. if(-1 == bind(udp_socket, (struct sockaddr *)&addr_in, sizeof(addr_in))){
    29. close(udp_socket); handler_error("bind()");
    30. }
    31. // 接受client的数据包之前一定要将地址长度赋值
    32. client_addr_len = sizeof(struct sockaddr_in);
    33. while(1){
    34. // 等待接受客户端请求
    35. if(-1 == (cnt = recvfrom(udp_socket, &rcvbuf, sizeof(rcvbuf), 0, (struct sockaddr *)&client_addr, &client_addr_len))){
    36. close(udp_socket); handler_error("recvfrom()");
    37. }
    38. // 调试语句
    39. printf("[%s][%d] ", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    40. printf("id:%d , msg: %s\n", rcvbuf.id, rcvbuf.msg);
    41. // 向客户端发送数据
    42. rcvbuf.id = 0;
    43. strcpy(rcvbuf.msg, "ok");
    44. sendto(udp_socket, &rcvbuf, sizeof(rcvbuf.id) + strlen(rcvbuf.msg) + 1,0, (struct sockaddr *)&client_addr, client_addr_len);
    45. }
    46. close(udp_socket);
    47. return 0;
    48. }
    需要注意的是
    1. 在编写 UDP 程序时,你需要关注数据包的大小、分片和重组、丢包处理等问题,因为 UDP 本身不提供这些功能。此外,UDP 也不提供拥塞控制,因此在高负载或不稳定的网络环境中,可能会导致丢包和延迟增加。

    1. UDP支持组播(群发)

      1. ipv4组播地址:224~239
      2. 组播就是套接字的选项,使能组播的功能,那么就需要将套接字的组播选项打开
        1. setsockopt(2)
        2. 套接字的选项在以下手册中均有:
          1. man 7 ip(组播选项)
          2. man 7 socket
          3. man 7 udp
          4. man 7 tcp
        3. 组播选项的级别(level):IPPROTO_IP
        4. 组播选项的开关:大多数选项需要一个整型变量,如果值为1就是开启,值为0就是关闭
        5. 选项:
          1. IP_ADD_MEMBERSHIP 加入多播组
          2. IP_MULTICAST_IF 将本地设备用于多播
        6. 抓包器
          • wireshark
      3. 示例代码(组播)
  1. #ifndef __GROUP_PROTO_H__
  2. #define __GROUP_PROTO_H__
  3. // 多播组 接受端口
  4. #define GROUP_IP "224.2.3.4"
  5. #define RCV_PORT 1314
  6. // 数据类型
  7. #define MAX_MSG 1024
  8. #endif
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <netinet/ip.h>
  6. #include <arpa/inet.h>
  7. #include <net/if.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include "group_proto.h"
  11. /* 客户端 */
  12. int main(void)
  13. {
  14. int udp_socket;
  15. struct sockaddr_in myaddr; // man 7 ip
  16. struct ip_mreqn imr;
  17. char *buf = NULL;
  18. int cnt;
  19. udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
  20. if (-1 == udp_socket) {
  21. perror("socket()");
  22. exit(1);
  23. }
  24. // 被动端需要bind地址
  25. myaddr.sin_family = AF_INET;
  26. myaddr.sin_port = htons(RCV_PORT);
  27. inet_aton("0.0.0.0"/*INADDR_ANY*/, &myaddr.sin_addr);
  28. if (-1 == bind(udp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
  29. perror("bind()");
  30. goto ERROR1;
  31. }
  32. // 加入多播组
  33. inet_aton(GROUP_IP, &imr.imr_multiaddr);
  34. // 注意INADDR_ANY不是字符串,是uint32_t整型数
  35. inet_aton("0.0.0.0", &imr.imr_address);
  36. // 虚拟网卡的索引值,索引名转换为值if_nametoindex(3)
  37. imr.imr_ifindex = if_nametoindex("ens33");
  38. if (-1 == setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr))) {
  39. perror("setsockopt()");
  40. goto ERROR1;
  41. }
  42. // 接受消息
  43. buf = malloc(MAX_MSG);
  44. // if error
  45. while (1) {
  46. memset(buf, '\0', MAX_MSG);
  47. cnt = recvfrom(udp_socket, buf, MAX_MSG, 0, NULL, NULL);
  48. if (-1 == cnt) {
  49. perror("recvfrom()");
  50. goto ERROR1;
  51. }
  52. if (strcmp(buf, "bye") == 0)
  53. break;
  54. puts(buf);
  55. }
  56. close(udp_socket);
  57. free(buf);
  58. buf = NULL;
  59. exit(0);
  60. ERROR1:
  61. close(udp_socket);
  62. exit(1);
  63. }
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <netinet/ip.h>
  6. #include <arpa/inet.h>
  7. #include <net/if.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include "group_proto.h"
  11. /* 服务端 */
  12. int main(void)
  13. {
  14. int udp_socket;
  15. struct sockaddr_in snd_addr; // man 7 ip
  16. struct ip_mreqn imr;
  17. udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
  18. if (-1 == udp_socket) {
  19. perror("socket()");
  20. exit(1);
  21. }
  22. // 将本地设备设置为多播
  23. inet_aton(GROUP_IP, &imr.imr_multiaddr);
  24. imr.imr_address.s_addr = INADDR_ANY;
  25. // inet_aton("0.0.0.0", &imr.imr_address);
  26. // 虚拟网卡的索引值,索引名转换为值if_nametoindex(3)
  27. imr.imr_ifindex = if_nametoindex("ens33");
  28. if (-1 == setsockopt(udp_socket, IPPROTO_IP, IP_MULTICAST_IF, &imr, sizeof(imr))) {
  29. perror("setsockopt()");
  30. goto ERROR1;
  31. }
  32. printf("[%d]debug...\n", __LINE__);
  33. // 发送消息
  34. snd_addr.sin_family = AF_INET;
  35. snd_addr.sin_port = htons(RCV_PORT);
  36. inet_aton(GROUP_IP, &snd_addr.sin_addr);
  37. while (1) {
  38. sendto(udp_socket, "hello", 5, 0, (struct sockaddr *)&snd_addr, sizeof(snd_addr));
  39. sleep(1);
  40. }
  41. close(udp_socket);
  42. exit(0);
  43. ERROR1:
  44. close(udp_socket);
  45. exit(1);
  46. }
  1. UDP支持广播

    1. 广播选项man 7 socket
      1. SO_BROADCAST
    2. 广播选项级别:SOL_SOCKET
    3. 广播地址
      1. "255.255.255.255"全网广播
  2. TCP

    1. TCP套接字
      1. man 7 tcp
      2. 流式套接字
      3. 特点:
        1. 基于连接的,可靠传输
    2. 创建 TCP 套接字

      1. server(被动端)
        1. socket(2)创建流式套接字
        2. bind(2)地址
        3. listen(2)使套接字处于监听状态
        4. accept(2)等待接受对端的连接请求
        5. read(2) / write(2)收发消息 send(2) / recv(2)也可以
        6. close(2)关闭套接字
      2. client(主动端)
        1. socket(2)创建流式套接字
        2. connect(2)请求与服务器连接
        3. read(2) / write(2)收发消息 send(2) / recv(2)也可以
        4. close(2);
    3. 示例代码
      1. #ifndef __TCP_PROT_H__
      2. #define __TCP_PROT_H__
      3. // server地址(ip + port)
      4. #define SERVER_IP "x.x.x.x"
      5. #define SERVER_PORT 3344
      6. // 对话格式(数据类型)
      7. #define MAXMSG 1024
      8. struct msg_st {
      9. char msg[MAXMSG];
      10. }__attribute__((packed));
      11. #endif
      1. #include <stdio.h>
      2. #include <string.h>
      3. #include <sys/socket.h>
      4. #include <netinet/in.h>
      5. #include <netinet/ip.h>
      6. #include <stdlib.h>
      7. #include <arpa/inet.h>
      8. #include <unistd.h>
      9. #include "tcp_proto.h"
      10. /* 客户端 */
      11. int main(void)
      12. {
      13. int tcp_socket;
      14. struct sockaddr_in server_addr;
      15. struct msg_st rcvbuf;
      16. int cnt;
      17. // 创建流式套接字
      18. tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
      19. if (-1 == tcp_socket) {
      20. perror("socket()");
      21. exit(1);
      22. }
      23. // 请求与服务器连接
      24. server_addr.sin_family = AF_INET;
      25. server_addr.sin_port = htons(SERVER_PORT);
      26. inet_aton(SERVER_IP, &server_addr.sin_addr);
      27. if (-1 == connect(tcp_socket, (struct sockaddr *)&server_addr, sizeof(server_addr))) {
      28. perror("connect()");
      29. goto ERROR;
      30. }
      31. // 接受
      32. memset(rcvbuf.msg, '\0', MAXMSG);
      33. cnt = read(tcp_socket, &rcvbuf, MAXMSG);
      34. printf("from server rcv msg:%s with %dbytes\n", rcvbuf.msg, cnt);
      35. close(tcp_socket);
      36. exit(0);
      37. ERROR:
      38. close(tcp_socket);
      39. exit(1);
      40. }
      1. #include <stdio.h>
      2. #include <sys/socket.h>
      3. #include <netinet/in.h>
      4. #include <netinet/ip.h>
      5. #include <stdlib.h>
      6. #include <arpa/inet.h>
      7. #include <unistd.h>
      8. #include "tcp_proto.h"
      9. /* 服务端 */
      10. int main(void)
      11. {
      12. int tcp_socket, accepted_socket;
      13. struct sockaddr_in myaddr;
      14. pid_t pid;
      15. // 创建流式套接字
      16. tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
      17. if (-1 == tcp_socket) {
      18. perror("socket()");
      19. exit(1);
      20. }
      21. // 绑定本地地址
      22. myaddr.sin_family = AF_INET;
      23. myaddr.sin_port = htons(SERVER_PORT);
      24. myaddr.sin_addr.s_addr = INADDR_ANY;
      25. if (-1 == bind(tcp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
      26. perror("bind()");
      27. goto ERROR;
      28. }
      29. // 套接字处于监听状态
      30. if (-1 == listen(tcp_socket, 200)) {
      31. perror("listen()");
      32. goto ERROR;
      33. }
      34. // sigaction(SIGCHLD, ); SA_NOCHLDWAIT
      35. while (1) {
      36. // 等待接受客户端的连接请求
      37. accepted_socket = accept(tcp_socket, NULL, NULL);
      38. if (-1 == accepted_socket) {
      39. perror("accept()");
      40. goto ERROR;
      41. }
      42. // 成功后accepted_socket就是用于数据交换的套接字 原来的tcp_socket是用于继续接受客户端连接请求的
      43. pid = fork();
      44. if (-1 == pid) {
      45. perror("fork()");
      46. goto ERROR;
      47. }
      48. if (0 == pid) {
      49. // 数据交换 用accepted_socket
      50. close(tcp_socket);
      51. sleep(1);
      52. write(accepted_socket, "can you see that?", 17);
      53. close(accepted_socket);
      54. exit(0);
      55. }
      56. close(accepted_socket);
      57. }
      58. close(tcp_socket);
      59. exit(0);
      60. ERROR:
      61. close(tcp_socket);
      62. exit(1);
      63. }
  3. 需要注意的是
    1. TCP 提供了可靠的数据传输,包括数据的分段、重组、流量控制和拥塞控制机制。它确保数据按照正确的顺序到达目标,并通过确认机制检测和恢复丢失或损坏的数据。TCP 还实现了流量控制,以避免发送方过载和接收方缓冲区溢出,以及拥塞控制,以优化网络性能和公平共享带宽。
    2. TCP 提供了可靠的、面向连接的数据传输,适用于对数据完整性和可靠性要求较高的应用场景,如文件传输、网页浏览、电子邮件等
  4. 三次握手与四次挥手

    1. 创建连接的三次握手过程
      1. client向server发起连接请求(第一次握手)
        1. SYN置1, seq=x
      2. server收到了client发送的数据包后,会向client发送一个应答,同时发送一个序号(第二次握手)
        1. ACK=1, ack=x+1, seq=y
      3. client收到server的应答后,向server发送最后的应答(第三次握手)
        1. ACK=1, ack = y+1
      4. 即客户端发送连接请求、服务器响应连接请求并发送确认、客户端再次响应确认
  5. 连接断开四次挥手过程
    1. client向server发送请求断开的数据包(第一次挥手)
      1. FIN = 1, seq = m
    2. server收到了client请求断开的数据包后,会向client端发送应答(第二次挥手)
      1. ACK = 1, ack = m + 1
    3. 当server数据交换完成,也不需要通讯的时候,向client发送断开数据包(第三次挥手)
      1. FIN = 1,seq = n
    4. client最后向server发送应答(第四次挥手)
      1. ACK = 1, ack = n + 1
    5. 即客户端发送关闭连接请求、服务器确认关闭连接请求、服务器发送关闭连接请求、客户端确认关闭连接请求并关闭连接
  6. IO多路复用在TCP服务器中的应用

    1. tcp的服务器不是盲目的接收到链接就并发,而是使用select/poll监听到已连接的套接字可读再并发
    2. 对于套接字文件,有链接请求和有数据到达都是可读事件
    3. 当client端close套接字,则server端的套接字也是发生了可读事件,并且读到的数据是0.
  7. 示例代码
    1. #ifndef __TCP_PROT_H__
    2. #define __TCP_PROT_H__
    3. // server地址(ip + port)
    4. #define SERVER_IP "x.x.x.x"
    5. #define SERVER_PORT 3344
    6. // 对话格式(数据类型)
    7. #define MAXMSG 1024
    8. struct msg_st {
    9. char msg[MAXMSG];
    10. }__attribute__((packed));
    11. #endif
    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <sys/socket.h>
    4. #include <netinet/in.h>
    5. #include <netinet/ip.h>
    6. #include <stdlib.h>
    7. #include <arpa/inet.h>
    8. #include <unistd.h>
    9. #include "tcp_proto.h"
    10. /* 客户端 */
    11. int main(void)
    12. {
    13. int tcp_socket;
    14. struct sockaddr_in server_addr;
    15. struct msg_st sndbuf;
    16. int cnt;
    17. // 创建流式套接字
    18. tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    19. if (-1 == tcp_socket) {
    20. perror("socket()");
    21. exit(1);
    22. }
    23. // 请求与服务器连接
    24. server_addr.sin_family = AF_INET;
    25. server_addr.sin_port = htons(SERVER_PORT);
    26. inet_aton(SERVER_IP, &server_addr.sin_addr);
    27. if (-1 == connect(tcp_socket, (struct sockaddr *)&server_addr, sizeof(server_addr))) {
    28. perror("connect()");
    29. goto ERROR;
    30. }
    31. // 接受
    32. memset(sndbuf.msg, '\0', MAXMSG);
    33. strncpy(sndbuf.msg, "this is a test", MAXMSG);
    34. write(tcp_socket, &sndbuf, MAXMSG);
    35. sleep(2);
    36. close(tcp_socket);
    37. exit(0);
    38. ERROR:
    39. close(tcp_socket);
    40. exit(1);
    41. }
    1. #include <stdio.h>
    2. #include <errno.h>
    3. #include <string.h>
    4. #include <sys/socket.h>
    5. #include <netinet/in.h>
    6. #include <netinet/ip.h>
    7. #include <stdlib.h>
    8. #include <arpa/inet.h>
    9. #include <unistd.h>
    10. #include <poll.h>
    11. #include "tcp_proto.h"
    12. /* 服务端 */
    13. int main(void)
    14. {
    15. int tcp_socket, accepted_socket;
    16. struct sockaddr_in myaddr;
    17. pid_t pid;
    18. struct pollfd *pfd = NULL;
    19. int nfds = 0;
    20. struct msg_st rcvbuf;
    21. int i;
    22. int cnt;
    23. // 创建流式套接字
    24. tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    25. if (-1 == tcp_socket) {
    26. perror("socket()");
    27. exit(1);
    28. }
    29. // 绑定本地地址
    30. myaddr.sin_family = AF_INET;
    31. myaddr.sin_port = htons(SERVER_PORT);
    32. myaddr.sin_addr.s_addr = INADDR_ANY;
    33. if (-1 == bind(tcp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
    34. perror("bind()");
    35. goto ERROR;
    36. }
    37. // 套接字处于监听状态
    38. if (-1 == listen(tcp_socket, 200)) {
    39. perror("listen()");
    40. goto ERROR;
    41. }
    42. // 监听tcp_socket
    43. pfd = calloc(1, sizeof(struct pollfd));
    44. if (NULL == pfd) {
    45. perror("calloc()");
    46. goto ERROR;
    47. }
    48. pfd[0].fd = tcp_socket;
    49. pfd[0].events = POLLIN; // tcp_socket是否有连接
    50. nfds = 1;
    51. while (1) {
    52. if (-1 == poll(pfd, nfds, -1)) {
    53. if (errno == EINTR)
    54. continue; // 被信号打断
    55. perror("poll()");
    56. goto ERROR;
    57. }
    58. // 监听的事件发生了
    59. for (i = 0; i < nfds; i++) {
    60. if (i == 0) {
    61. if (pfd[0].fd == tcp_socket && pfd[0].revents & POLLIN) {
    62. // 套接字有连接到来了
    63. accepted_socket = accept(tcp_socket, NULL, NULL);
    64. if (-1 == accepted_socket) {
    65. perror("accept()");
    66. goto ERROR;
    67. }
    68. printf("**********client connected succefully************\n");
    69. // accepted_socket 就是将来用于数据交换的套接字
    70. // 如果可读了再读
    71. pfd = realloc(pfd, (nfds + 1) * sizeof(struct pollfd));
    72. // if error
    73. pfd[nfds].fd = accepted_socket;
    74. pfd[nfds].events = POLLIN; // 数据
    75. pfd[nfds].revents = 0;
    76. nfds ++;
    77. }
    78. } else {
    79. // 不是客户端的连接请求,而是有数据请求
    80. if (pfd[i].revents & POLLIN) {
    81. // 创建子进程/线程
    82. memset(rcvbuf.msg, '\0', MAXMSG);
    83. cnt = recv(pfd[i].fd, &rcvbuf, MAXMSG, 0);
    84. if (cnt == -1) {
    85. perror("recv()");
    86. goto ERROR;
    87. }
    88. if (cnt == 0) {
    89. // c端close()
    90. printf("***************888***************\n");
    91. close(pfd[i].fd);
    92. pfd[i].events = 0;
    93. memmove(pfd + i, pfd + i + 1, (nfds - (i + 1)) * sizeof(struct pollfd));
    94. nfds--;
    95. pfd = realloc(pfd, nfds * sizeof(struct pollfd));
    96. i--; // 下一次循环要执行i++
    97. } else {
    98. printf("!!!!!!!!!!!recv data!!!!!!!!!!!\n");
    99. // 接受到数据请求,处理请求
    100. // 暂且调试输出
    101. puts(rcvbuf.msg);
    102. }
    103. }
    104. }
    105. }
    106. }
    107. close(tcp_socket);
    108. exit(0);
    109. ERROR:
    110. close(tcp_socket);
    111. exit(1);
    112. }

UDP与TCP 协议格式

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/158761
推荐阅读
相关标签
  

闽ICP备14008679号