首页 > 代码库 > 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。