网络编程基础

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\n");
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\n");
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\n");
65         _exit(-1);
66     }
67 
68     ret = listen(socket_fd, backlog);
69     if (ret == -1) {
70         printf("failed listen\n");
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]\n", 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\n");
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\n");
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]\n", send_buf);
51             break;
52         }
53 
54         ret = recv(socket_fd, recv_buf, sizeof(recv_buf), 0);
55         recv_buf[ret] = '\0';
56         if (ret <= 0) {
57             printf("recv zero msg\n");
58             continue;
59         }
60 
61         printf("recv[%s|%d]\n", 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] = '\0';
32             printf("recv[%s|%d]\n", 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>\n");
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] = '\0';
43             printf("recv[%s|%d]\n", 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()则都会接收并发送。

 

posted @ 2020-06-14 21:30  sp0917  阅读(214)  评论(0编辑  收藏  举报