• 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
    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    java核心学习(二十七) 多线程---线程相关类
    java核心学习(二十六) 多线程---线程池
    java核心学习(二十五) 多线程---线程组和未处理的异常
    java核心学习(二十四) 多线程---线程通信
    java核心学习(二十三) 多线程---线程同步
    java核心学习(二十二) 多线程---线程控制
    模线性方程 poj2115
    求两个圆的重合面积+二分 hdu3264
    求多边形面积 HDU2036
    判断两直线是否相交 hdu1086
  • 原文地址:https://www.cnblogs.com/ch122633/p/8433307.html
Copyright © 2020-2023  润新知