zoukankan      html  css  js  c++  java
  • libevent学习笔记 —— 牛刀小试:简易的服务器

    回想起之前自己用纯c手动写epoll循环,libevent用起来还真是很快捷啊!重写了之前学习的时候的一个例子,分别用纯c与libevent来实现。嗯,为了方便对比一下,就一个文件写到黑了。

    纯c版:

    一个server.c与client.c共同引用的头文件func.h

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<sys/types.h>
     4 #include<sys/stat.h>
     5 #include<fcntl.h>
     6 #include<unistd.h>
     7 #include<dirent.h>
     8 #include<time.h>
     9 #include<pwd.h>
    10 #include<grp.h>
    11 #include<stdlib.h>
    12 #include<sys/time.h>
    13 #include<sys/select.h>
    14 #include<sys/mman.h>
    15 #include<sys/wait.h>
    16 #include<sys/ipc.h>
    17 #include<sys/shm.h>
    18 #include<sys/sem.h>
    19 #include<signal.h>
    20 #include<pthread.h>
    21 #include<netinet/in.h>
    22 #include<sys/socket.h>
    23 #include<arpa/inet.h>
    24 #include<sys/epoll.h>
    25 #include<fcntl.h>
    View Code

    client.c

      1  ///
      2  /// @file    client.c
      3  /// @author  marrs(chenchengxi993@gmail.com)
      4  /// @date    2017-10-19 22:21:01
      5  ///
      6  
      7 #include "func.h"
      8 
      9 int socket_init(char * pst_ip, short short_port);
     10 int epoll_init(int int_sfd);
     11 int epoll_add(int int_sfd, int int_epfd);
     12 int epoll_del(int int_sfd, int int_epfd);
     13 int epoll_loop(int int_sfd, int int_epfd);
     14 int on_send_message_callback(int int_sfd, int int_epfd);
     15 int on_recv_message_callback(int int_fd, int int_epfd);
     16 
     17 int main(int argc, char* argv[])
     18 {
     19     if(argc != 3 )
     20     {
     21         printf("%s ip port
    ",argv[0]);
     22         return -1;
     23     }
     24 
     25     char * pst_ip = argv[1];
     26     short short_port = atoi(argv[2]);
     27 
     28     //初始化socket
     29     int int_sfd = socket_init(pst_ip, short_port);
     30     if (-1 == int_sfd)
     31     {
     32         printf("socket init fail...
    ");
     33         return -1;
     34     }
     35 
     36     //初始化epoll
     37     int int_epfd = epoll_init(int_sfd);
     38 
     39     //epoll循环
     40     epoll_loop(int_sfd, int_epfd);
     41     return 0;
     42 }
     43 
     44 int socket_init(char * pst_ip, short short_port)
     45 {
     46     //初始化socket
     47     int int_sfd = socket(AF_INET,SOCK_STREAM,0);
     48     if(-1 == int_sfd)
     49     {
     50         perror("socket");
     51         return -1;
     52     }
     53     int int_ret; 
     54 
     55     //连接服务器
     56     struct sockaddr_in sock_client;    
     57     sock_client.sin_family = AF_INET;
     58     sock_client.sin_addr.s_addr = inet_addr(pst_ip);
     59     sock_client.sin_port = htons(short_port);    
     60 
     61     printf("prepare to connect ip:%s port:%d
    ", pst_ip, short_port);
     62     int_ret = connect(int_sfd, (struct sockaddr*)&sock_client, sizeof(sock_client));
     63     if(-1 == int_ret)
     64     {
     65         perror("connect");
     66         return -1;
     67     }
     68     printf("connect ip:%s port:%d success!
    ", pst_ip, short_port);
     69 
     70     //修改文件描述符状态为非阻塞
     71     int status;
     72     status=fcntl(int_sfd,F_GETFL);
     73     status=status|O_NONBLOCK;
     74     fcntl(int_sfd,F_SETFL,status);
     75 
     76     return int_sfd;
     77 }
     78 
     79 int epoll_add(int int_fd, int int_epfd)
     80 {
     81     struct epoll_event epoll_ev;
     82     epoll_ev.events = EPOLLIN|EPOLLET;
     83     epoll_ev.data.fd = int_fd;
     84     epoll_ctl(int_epfd, EPOLL_CTL_ADD, int_fd, &epoll_ev);
     85     return 0;
     86 }
     87 
     88 int epoll_del(int int_fd, int int_epfd)
     89 {
     90     struct epoll_event epoll_ev;
     91     epoll_ev.events = EPOLLIN|EPOLLET;
     92     epoll_ev.data.fd = int_fd;
     93     epoll_ctl(int_epfd, EPOLL_CTL_DEL, int_fd, &epoll_ev);
     94     return 0;
     95 }
     96 
     97 int epoll_init(int int_sfd)
     98 {
     99     int int_epfd;
    100     int_epfd = epoll_create(1);
    101     epoll_add(0, int_epfd);
    102     epoll_add(int_sfd, int_epfd);
    103     return int_epfd;
    104 
    105 }
    106 
    107 int on_send_message_callback(int int_sfd, int int_epfd)
    108 {
    109     char pst_buffer[1024];
    110     int int_ret;
    111     memset(pst_buffer, 0, sizeof(pst_buffer));    
    112     int_ret = read(0, pst_buffer, sizeof(pst_buffer) - 1);
    113     printf("input = %s; ret = %d
    ", pst_buffer, int_ret);
    114     if(0 == int_ret)
    115     {
    116         printf("bye~
    ");
    117         epoll_del(int_sfd, int_epfd);
    118         epoll_del(0, int_epfd);
    119         return -1;    
    120     }
    121 
    122     else
    123     {
    124         printf("send = %s
    ", pst_buffer);
    125         int_ret = send(int_sfd, (void*)pst_buffer, sizeof(pst_buffer) - 1, 0);
    126         if(-1 == int_ret)
    127         {
    128             perror("send");
    129             epoll_del(int_sfd, int_epfd);
    130             epoll_del(0, int_epfd);
    131             return -1;    
    132         }
    133         printf("send success!
    ");
    134     }
    135     return int_ret;
    136 }
    137 
    138 int on_recv_message_callback(int int_fd, int int_epfd)
    139 {
    140     char pst_buffer[1024];
    141     int int_ret;
    142     while(1)
    143     {
    144         memset(pst_buffer, 0, sizeof(pst_buffer));
    145         int_ret = recv(int_fd, (void*)pst_buffer, sizeof(pst_buffer) - 1, 0);
    146         if(0 > int_ret)
    147         {
    148             break;
    149         }
    150         if(0 == int_ret)
    151         {
    152             printf("The server has been offline
    ");
    153             epoll_del(int_fd, int_epfd);
    154             return -1;
    155         }
    156         printf("%s", pst_buffer);
    157     }
    158     printf("
    ");
    159 
    160     return 0;
    161 }
    162 
    163 int epoll_loop(int int_sfd, int int_epfd)
    164 {
    165     struct epoll_event epoll_evs[2];
    166     int int_ret;
    167     int int_event_num;
    168     int int_idx;
    169     int is_loop = 1;
    170 
    171     //循环体
    172     while(is_loop)
    173     {
    174         memset(epoll_evs, 0, sizeof(epoll_evs));
    175 
    176         //等待事件
    177         int_event_num = epoll_wait(int_epfd, epoll_evs, 2, -1);    
    178         if (int_event_num > 0)
    179         {
    180             printf("someting in...
    ");
    181             for(int_idx = 0; int_idx < int_event_num; ++int_idx)
    182             {
    183                 if(epoll_evs[int_idx].events == EPOLLIN)
    184                 {
    185                     if(epoll_evs[int_idx].data.fd == 0)
    186                     {
    187                         //要发送消息
    188                         int_ret = on_send_message_callback(int_sfd, int_epfd);
    189                         if(-1 == int_ret)
    190                         {
    191                             printf("on send message callback fail...
    ");
    192                             is_loop = 0;
    193                             break;
    194                         }
    195 
    196                         if(0 == int_ret)
    197                         {
    198                             is_loop = 0;
    199                             break;
    200                         }
    201                     }
    202                     else if(epoll_evs[int_idx].data.fd == int_sfd)
    203                     {
    204                         //收到消息
    205                         int_ret = on_recv_message_callback(int_sfd, int_epfd);
    206                         if(-1 == int_ret)
    207                         {
    208                             printf("on recv message callback fail...
    ");
    209                             is_loop = 0;
    210                             break;
    211                         }
    212                     }
    213                 }
    214             }
    215         }
    216     }
    217     return 0;
    218 }

    server.c

      1  ///
      2  /// @file    server.c
      3  /// @author  marrs(chenchengxi993@gmail.com)
      4  /// @date    2017-10-19 21:27:33
      5  ///
      6  
      7 #include "func.h"
      8 
      9 int socket_init();
     10 int epoll_init(int int_sfd);
     11 int epoll_add(int int_sfd, int int_epfd);
     12 int epoll_del(int int_sfd, int int_epfd);
     13 int epoll_loop(int int_sfd, int int_epfd);
     14 int on_accept_callback(int int_sfd, int int_epfd);
     15 int on_recv_message_callback(int int_fd, int int_epfd);
     16 
     17 int main()
     18 {
     19     //初始化socket
     20     int int_sfd = socket_init();
     21     if (-1 == int_sfd)
     22     {
     23         printf("socket init fail...
    ");
     24         return -1;
     25     }
     26 
     27     //初始化epoll
     28     int int_epfd = epoll_init(int_sfd);
     29 
     30     //进入epoll循环
     31     epoll_loop(int_sfd, int_epfd);
     32 
     33 }
     34 
     35 int socket_init()
     36 {
     37     //初始化socket
     38     int int_sfd = socket(AF_INET,SOCK_STREAM,0);
     39     int int_ret; 
     40 
     41     //绑定ip、port
     42     char pst_ip[] = "127.0.0.1";
     43     struct sockaddr_in sock_server;    
     44     sock_server.sin_family = AF_INET;
     45     sock_server.sin_addr.s_addr = inet_addr(pst_ip);
     46     short int_16_port;
     47     for(int_16_port = 2000; int_16_port < 9999; ++int_16_port)
     48     {
     49         sock_server.sin_port = htons(int_16_port);
     50         int_ret = bind(int_sfd, (struct sockaddr*)&sock_server, sizeof(struct sockaddr));
     51         if(-1 == int_ret)
     52         {
     53             printf("bind port = %d fail..retry!
    ",int_16_port);
     54             continue;
     55         }
     56         break;
     57     }
     58 
     59     if(-1 == int_ret)
     60     {
     61         perror("bind");
     62         return -1;
     63     }
     64     printf("bind port = %d success!
    ",int_16_port);
     65 
     66     //监听
     67     int_ret = listen(int_sfd, 10);
     68     if(-1 == int_ret)
     69     {
     70         perror("listen");
     71         return -1;
     72     }
     73 
     74     return int_sfd;
     75 }
     76 
     77 int epoll_add(int int_fd, int int_epfd)
     78 {
     79     struct epoll_event epoll_ev;
     80     epoll_ev.events = EPOLLIN|EPOLLET;
     81     epoll_ev.data.fd = int_fd;
     82     epoll_ctl(int_epfd, EPOLL_CTL_ADD, int_fd, &epoll_ev);
     83     return 0;
     84 }
     85 
     86 int epoll_del(int int_fd, int int_epfd)
     87 {
     88     struct epoll_event epoll_ev;
     89     epoll_ev.events = EPOLLIN|EPOLLET;
     90     epoll_ev.data.fd = int_fd;
     91     epoll_ctl(int_epfd, EPOLL_CTL_DEL, int_fd, &epoll_ev);
     92     printf("close fd = %d
    ", int_fd);
     93     close(int_fd);
     94     return 0;
     95 }
     96 
     97 int epoll_init(int int_sfd)
     98 {
     99     int int_epfd;
    100     int_epfd = epoll_create(1);
    101     epoll_add(int_sfd, int_epfd);
    102     return int_epfd;
    103 
    104 }
    105 
    106 int on_accept_callback(int int_sfd, int int_epfd)
    107 {
    108     struct sockaddr_in sock_client;    
    109     socklen_t sock_len;
    110 
    111     //接入客户端
    112     int int_new_fd = accept(int_sfd, (struct sockaddr*)&sock_client, &sock_len);
    113     if(-1 == int_new_fd)
    114     {
    115         perror("accept");
    116         return -1;
    117     }
    118 
    119     //把new_fd注册到epfd中
    120     epoll_add(int_new_fd, int_epfd);
    121 
    122     //修改文件描述符状态为非阻塞
    123     int int_status=fcntl(int_new_fd,F_GETFL);
    124     int_status=int_status|O_NONBLOCK;
    125     fcntl(int_new_fd,F_SETFL,int_status);
    126 
    127     printf("accept new_fd = %d success!
    ", int_new_fd);
    128     return int_new_fd;
    129 }
    130 
    131 int on_recv_message_callback(int int_fd, int int_epfd)
    132 {
    133     printf("recv msg from fd = %d
    ", int_fd);
    134     char pst_buffer[8];
    135     int int_ret;
    136     while(1)
    137     {
    138         memset(pst_buffer, 0, sizeof(pst_buffer));
    139         int_ret = recv(int_fd, (void*)pst_buffer, sizeof(pst_buffer) - 1, 0);
    140         if(0 > int_ret)
    141         {
    142             break;
    143         }
    144         if(0 == int_ret)
    145         {
    146             printf("The client has been offline
    ");
    147             epoll_del(int_fd, int_epfd);
    148             return -1;
    149         }
    150         printf("%s", pst_buffer);
    151     }
    152     printf("
    ");
    153 
    154     char pst_msg[] = "The server has recv your message...";
    155     printf("%ld
    ", sizeof(pst_msg));
    156 
    157     int_ret = send(int_fd, (void*)pst_msg, sizeof(pst_msg) - 1, 0);
    158     if(-1 == int_ret)
    159     {
    160         perror("send msg");
    161         epoll_del(int_fd,int_epfd);
    162         return -1;
    163     }
    164     printf("%d
    ", int_ret);
    165 
    166     return 0;
    167 }
    168 
    169 int epoll_loop(int int_sfd, int int_epfd)
    170 {
    171     struct epoll_event epoll_evs[10];
    172     int int_ret;
    173     int int_event_num;
    174     int int_idx;
    175     printf("loop....
    ");
    176 
    177     //循环体
    178     while(1)
    179     {
    180         memset(epoll_evs, 0, sizeof(epoll_evs));
    181 
    182         //等待事件
    183         int_event_num = epoll_wait(int_epfd, epoll_evs, 10, -1);    
    184         if (int_event_num > 0)
    185         {
    186             for(int_idx = 0; int_idx < int_event_num; ++int_idx)
    187             {
    188                 if(epoll_evs[int_idx].events == EPOLLIN)
    189                 {
    190                     if(epoll_evs[int_idx].data.fd == int_sfd)
    191                     {
    192                         //有新客户端要接入
    193                         int_ret = on_accept_callback(int_sfd, int_epfd);
    194                         if(-1 == int_ret)
    195                         {
    196                             printf("on accept callback fail...
    ");
    197                             continue;
    198                         }
    199                     }
    200                     else
    201                     {
    202                         //收到来自客户端的消息
    203                         int_ret = on_recv_message_callback(epoll_evs[int_idx].data.fd, int_epfd);
    204                         if(-1 == int_ret)
    205                         {
    206                             printf("on recv message callback fail...
    ");
    207                             continue;
    208                         }
    209                     }
    210                 }
    211             }
    212         }
    213     }
    214 }

    使用libevent:

    只需要写回调函数,然后添加到监听的事件集合里就行了。就使用上来说,还是很方便的。

    client.c

      1  ///
      2  /// @file    client.c
      3  /// @author  marrs(chenchengxi993@gmail.com)
      4  /// @date    2017-10-23 21:27:33
      5  ///
      6  
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <unistd.h>
     10 #include <string.h>
     11 #include <sys/types.h>  
     12 #include <sys/socket.h>  
     13 #include <netinet/in.h>  
     14 #include <arpa/inet.h>  
     15 #include <event.h>
     16 
     17 int socket_init(char * pst_ip, short short_port);
     18 void on_send_message_callback(int int_fd, __attribute__((unused)) short short_events, void *arg);
     19 void on_recv_message_callback(int int_fd, __attribute__((unused)) short short_events, __attribute__((unused)) void *arg);
     20 
     21 int main(int argc, char* argv[])
     22 {
     23     if(argc != 3 )
     24     {
     25         printf("%s ip port
    ",argv[0]);
     26         return -1;
     27     }
     28 
     29     char * pst_ip = argv[1];
     30     short short_port = atoi(argv[2]);
     31 
     32     //初始化socket
     33     int int_sfd = socket_init(pst_ip, short_port);
     34     if (-1 == int_sfd)
     35     {
     36         printf("socket init fail...
    ");
     37         return -1;
     38     }
     39 
     40     //添加监听服务器消息事件
     41     struct event_base * base = event_base_new();
     42     struct event* event_recv_msg = event_new(base, int_sfd, EV_READ|EV_PERSIST, on_recv_message_callback, NULL);
     43     event_add(event_recv_msg, NULL);
     44 
     45     //添加监听终端输入事件
     46     struct event* event_send_msg = event_new(base, STDIN_FILENO, EV_READ|EV_PERSIST, on_send_message_callback, (void*)&int_sfd);
     47     event_add(event_send_msg, NULL);
     48 
     49     //进入循环
     50     event_base_dispatch(base);
     51 
     52     return 0;
     53 }
     54 
     55 void on_send_message_callback(int int_fd, __attribute__((unused)) short short_events, void *arg)
     56 {
     57     char pst_buffer[1024];
     58     int int_ret;
     59     int int_socket_fd = *(int*)arg;
     60     memset(pst_buffer, 0, sizeof(pst_buffer));    
     61     int_ret = read(int_fd, pst_buffer, sizeof(pst_buffer) - 1);
     62     printf("input = %s; ret = %d
    ", pst_buffer, int_ret);
     63     if(0 == int_ret)
     64     {
     65         printf("bye~
    ");
     66         exit(-1);    
     67     }
     68 
     69     else
     70     {
     71         printf("send = %s
    ", pst_buffer);
     72         int_ret = write(int_socket_fd, (void*)pst_buffer, sizeof(pst_buffer) - 1);
     73         if(-1 == int_ret)
     74         {
     75             perror("send");
     76             exit(-1);    
     77         }
     78         printf("send success!
    ");
     79     }
     80 }
     81 
     82 void on_recv_message_callback(int int_fd, __attribute__((unused)) short short_events, __attribute__((unused)) void *arg)
     83 {
     84     char pst_buffer[8];
     85     int int_ret;
     86     while(1)
     87     {
     88         memset(pst_buffer, 0, sizeof(pst_buffer));
     89         int_ret = recv(int_fd, (void*)pst_buffer, sizeof(pst_buffer) - 1, 0);
     90         if(0 > int_ret)
     91         {
     92             break;
     93         }
     94         if(0 == int_ret)
     95         {
     96             printf("The server has been offline
    ");
     97             exit(-1);    
     98         }
     99         printf("%s", pst_buffer);
    100     }
    101     printf("
    ");
    102 }
    103 
    104 int socket_init(char * pst_ip, short short_port)
    105 {
    106     int int_sfd = socket(AF_INET,SOCK_STREAM,0);
    107     if(-1 == int_sfd)
    108     {
    109         perror("socket");
    110         return -1;
    111     }
    112     int int_ret; 
    113 
    114     struct sockaddr_in sock_client;    
    115     sock_client.sin_family = AF_INET;
    116     sock_client.sin_addr.s_addr = inet_addr(pst_ip);
    117     sock_client.sin_port = htons(short_port);    
    118 
    119     printf("prepare to connect ip:%s port:%d
    ", pst_ip, short_port);
    120     int_ret = connect(int_sfd, (struct sockaddr*)&sock_client, sizeof(sock_client));
    121     if(-1 == int_ret)
    122     {
    123         perror("connect");
    124         return -1;
    125     }
    126     printf("connect ip:%s port:%d success!
    ", pst_ip, short_port);
    127     evutil_make_socket_nonblocking(int_sfd);    
    128     return int_sfd;
    129 }

    server.c

      1  ///
      2  /// @file    server.c
      3  /// @author  marrs(chenchengxi993@gmail.com)
      4  /// @date    2017-10-22 19:58:15
      5  ///
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <unistd.h>
     10 #include <event.h>
     11 #include <arpa/inet.h>
     12 
     13 int socket_init();
     14 void on_accept_callback(int int_fd, __attribute__((unused)) short short_events, void *arg);
     15 void on_recv_message(int int_fd, __attribute__((unused)) short short_events, void *arg);
     16 
     17 int main()
     18 {
     19     //初始化socket
     20     int int_sfd = socket_init();
     21     if(-1 == int_sfd)
     22     {
     23         printf("socket init fail...
    ");
     24         return -1;
     25     }
     26 
     27     //初始化struct event_base对象
     28     struct event_base * base = event_base_new();
     29 
     30     //添加监听客户端请求连接事件
     31     struct event* event_listen = event_new(base, int_sfd, EV_READ|EV_PERSIST, on_accept_callback, base);
     32     event_add(event_listen, NULL);
     33 
     34     //进入循环
     35     event_base_dispatch(base);
     36 
     37 }
     38 
     39 int socket_init()
     40 {
     41     int int_ret;
     42     short short_port;
     43     struct sockaddr_in sock_server;
     44 
     45     //初始化socket
     46     evutil_socket_t socket_fd = socket(AF_INET, SOCK_STREAM, 0);
     47     if(-1 == socket_fd)
     48     {
     49         goto error;
     50     }
     51     printf("get socket fd success
    ");
     52 
     53     //允许多次绑定同一个地址
     54     evutil_make_listen_socket_reuseable(socket_fd);
     55 
     56     //绑定ip、port
     57     sock_server.sin_family = AF_INET;
     58     sock_server.sin_addr.s_addr = 0;
     59     for(short_port = 2000; short_port < 9999; ++short_port)
     60     {
     61         sock_server.sin_port = htons(short_port);
     62         int_ret = bind(socket_fd, (struct sockaddr*)&sock_server, sizeof(sock_server));
     63         if(-1 == int_ret)
     64         {
     65             continue;
     66         }
     67         break;
     68     }
     69     if(-1 == int_ret)
     70     {
     71         goto error;
     72     }
     73 
     74     printf("bind port = %d success
    ", short_port);
     75 
     76     //监听
     77     int_ret = listen(socket_fd, 10);
     78     if(-1 == int_ret)
     79     {
     80         goto error;
     81     }
     82     printf("listen success
    ");
     83 
     84     //修改文件描述符状态为非阻塞
     85     evutil_make_socket_nonblocking(socket_fd);
     86     return socket_fd;
     87 
     88     //error
     89 error:
     90     perror("socket init");
     91     evutil_closesocket(socket_fd);
     92     return -1;
     93 }
     94 
     95 void on_accept_callback(int int_fd,    __attribute__((unused))short short_events, void *arg)
     96 {
     97     evutil_socket_t socket_fd;
     98     struct sockaddr_in sock_client;
     99     socklen_t sock_len;
    100 
    101     //接入
    102     socket_fd = accept(int_fd, (struct sockaddr*)&sock_client, &sock_len);
    103     if(-1 == socket_fd)
    104     {
    105         perror("accept");
    106         return;
    107     }
    108     printf("accpet a new client...
    ");
    109 
    110     //修改文件描述符状态为非阻塞
    111     evutil_make_socket_nonblocking(socket_fd);
    112 
    113     //添加监听客户端发送消息事件
    114     struct event_base* base = (struct event_base*)arg;
    115     struct event* event_client = event_new(NULL, -1, 0, NULL, NULL);
    116     event_assign(event_client, base, socket_fd, EV_READ|EV_PERSIST, on_recv_message, (void*)event_client);
    117     event_add(event_client, NULL);
    118 
    119 }
    120 
    121 void on_recv_message(int int_fd, __attribute__((unused))short short_events, void *arg)
    122 {
    123     char pst_buffer[8];
    124     int int_ret;
    125     struct event *event_client = (struct event*)arg;
    126     while(1)
    127     {
    128         memset(pst_buffer, 0, sizeof(pst_buffer));
    129         int_ret = read(int_fd, (void*)pst_buffer, sizeof(pst_buffer) - 1);
    130         if(0 == int_ret)
    131         {
    132             printf("the client has been offline...
    ");
    133             event_free(event_client);
    134             close(int_fd);
    135             return;
    136         }
    137         else if(0 > int_ret)
    138         {
    139             break;
    140         }
    141         else
    142         {
    143             printf("%s", pst_buffer);
    144         }
    145     }
    146     printf("
    ");
    147 
    148     char pst_msg[] = "the server has recv your msg....";
    149     int_ret = write(int_fd, pst_msg, strlen(pst_msg));
    150 }
  • 相关阅读:
    【Mybatis源码解析】- JDBC连接数据库的原理和操作
    【JDK源码解析】- ArrayList源码解析,绝对详细
    【设计模式】-代理模式及动态代理详解
    【Java基础】反射机制及应用
    Go 中的 channel 与 Java BlockingQueue 的本质区别
    Github Actions 还能做这些事
    写了一个 gorm 乐观锁插件
    Go 去找个对象吧
    Web 自动化测试全面提升之 Pytest
    【51testing专访】web自动化,从入门到进阶
  • 原文地址:https://www.cnblogs.com/chinxi/p/7719782.html
Copyright © 2011-2022 走看看