TCP练习

然后基本的socket编程,用TCP做两个进程互相发消息。C端主动发hello,S端收到后回world。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <sys/types.h>
 4 #include <sys/socket.h>
 5 #include <netinet/in.h>
 6 #include <arpa/inet.h>
 7 #include <string.h>
 8 
 9 #define MAXLINE 80
10 #define SERV_PORT 8000
11 
12 int main()
13 {
14     char buf[MAXLINE];
15     int listenfd = 0;
16 
17     listenfd = socket(AF_INET, SOCK_STREAM, 0);
18 
19     struct sockaddr_in servaddr = {0};
20     servaddr.sin_family = AF_INET;
21     servaddr.sin_port = htons(SERV_PORT);
22     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
23 
24     bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
25     listen(listenfd, 20);
26 
27     printf("Accepting connections ...
");
28     while(1) {
29         struct sockaddr_in cliaddr = {0};
30         socklen_t cliaddr_len = sizeof(cliaddr);
31         int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
32 
33         char str[INET_ADDRSTRLEN];
34         printf("connect from %s at PORT %d
",
35                inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
36                ntohs(cliaddr.sin_port));
37         while(1) {
38             int count = read(connfd, buf, MAXLINE);
39             if(count == 0)
40                 break;
41 
42             if(!strcmp(buf, "Hello")) {
43                 printf("client send %s
", buf);
44                 write(connfd, "World", 6);
45             }
46         }
47         close(connfd);
48         printf("closed from %s at PORT %d
",
49                 inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
50                 ntohs(cliaddr.sin_port));
51     }
52     return 0;
53 }
server.c

 c端

 1 #include <stdio.h>
 2 #include <arpa/inet.h>
 3 #include <stdlib.h>
 4 #include <unistd.h>
 5 #include <sys/socket.h>
 6 #include <netinet/in.h>
 7 
 8 #define MAXLINE 80
 9 #define SERV_PORT 8000
10 #define MESSAGE "Hello"
11 
12 int main(int argc, char *argv[])
13 {
14         char buf[MAXLINE];
15 
16         int sockfd = socket(AF_INET, SOCK_STREAM, 0);
17 
18         struct sockaddr_in servaddr = {0};
19         servaddr.sin_family = AF_INET;
20         inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
21         servaddr.sin_port = htons(SERV_PORT);
22 
23         if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
24         {
25                 printf("connected failed");
26                 return 1;
27         }
28 
29         write(sockfd, MESSAGE, sizeof(MESSAGE));
30         int count = read(sockfd, buf, MAXLINE);
31 
32         printf("Response from server: %s
", buf);
33 
34         close(sockfd);
35         return 0;
36 }
client

然后把S端用EPOLL做成异步处理,可以同时给好几个C端回复。

 1 #include <iostream>
 2 #include <sys/socket.h>
 3 #include <sys/epoll.h>
 4 #include <netinet/in.h>
 5 #include <arpa/inet.h>
 6 #include <fcntl.h>
 7 #include <stdio.h>
 8 #include <unistd.h>
 9 #include <errno.h>
10 #include <stdlib.h>
11 #include <strings.h>
12 #include <string.h>
13 
14 using namespace std;
15 
16 #define MAXLINE   5
17 #define OPEN_MAX  100
18 #define LISTENQ   20
19 #define SERV_PORT 8000
20 #define INFTIM    1000
21 
22 int main(void)
23 {
24     int i, maxi, listenfd, connfd, sockfd, epfd, nfds;
25     ssize_t n;
26     char line[MAXLINE];
27     char buf[20];
28     socklen_t clilen;
29 
30     struct epoll_event ev, events[20];
31     epfd = epoll_create(256);
32     struct sockaddr_in clientaddr;
33     struct sockaddr_in serveraddr;
34     listenfd = socket(AF_INET, SOCK_STREAM, 0);
35 
36     ev.data.fd = listenfd;
37     ev.events = EPOLLIN | EPOLLET;
38     epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);
39 
40     bzero(&serveraddr, sizeof(serveraddr));
41     serveraddr.sin_family = AF_INET;
42     serveraddr.sin_port = htons(SERV_PORT);
43     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
44 
45     bind(listenfd, (sockaddr *)&serveraddr, sizeof(serveraddr));
46     listen(listenfd, LISTENQ);
47 
48     for( ; ; ) {
49         nfds = epoll_wait(epfd, events, 20, 500);
50 
51         for(i=0;i<nfds;i++) {
52             if(events[i].data.fd == listenfd) {
53                 clilen = sizeof(clientaddr);
54                 connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen);
55                 ev.data.fd = connfd;
56                 ev.events = EPOLLIN | EPOLLET;
57                 epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
58             } else if(events[i].events & EPOLLIN) {
59                 if((sockfd = events[i].data.fd) < 0) {
60                     continue;
61                 }
62                 if((n = read(sockfd, line, MAXLINE)) < 0) {
63                     if(errno == ECONNRESET) {
64                         close(sockfd);
65                         events[i].data.fd = -1;
66                     } else {
67                         std::cout<<"readline error"<<std::endl;
68                     }
69                 } else if(n == 0) {
70                     close(sockfd);
71                     events[i].data.fd = -1;
72                 }
73                 ev.data.fd = sockfd;
74                 ev.events = EPOLLOUT | EPOLLET;
75                 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
76             } else if(events[i].events & EPOLLOUT) {
77                 sockfd = events[i].data.fd;
78                 if(!strcmp(line, "Hello")) {
79                     strcpy(buf, "World");
80                     write(sockfd, buf, 6);
81                 }
82                 ev.data.fd = sockfd;
83                 ev.events = EPOLLIN | EPOLLET;
84                 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
85             }
86         }
87     }
88 }
epoll server

c端

 1 #include <stdio.h>
 2 #include <arpa/inet.h>
 3 #include <stdlib.h>
 4 #include <unistd.h>
 5 #include <sys/socket.h>
 6 #include <netinet/in.h>
 7 
 8 #define MAXLINE 80
 9 #define SERV_PORT 8000
10 #define MESSAGE "Hello"
11 
12 int main(int argc, char *argv[])
13 {
14         char buf[MAXLINE];
15 
16         int sockfd = socket(AF_INET, SOCK_STREAM, 0);
17 
18         struct sockaddr_in servaddr = {0};
19         servaddr.sin_family = AF_INET;
20         inet_pton(AF_INET, "192.168.1.63", &servaddr.sin_addr);
21         servaddr.sin_port = htons(SERV_PORT);
22 
23         if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)        {
24                 printf("connected failed");
25                 return 1;
26         }
27 
28         for( ; ;) {
29             write(sockfd, MESSAGE, sizeof(MESSAGE));
30             int count = read(sockfd, buf, MAXLINE);
31 
32             printf("Response from server: %s
", buf);
33             sleep(1);
34         }
35         close(sockfd);
36         return 0;
37 }
epoll client

4,然后把S做成多进程,任何一个进程收到任何一个C端的消息后,广播给其他进程,然后所有进程打印如下信息:“几号”进程收到“几号”客户端的“啥啥”消息(由“几号”进程转发)。不是转发的,括号内省略。“”内的替换为正确值。

S端:

 1 #ifndef _3PROCESS_FD_H_
 2 #define _3PROCESS_FD_H_
 3 
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 #include <iostream>
 8 
 9 using namespace std;
10 
11 #include <sys/socket.h>
12 #include <unistd.h>
13 #include <sys/wait.h>
14 #include <fcntl.h>
15 #include <sys/uio.h>
16 #include <sys/epoll.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include <strings.h>
22 #include <errno.h>
23 #include "3process_fun.h"
24 
25 typedef struct {
26         int index;
27         int chanel[2];
28 }process_t;
29 
30 #define MAXPROCESS 3
31 #define MAXLINE 100
32 
33 #define SERV_PORT  9876
34 
35 #endif
server.h
  1 #include "3process_fd.h"
  2 
  3 void setnonblocking(int sock)
  4 {
  5         int opts;
  6         opts = fcntl(sock, F_GETFL);
  7         if(opts < 0) {
  8                 cout<<"fcntl error"<<endl;
  9                 exit(1);
 10         }
 11 
 12         opts = opts | O_NONBLOCK;
 13         if(fcntl(sock, F_SETFL, opts) < 0) {
 14                 cout<<"set nonblock error"<<endl;
 15                 exit(1);
 16         }
 17 }
 18 
 19 void child_process(int index, process_t *processes)
 20 {
 21         cout<<"child "<<index<<" pid: "<<getpid()<<endl;
 22         struct epoll_event ev, events[20];
 23         int epfd, nfds, sockfd, listenfd, connfd;
 24         int i, n;
 25         char buf[MAXLINE], line[MAXLINE];
 26         struct sockaddr_in servaddr;
 27         struct sockaddr_in clientaddr;
 28         socklen_t clilen = sizeof(struct sockaddr_in);
 29 
 30         /* socket bind and listen */
 31         listenfd = socket(AF_INET, SOCK_STREAM, 0);
 32         setnonblocking(listenfd);
 33         bzero(&servaddr, sizeof(servaddr));
 34         servaddr.sin_family = AF_INET;
 35         servaddr.sin_port = htons(SERV_PORT);
 36         servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 37         bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
 38         listen(listenfd, 20);
 39 
 40         /* create epoll */
 41         epfd = epoll_create(256);
 42         ev.data.fd = (processes+index)->chanel[1];
 43         ev.events = EPOLLIN | EPOLLET;
 44         epoll_ctl(epfd, EPOLL_CTL_ADD, (processes+index)->chanel[1], &ev);
 45 
 46         ev.data.fd = listenfd;
 47         ev.events = EPOLLIN | EPOLLET;
 48         epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);
 49 
 50         for( ; ;) {
 51                 nfds = epoll_wait(epfd, events, 100, 500);
 52                 for(i=0;i<nfds;i++) {
 53                         if(events[i].data.fd == listenfd) {
 54                                 connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen);
 55                                 if(connfd < 0) {
 56                                         cout<<"[child"<<index<<"] accept error"<<endl;
 57                                         exit(1);
 58                                 }
 59                                 setnonblocking(connfd);
 60                                 char *str = inet_ntoa(clientaddr.sin_addr);
 61                                 cout<<"[child"<<index<<"] connect from "<<str<<endl;
 62                                 ev.data.fd = connfd;
 63                                 ev.events = EPOLLIN | EPOLLET;
 64                                 epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
 65                         } else if(events[i].data.fd == (processes+index)->chanel[1]) {
 66                                 read((processes+index)->chanel[1], buf, sizeof(buf));
 67                                 cout<<"child "<<index<<" recv: "<<buf<<endl;
 68                         } else if(events[i].events & EPOLLIN) {
 69                                 if((sockfd = events[i].data.fd) < 0) {
 70                                         ev.data.fd = sockfd;
 71                                         ev.events = EPOLLIN | EPOLLET;
 72                                         epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
 73                                         continue;
 74                                 }
 75                                 if((n = read(sockfd, line, MAXLINE)) < 0) {
 76                                         if(errno == ECONNRESET) {
 77                                                 close(sockfd);
 78                                                 events[i].data.fd = -1;
 79                                                 ev.data.fd = sockfd;
 80                                                 ev.events = EPOLLIN | EPOLLET;
 81                                                 epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
 82                                         } else {
 83                                                 cout<<"readline error"<<endl;
 84                                         }
 85                                 } else if(n == 0) {
 86                                         close(sockfd);
 87                                         events[i].data.fd = -1;
 88                                         ev.data.fd = sockfd;
 89                                         ev.events = EPOLLIN | EPOLLET;
 90                                         epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
 91                                         cout<<"[child"<<index<<"] close socket?"<<endl;
 92                                         continue;
 93                                 }
 94                                 cout<<"[child"<<index<<"] here is a EPOLLIN event."<<endl;
 95                                 ev.data.fd = sockfd;
 96                                 ev.events = EPOLLOUT | EPOLLET;
 97                                 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
 98                         } else if(events[i].events & EPOLLOUT) {
 99                                 if((sockfd = events[i].data.fd) < 0) {
100                                         ev.data.fd = sockfd;
101                                         ev.events = EPOLLIN | EPOLLET;
102                                         epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
103                                         continue;
104                                 }
105                                 if(!strcmp(line, "Hello")) {
106                                         strcpy(buf, "World");
107                                         write(sockfd, buf, strlen(buf));
108                                 }
109                                 cout<<"[child"<<index<<"] here is a EPOLLOUT event."<<endl;
110                                 ev.data.fd = sockfd;
111                                 ev.events = EPOLLIN | EPOLLET;
112                                 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
113                         }
114                 }
115         }
116 
117         exit(0);
118 }
119 
120 int main(int argc, char *argv[])
121 {
122         cout<<"current pid: "<<getpid()<<endl;
123         process_t *pprocess = (process_t *)malloc(sizeof(process_t)*MAXPROCESS);
124         int i;
125         int pid[MAXPROCESS];
126 
127         for(i=0;i<MAXPROCESS;i++) {
128                 (pprocess+i)->index = i;
129                 if(socketpair(AF_UNIX, SOCK_STREAM, 0, (pprocess+i)->chanel) == -1) {
130                         cout<<"failed to create domain socket by socketpair"<<endl;
131                         exit(1);
132                 }
133         }
134 
135         for(i=0;i<MAXPROCESS;i++) {
136                 pid[i] = fork();
137                 switch(pid[i]) {
138                         case -1:
139                                 cout<<"fork error"<<endl;
140                                 exit(-1);
141                         case 0:
142                                 child_process(i, pprocess);
143                                 exit(1);
144                         defualt:
145                                 cout<<"default?"<<endl;
146                                 break;
147                 }
148         }
149 
150         for(i=0;i<MAXPROCESS;i++) {
151                 write((pprocess+i)->chanel[0], "Hello child", strlen("Hello child"));
152         }
153 
154         for(;;) {
155                 pause();
156         }
157 }
server.cpp

C端:

 1 #include <stdio.h>
 2 #include <arpa/inet.h>
 3 #include <stdlib.h>
 4 #include <unistd.h>
 5 #include <sys/socket.h>
 6 #include <netinet/in.h>
 7 #include <errno.h>
 8 
 9 #define MAXLINE 80
10 #define SERV_PORT 9876
11 #define MESSAGE "Hello"
12 
13 int main(int argc, char *argv[])
14 {
15         char buf[MAXLINE];
16 
17         int sockfd = socket(AF_INET, SOCK_STREAM, 0);
18 
19         struct sockaddr_in servaddr = {0};
20         servaddr.sin_family = AF_INET;
21         inet_pton(AF_INET, "192.168.1.63", &servaddr.sin_addr);
22         servaddr.sin_port = htons(SERV_PORT);
23 
24         if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
25         {
26                 printf("connected failed:%d,%s",errno, strerror(errno));
27                 return 1;
28         }
29         while(1)
30         {
31                 write(sockfd, MESSAGE, sizeof(MESSAGE));
32 //              int count = read(sockfd, buf, MAXLINE);
33 
34 //              printf("Response from server: %s
", buf);
35                 sleep(6);
36         }
37 
38         close(sockfd);
39         return 0;
40 }
client.c
无欲速,无见小利。欲速,则不达;见小利,则大事不成。
原文地址:https://www.cnblogs.com/ch122633/p/8433307.html