首页 > 代码库 > TCP编程之一

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\n",__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\n",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!\n");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>\n",argv[0]);11         exit(0);12     }13     char *ipstr = argv[1];14     unsigned short port = strtol(argv[2],NULL,10);15 16     //2.socket17     int sockfd;18     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)19         ERR("socket failed");20 21     //3.connect22     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\n",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\n",msg);71     }72 }

 

 Makefile  

CC = gccCPPFLAGS = -DMODEL_THREADCFLAGS = -Wall -gLDFLAGS =  -lpthreadTARGETS = echoserver echoclientall:$(TARGETS)clean:    $(RM) $(TARGETS).PHONY: all clean