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.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\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 = gcc
CPPFLAGS = -DMODEL_THREAD
CFLAGS = -Wall -g
LDFLAGS =  -lpthread

TARGETS = echoserver echoclient

all:$(TARGETS)

clean:
    $(RM) $(TARGETS)

.PHONY: all clean

 

posted @ 2014-06-16 15:07  尾巴草  阅读(166)  评论(0编辑  收藏  举报