• 网络编程基础


    1. socket基础编程

    1.1 TCP Server网络编程基本步骤

      1.创建socket,指定使用TCP协议

      2.将socket与地址和端口绑定

      3.监听端口

      4.创建连接socket

      5.使用recv接收数据

      6.使用send发送数据

      7.使用close关闭连接

    1.2 TCP常见套接字选项

      1. SO_REUSEADDR端口处于time_wait时,仍然可以启动,无需等待连接的FIN标识;

      2. SO_RECVBUF/SO_SNDBUF

    1.3 TCP通信

    1.3.1 TCP服务端实现

     1 /**
     2   tcpserver.c
     3 */
     4 
     5 /**
     6 struct sockaddr_in
     7 {
     8     sa_family_t    sin_family;
     9     uint16_t         sin_port;
    10     struct in_addr sin_addr;
    11     char               sin_zero[8]; 
    12 }
    13 
    14 struct in_addr
    15 {
    16     in_addr_t s_addr;
    17 }
    18 
    19 struct sockaddr
    20 {
    21     sa_family_t  sin_family;
    22     char             sin_zero[14];
    23 }
    24 */
    25 #include <stdio.h>
    26 #include <strings.h>
    27 #include <string.h>
    28 #include <unistd.h>
    29 #include <netinet/in.h>
    30 #include <sys/types.h>
    31 #include <sys/socket.h>
    32 
    33 #define PORT 8111
    34 #define MESSAGE_LEN 1024
    35 
    36 int main(int argc, char* argv[])
    37 {
    38     int socket_fd;
    39     int accept_fd;
    40     int on = 1;
    41     int ret = -1;
    42     int backlog = 10;
    43     char in_buff[MESSAGE_LEN] = { 0 };
    44     struct sockaddr_in localaddr, remoteaddr;
    45 
    46     socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    47     if (socket_fd == -1) {
    48         printf("can't create socket fd
    ");
    49         _exit(-1);
    50     }
    51 
    52     ret = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    53     if (ret == -1) {
    54         printf("faild to set socket option
    ");
    55     }
    56 
    57     localaddr.sin_family = AF_INET;
    58     localaddr.sin_port = htons(PORT);
    59     localaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    60     bzero(localaddr.sin_zero, 8);
    61     socklen_t addr_len = sizeof(struct sockaddr_in);
    62     ret = bind(socket_fd, (struct sockaddr *)&localaddr, addr_len);
    63     if (ret == -1) {
    64         printf("failed to bind addr
    ");
    65         _exit(-1);
    66     }
    67 
    68     ret = listen(socket_fd, backlog);
    69     if (ret == -1) {
    70         printf("failed listen
    ");
    71         _exit(-1);
    72     }
    73 
    74     while (1) {
    75         accept_fd = accept(socket_fd, (struct sockaddr *)&remoteaddr, &addr_len);
    76         if (accept_fd <= 0) continue;
    77 
    78         while (1) {
    79             memset(in_buff, 0, sizeof(in_buff));
    80             ret = recv(accept_fd, (void *)in_buff, MESSAGE_LEN, 0);
    81             if (ret == 0) break;
    82 
    83             printf("recv[%s|%d]
    ", in_buff, ret);
    84             send(accept_fd, (void *)in_buff, strlen(in_buff), 0);
    85         } // end while
    86 
    87         close(accept_fd);
    88     } //end while
    89 
    90     close(socket_fd);
    91 
    92     return 0;
    93 }
    94 
    95 # gcc -std=c11 -g -o tcpserver tcpserver.c
    96 # ./tcpserver

    1.3.2 TCP 客户端实现

        1.创建socket,指定使用TCP协议;

        2.使用connect连接服务器;

        3.使用send/recv发送/接受数据;

        4.关闭socket。

     1 /**
     2   tcpclient.c
     3 */
     4 #include <stdio.h>
     5 #include <unistd.h>
     6 #include <string.h>
     7 #include <sys/socket.h>
     8 #include <sys/types.h>
     9 #include <netinet/in.h>
    10 #include <arpa/inet.h>
    11 
    12 #define PORT 8111
    13 #define MESSAGE_LEN 1024
    14 
    15 int main(int argc, char* argv[]) 
    16 {
    17     int ret = -1;
    18     int socket_fd;
    19     struct sockaddr_in server_addr;
    20     socklen_t addr_len;
    21     char send_buf[MESSAGE_LEN] = { 0 };
    22     char recv_buf[MESSAGE_LEN] = { 0 };
    23 
    24     socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    25     if (socket_fd < 0) {
    26         printf("failed create socket
    ");
    27         _exit(-1);
    28     }
    29 
    30     server_addr.sin_family = AF_INET;
    31     server_addr.sin_port = htons(PORT);
    32     server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    33     addr_len  = sizeof(struct sockaddr_in);
    34     ret = connect(socket_fd, (struct sockaddr *)&server_addr, addr_len);
    35     if (ret < 0) {
    36         printf("connect to server
    ");
    37         _exit(-1);
    38     }
    39 
    40     while (1) {
    41         memset(send_buf, 0, sizeof(send_buf));
    42         memset(recv_buf, 0, sizeof(recv_buf));
    43         //fgets(send_buf, MESSAGE_LEN, stdin);
    44         gets(send_buf);
    45         if (strncmp(send_buf, "quit", 4) == 0)
    46             break;
    47 
    48         ret = send(socket_fd, send_buf, strlen(send_buf), 0);
    49         if (ret <= 0) {
    50             printf("failed send msg[%s]
    ", send_buf);
    51             break;
    52         }
    53 
    54         ret = recv(socket_fd, recv_buf, sizeof(recv_buf), 0);
    55         recv_buf[ret] = '';
    56         if (ret <= 0) {
    57             printf("recv zero msg
    ");
    58             continue;
    59         }
    60 
    61         printf("recv[%s|%d]
    ", recv_buf, ret);
    62     } // end while
    63 
    64     close(socket_fd);
    65 
    66     return 0;
    67 }
    68 
    69 # gcc -std=c11 -g -o tcpclient tcpclient.c
    70 # ./tcpclient 127.0.0.1

    1.4 UDP通信

    1.4.1 UDP服务端实现

        1.创建socket,指定使用UDP协议;

        2.将socket与地址和端口绑定;

        3.使用send/recv发送/接受数据;

        4.使用close关闭连接。

     1 /**
     2   udpserver.c
     3 */
     4 #include <stdio.h>
     5 #include <sys/socket.h>
     6 #include <sys/types.h>
     7 #include <netinet/in.h>
     8 #include <arpa/inet.h>
     9 #include <strings.h>
    10 
    11 #define PORT 8111
    12 #define MSG_LEN 1024
    13 
    14 int main(int argc, char* argv[])
    15 {
    16     int     sockfd;
    17     socklen_t cli_len;
    18     char msg[MSG_LEN] = { 0 };
    19     struct sockaddr_in serv_addr, cli_addr;
    20     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    21 
    22     bzero(&serv_addr, sizeof(serv_addr));
    23     serv_addr.sin_family = AF_INET;
    24     serv_addr.sin_port = htons(PORT);
    25     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    26     bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    27 
    28     while (1) {
    29         int n = recvfrom(sockfd, msg, MSG_LEN, 0, (struct sockaddr *)&cli_addr, &cli_len);
    30         if (n > 0) {
    31             msg[n] = '';
    32             printf("recv[%s|%d]
    ", msg, n);
    33             sendto(sockfd, msg, n, 0, (struct sockaddr *)&cli_addr, cli_len);
    34         }
    35     }
    36 
    37     return 0;
    38 }
    39 
    40 # gcc -std=c11 -g -o udpserver udpserver.c
    41 # ./udpserver

    1.4.2 UDP客户端实现

     1 /**
     2   udpclient.c
     3 */
     4 #include <stdio.h>
     5 #include <unistd.h>
     6 #include <sys/socket.h>
     7 #include <sys/types.h>
     8 #include <arpa/inet.h>
     9 #include <string.h>
    10 #include <strings.h>
    11 
    12 #define PORT 8111
    13 #define MSG_LEN 1024
    14 
    15 int main(int argc, char* argv[])
    16 {
    17     int  sockfd;
    18     char send_buf[MSG_LEN] = { 0 };
    19     char recv_buf[MSG_LEN + 1] = { 0 };
    20     struct sockaddr_in serv_addr;
    21 
    22     if (argc != 2) {
    23         printf("usage: udpclient <ip address>
    ");
    24         _exit(-1);
    25     }
    26 
    27     bzero(&serv_addr, sizeof(serv_addr));
    28     serv_addr.sin_family = AF_INET;
    29     serv_addr.sin_port = htons(PORT);
    30     inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
    31     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    32 
    33     while (fgets(send_buf, MSG_LEN, stdin) != NULL) {
    34         sendto(sockfd, 
    35             send_buf, 
    36             strlen(send_buf), 
    37             0, 
    38             (struct sockaddr *)&serv_addr, 
    39             sizeof(serv_addr));
    40         int n = recvfrom(sockfd, recv_buf, MSG_LEN, 0, NULL, NULL);
    41         if (n > 0) {
    42             recv_buf[n] = '';
    43             printf("recv[%s|%d]
    ", recv_buf, n);
    44             //fputs(recv_msg, stdout);
    45         }
    46     }
    47 
    48     return 0;
    49 }
    50 
    51 # gcc -std=c11 -g -o udpclient udpclient.c
    52 # ./udpclient 127.0.0.1

    注:gets()和fgets()不同的地方除了安全性外,还有就是gets()不会接收控制端的回车换行等不可见字符,fgets()则都会接收并发送。

  • 相关阅读:
    洛谷 P1119 灾后重建
    [NOIP 2011] 观光公交
    AtCoder Beginner Contest 071 D
    UOJ #228. 基础数据结构练习题
    bzoj 3673&3674: 可持久化并查集 by zky
    bzoj 2427: [HAOI2010]软件安装
    都市环游
    poj2299——Ultra-QuickSort
    poj1958——Strange Towers of Hanoi
    洛谷 P4139 上帝与集合的正确用法
  • 原文地址:https://www.cnblogs.com/sip-inaction/p/13121590.html
Copyright © 2020-2023  润新知