• TCP编程之一


    一、基本模型(多进程多线程)

         apue.h  /usr/include 

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <errno.h>
     5 #include <sys/wait.h>
     6 #include <sys/ioctl.h>
     7 #include <sys/types.h>
     8 #include <fcntl.h>
     9 #include <pthread.h>
    10 #include<netinet/in.h>
    11 #include <arpa/inet.h>
    12 #include <signal.h>
    13 #include <sys/socket.h>
    14 #include <string.h>
    15 
    16 #define ERR(msg) do{    
    17     fprintf(stderr,"[%s:%d] %s:%s
    ",__FILE__,__LINE__,msg,strerror(errno));
    18     exit(-1);    
    19 }while(0)
    20 
    21 #define STREQ(s1,s2) (strcmp(s1,s2)==0)
    22 #define MAXER(n1,n2) ((n1)>(n2)?(n1):(n2))
    23 #define MINOR(n1,n2) ((n1)<(n2)?(n1):(n2))
    24 #define CLEAR(n) (memset(&n,0,sizeof(n)))

         echoserver.c 

      1 #include <apue.h>
      2 
      3 #define PORT 8080
      4 #define IP "192.168.5.99"
      5 #define BACKLOG 10
      6 
      7 void *routine(void *arg);
      8 void do_business();
      9 
     10 int main(int argc, char **argv)
     11 {
     12     int sockfd;
     13     //1.创建socket
     14     if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
     15         ERR("Socket failed");
     16     
     17     int val = 1;
     18     if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val))<0)
     19         ERR("set reuseaddr failed");
     20 #ifdef SO_REUSEPORT
     21     if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEPORT,&val,sizeof(val))<0)
     22         ERR("set reuseaddr failed");
     23 #endif
     24 
     25 #if 0
     26     struct sockaddr_in {
     27         sa_family_t sin_family;
     28         in_port_t sin_port;
     29         struct in_addr sin_addr;
     30         unsigned char sin_zero[8];
     31     };
     32 #endif
     33     //2.给socket绑定地址
     34     struct sockaddr_in ipv4, peer;
     35     ipv4.sin_family = AF_INET;
     36     ipv4.sin_port = htons(PORT);    //NBO
     37     inet_pton(AF_INET, IP, &ipv4.sin_addr);    //NBO
     38     memset(ipv4.sin_zero, 0, sizeof(ipv4.sin_zero));
     39     if (bind(sockfd, (struct sockaddr *) &ipv4, sizeof(ipv4)) < 0)
     40         ERR("bind failed");
     41 
     42     //3.监听
     43     if (listen(sockfd, BACKLOG) < 0)
     44         ERR("listen failed");
     45 
     46     //4.接收连接
     47     socklen_t len = sizeof(peer);    //value-result argument
     48     int connfd;
     49     for (;;) {
     50         if ((connfd = accept(sockfd, (struct sockaddr *) &peer, &len)) < 0)
     51             ERR("accept failed");
     52 
     53         unsigned short peerport = ntohs(peer.sin_port);
     54         char ipstr[] = "ddd.ddd.ddd.ddd";
     55         inet_ntop(AF_INET, &peer.sin_addr, ipstr, sizeof(ipstr));
     56 
     57         //5.通信
     58         char banner[255];
     59         sprintf(banner, "[%s:%d] welcome to echoserver!", ipstr,
     60             peerport);
     61         printf("Accept a new Connection: %s,%d
    ",ipstr,peerport);
     62         if(write(connfd, banner, strlen(banner)) < strlen(banner))
     63             ERR("write failed");
     64 
     65 #ifdef MODEL_THREAD
     66         pthread_t tid;
     67         if(pthread_create(&tid,NULL,routine,(void*)connfd))
     68             ERR("create thread failed");
     69 #elif MODEL_FORK
     70         pid_t pid;
     71         if((pid = fork())<0)
     72             ERR("fork failed");
     73         else if(pid==0)
     74         {
     75             close(sockfd);        //1.关闭无用描述符
     76             do_business(connfd);
     77             exit(0);            //2.显式指定退出
     78         }
     79         close(connfd);    
     80 #endif
     81     }
     82     //7.关闭服务器
     83     close(sockfd);
     84     return 0;
     85 }
     86 
     87 void do_business()
     88 {
     89     sleep(20);
     90 }
     91 
     92 void *routine(void *arg)
     93 {
     94     int connfd = (int)arg;
     95     char buf[255];
     96     int n;
     97     while(1)
     98     {
     99         if((n = read(connfd,buf,sizeof(buf)))<0)
    100             ERR("read failed");
    101         else if(n==0)
    102         {
    103             printf("Connection is closed by peer!
    ");
    104             goto end;
    105         }
    106         if(write(connfd,buf,n)<0)
    107             ERR("write failed");
    108     }
    109 end:
    110     close(connfd);
    111     return NULL;
    112 }

     

     echoclient.c  

     1 #include <apue.h>
     2 
     3 void do_business(int sockfd);
     4 
     5 int main(int argc,char **argv)
     6 {    
     7     //1.判断命令行
     8     if(argc!=3)
     9     {
    10         printf("Usage: %s <host> <port>
    ",argv[0]);
    11         exit(0);
    12     }
    13     char *ipstr = argv[1];
    14     unsigned short port = strtol(argv[2],NULL,10);
    15 
    16     //2.socket
    17     int sockfd;
    18     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)
    19         ERR("socket failed");
    20 
    21     //3.connect
    22     struct hostent *ent;
    23     if((ent=gethostbyname(ipstr))==NULL)
    24         ERR("gethostbyname failed");
    25 
    26     struct sockaddr_in peer;
    27     CLEAR(peer);
    28     peer.sin_family = AF_INET;
    29     peer.sin_port = htons(port);
    30     //inet_pton(AF_INET,ipstr,&peer.sin_addr);
    31     memcpy(&peer.sin_addr,ent->h_addr,sizeof(struct in_addr));
    32     if(connect(sockfd,(struct sockaddr*)&peer,sizeof(peer))<0)
    33         ERR("connect failed");
    34 
    35     //4.交互
    36     char banner[255];
    37     int n;
    38     if((n = read(sockfd,banner,sizeof(banner)))<0)
    39         ERR("read failed");
    40     else if(n==0)
    41         goto end;
    42     banner[n] = 0;
    43     printf("%s
    ",banner);
    44 
    45     do_business(sockfd);
    46 
    47     //5.关闭
    48 end:
    49     close(sockfd);
    50 
    51     return 0;
    52 }
    53 
    54 void do_business(int sockfd)
    55 {
    56     int n;
    57     char buf[255],msg[255];
    58     while(1)
    59     {
    60         printf("shell# ");
    61         fflush(stdout);
    62         scanf("%s",buf);
    63         if(write(sockfd,buf,strlen(buf))<0)
    64             ERR("write failed");
    65         if((n = read(sockfd,msg,sizeof(msg)))<0)
    66             ERR("read failed");
    67         else if(n==0)
    68             break;
    69         msg[n] = 0;
    70         printf("%s
    ",msg);
    71     }
    72 }

     Makefile  

    CC = gcc
    CPPFLAGS = -DMODEL_THREAD
    CFLAGS = -Wall -g
    LDFLAGS =  -lpthread
    
    TARGETS = echoserver echoclient
    
    all:$(TARGETS)
    
    clean:
        $(RM) $(TARGETS)
    
    .PHONY: all clean
  • 相关阅读:
    P2P理财友情提示
    P2P理财友情提示
    如何在Chrome development tool里查看C4C前台发送的请求细节
    CRM和ERP的Sales Organization的映射关系
    如何从ERP将Material的Batch信息下载到CRM并存储在settype COMM_PR_BATCH里
    CRM中间件里的发布-订阅者模式
    CRM订单状态的Open, In process和Completed这些条目是从哪里来的
    如何证明CRM WebClient UI上的应用是有状态(Stateful)的
    如何使用代码获得一个function module的Where Used List
    观察者模式在One Order回调函数中的应用
  • 原文地址:https://www.cnblogs.com/xiaoying1245970347/p/3790991.html
Copyright © 2020-2023  润新知