Unix-Linux编程实践教程——第十三章
来源:互联网 发布:log4j sql日志级别 编辑:程序博客网 时间:2024/06/04 19:51
章节概要
本章节介绍UDP编程以及编写许可证服务器
dgram.c
/********************************************************* > File Name: dgram.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 12时21分59秒 ********************************************************/#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<netdb.h>#include<string.h>#define HOSTLEN 256int get_internet_address(char* host,int len,int* portp,struct sockaddr_in *addrp){ strncpy(host,inet_ntoa(addrp->sin_addr),len); *portp = ntohs(addrp->sin_port); return 0;}//封装int make_internet_address(char* hostname,int port ,struct sockaddr_in *addrp){ struct hostent *hp; bzero((void*)addrp,sizeof(struct sockaddr_in)); hp = gethostbyname(hostname); if(hp==NULL) return -1; bcopy((void*)hp->h_addr,(void*)&addrp->sin_addr,hp->h_length); addrp->sin_port = htons(port); addrp->sin_family=AF_INET; return 0;}//封装服务器端的套接字建立以及绑定int make_dgram_server_socket(int portnum){ struct sockaddr_in saddr; char hostname[HOSTLEN]; int sock_id; sock_id = socket(PF_INET,SOCK_DGRAM,0); if(sock_id==-1) return -1; gethostname(hostname,HOSTLEN); printf("hostname :%s",hostname); make_internet_address(hostname,portnum,&saddr); if(bind(sock_id,(struct sockaddr*)&saddr,sizeof(saddr))!=0) return -1; return sock_id;}int make_dgram_client_socket(){ return socket(PF_INET,SOCK_DGRAM,0);}
dgrecv.c
/******************************************************** > File Name: dgrecv.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 11时16分53秒 ********************************************************/#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#define oops(m,x){perror(m);exit(x);}int make_dgram_server_socket(int);int get_internet_address(char*,int,int*,struct sockaddr_in*);void say_who_called(struct sockaddr_in*);int main(int ac,char *av[]){ int port; int sock; char buf[BUFSIZ]; ssize_t msglen; struct sockaddr_in saddr; socklen_t saddrlen; if(ac==1||(port=atoi(av[1]))<=0){ fprintf(stderr,"usage:dgrecv portnumber\n"); exit(1); } if((sock=make_dgram_server_socket(port))==-1) oops("cannot make socket",2); saddrlen = sizeof(saddr); while((msglen=recvfrom(sock,buf,BUFSIZ,0,&saddr,&saddrlen))>0){ buf[msglen]='\0'; printf("dgrecv:got a message:%s\n",buf); say_who_called(&saddr); } return 0;}void say_who_called(struct sockaddr_in *addrp){ char host[BUFSIZ]; int port; get_internet_address(host,BUFSIZ,&port,addrp); printf("from:%s:%d\n",host,port);}
dgsend.c
/********************************************************** > File Name: dgsend.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 11时24分58秒 *********************************************************/#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<string.h>#define oops(m,x){perror(m);exit(x);}int make_dgram_client_socket();int make_internet_address(char*,int,struct sockaddr_in*);int main(int ac,char *av[]){ int sock; char *msg; struct sockaddr_in saddr; if(ac!=4){ fprintf(stderr,"usage:dgsend host port 'message'\n"); exit(1); } msg = av[3]; if((sock=make_dgram_client_socket())==-1) oops("cannot make socket",2); make_internet_address(av[1],atoi(av[2]),&saddr); if(sendto(sock,msg,strlen(msg),0,&saddr,sizeof(saddr))==-1) oops("sendto failed",3); return 0;}
dgrecv2.c
/********************************************************** > File Name: dgrecv2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 11时16分53秒 ********************************************************/#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<string.h>#include<unistd.h>#define oops(m,x){perror(m);exit(x);}int make_dgram_server_socket(int);int get_internet_address(char*,int,int*,struct sockaddr_in*);void say_who_called(struct sockaddr_in*);void reply_to_sender(int,char*,struct sockaddr_in*,socklen_t);int main(int ac,char *av[]){ int port; int sock; char buf[BUFSIZ]; ssize_t msglen; struct sockaddr_in saddr; socklen_t saddrlen; if(ac==1||(port=atoi(av[1]))<=0){ fprintf(stderr,"usage:dgrecv portnumber\n"); exit(1); } if((sock=make_dgram_server_socket(port))==-1) oops("cannot make socket",2); saddrlen = sizeof(saddr); while((msglen=recvfrom(sock,buf,BUFSIZ,0,&saddr,&saddrlen))>0){ buf[msglen]='\0'; printf("dgrecv:got a message:%s\n",buf); say_who_called(&saddr); reply_to_sender(sock,buf,&saddr,saddrlen); } return 0;}void say_who_called(struct sockaddr_in *addrp){ char host[BUFSIZ]; int port; get_internet_address(host,BUFSIZ,&port,addrp); printf("from:%s:%d\n",host,port);}void reply_to_sender(int sock,char *msg,struct sockaddr_in* addrp,socklen_t len){ char reply[BUFSIZ+BUFSIZ]; sprintf(reply,"Thanks for your %lu char message\n",strlen(msg)); sendto(sock,reply,strlen(reply),0,addrp,len);}
dgsend2.c
/********************************************************* > File Name: dgsend2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 11时24分58秒 ********************************************************/#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<string.h>#define oops(m,x){perror(m);exit(x);}int make_dgram_client_socket();int make_internet_address(char*,int,struct sockaddr_in*);int main(int ac,char *av[]){ int sock; char *msg; char buf[BUFSIZ]; struct sockaddr_in saddr; socklen_t saddrlen; if(ac!=4){ fprintf(stderr,"usage:dgsend host port 'message'\n"); exit(1); } msg = av[3]; if((sock=make_dgram_client_socket())==-1) oops("cannot make socket",2); make_internet_address(av[1],atoi(av[2]),&saddr); if(sendto(sock,msg,strlen(msg),0,&saddr,sizeof(saddr))==-1) oops("sendto failed",3); saddrlen = sizeof(saddr); int msglen = recvfrom(sock,buf,BUFSIZ,0,&saddr,&saddrlen); if(msglen<=0) printf("receive msg err"); else{ buf[msglen]='\0'; printf("receive msg from server:%s\n",buf); } return 0;}
lclnt1.c
/******************************************************* > File Name: lclnt1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 13时47分59秒 *******************************************************/#include<stdio.h>#include<unistd.h>void do_regular_work(){ printf("SuperSleep version 1.0 Running-Licensed Software\n"); sleep(5);}int main(int ac,char *av[]){ setup(); if(get_ticket()!=0) exit(0); do_regular_work(); release_ticket(); shut_down(); return 0;}
lclnt_funcs1.c
/***************************************************** > File Name: lclnt_funcs1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 13时50分01秒 ******************************************************/#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<netdb.h>#include<string.h>#include<stdlib.h>#include<unistd.h>static int pid = -1;static int sd = -1;static struct sockaddr serv_addr;static socklen_t serv_alen;static char ticket_buf[128];static int have_ticket=0;#define MSGLEN 128#define SERVER_PORTNUM 2020#define HOSTLEN 512#define oops(p) {perror(p);exit(1);}char* do_transaction();void setup(){ char hostname[BUFSIZ]; pid = getpid(); sd = make_dgram_client_socket(); if(sd==-1) oops("Cannot create socket"); gethostname(hostname,HOSTLEN); make_internet_address(hostname,SERVER_PORTNUM,&serv_addr); serv_alen = sizeof(serv_addr);}void narrate(char *m1,char *m2){ fprintf(stderr,"CLIENT [%d]:%s %s\n",pid,m1,m2);}void syserr(char *msg){ char buf[MSGLEN]; sprintf(buf,"CLIENT [%d]:%s",pid,msg); perror(buf);}void shut_down(){ close(sd);}char* do_transaction(char* msg){ static char buf[MSGLEN]; struct sockaddr retaddr; socklen_t addrlen = sizeof(retaddr); int ret; ret = sendto(sd,msg,strlen(msg),0,&serv_addr,serv_alen); if(ret==-1){ syserr("sendto"); return NULL; } ret = recvfrom(sd,buf,MSGLEN,0,&retaddr,&addrlen); if(ret==-1){ syserr("recvfrom"); return NULL; } return buf;}int get_ticket(){ char *response; char buf[MSGLEN]; if(have_ticket) return 0; sprintf(buf,"HELO %d",pid); if((response=do_transaction(buf))==NULL){ return -1; } if(strncmp(response,"TICK",4)==0){ strcpy(ticket_buf,response+5); have_ticket = 1; narrate("got ticket",ticket_buf); return 0; } if(strncmp(response,"FAIL",4)==0) narrate("Could not get ticket",response); else narrate("Unknown message:",response); return -1;}int release_ticket(){ char buf[MSGLEN]; char *response; if(!have_ticket) return 0; sprintf(buf,"GBYE %s",ticket_buf); if((response=do_transaction(buf))==NULL) return -1; if(strncmp(response,"THNX",4)==0){ narrate("released ticket OK",""); return 0; } if(strncmp(response,"FAIL",4)==0){ narrate("release failed",response+5); }else{ narrate("Unknown message:",response); } return -1;}
lserv1.c
/*********************************************************** > File Name: lserv1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 14时23分06秒 *********************************************************/#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<signal.h>#include<sys/errno.h>#define MSGLEN 128int main(int ac,char *av[]){ struct sockaddr_in client_addr; socklen_t addrlen = sizeof(client_addr); char buf[MSGLEN]; int ret; int sock; sock = setup(); while(1){ addrlen = sizeof(client_addr); ret = recvfrom(sock,buf,MSGLEN,0,&client_addr,&addrlen); if(ret!=-1){ buf[ret]='\0'; narrate("GOT:",buf,&client_addr); handle_request(buf,&client_addr,addrlen); }else if(errno!=EINTR) perror("recvfrom"); } return 0;}
lsrv_funcs1.c
/************************************************************* > File Name: lsrv_funcs1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 14时27分17秒 ***********************************************************/#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<netdb.h>#include<signal.h>#include<sys/errno.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#include<arpa/inet.h>#define SERVER_PORTNUM 2020#define MSGLEN 128#define TICKET_AVAIL 0#define MAXUSERS 3#define oops(x) {perror(x);exit(-1);}int ticket_array[MAXUSERS];int sd = -1;int num_tickets_out = 0;char *do_hello();char *do_goodbye();void free_all_tickets(){ int i; for(i=0;i<MAXUSERS;++i){ ticket_array[i]=TICKET_AVAIL; }}void shut_down(){ close(sd);}void narrate(char *msg1,char *msg2,struct sockaddr_in *clientp){ fprintf(stderr,"\t\tSERVER:%s %s",msg1,msg2); if(clientp) fprintf(stderr,"(%s:%d)",inet_ntoa(clientp->sin_addr),ntohs(clientp->sin_port)); putc('\n',stderr);}char *do_hello(char *msg_p){ int x; static char replybuf[MSGLEN]; if(num_tickets_out>=MAXUSERS) return "FAIL no tickets available"; for(x=0;x<MAXUSERS&&ticket_array[x]!=TICKET_AVAIL;++x); if(x==MAXUSERS){ narrate("database corrupt","",NULL); return "FAIL database corupt"; } ticket_array[x] = atoi(msg_p+5); sprintf(replybuf,"TICK %d.%d",ticket_array[x],x); num_tickets_out++; return replybuf;}char *do_goodbye(char *msg_p){ int pid,slot; if((sscanf((msg_p+5),"%d.%d",&pid,&slot)!=2)|| (ticket_array[slot]!=pid)){ narrate("Bogus ticket",msg_p+5,NULL); return "FAIL invalid ticket"; } ticket_array[slot] = TICKET_AVAIL; num_tickets_out--; return "THNX See ya!";}void handle_request(char *req,struct sockaddr_in *client,socklen_t addlen){ char *response; int ret; if(strncmp(req,"HELO",4)==0) response = do_hello(req); else if(strncmp(req,"GBYE",4)==0) response = do_goodbye(req); else response = "FAIL invalid request"; narrate("SAID:",response,client); ret = sendto(sd,response,strlen(response),0,client,addlen); if(ret==-1) perror("SERVER sendto failed");}int setup(){ sd = make_dgram_server_socket(SERVER_PORTNUM); if(sd==-1) oops("make socket"); free_all_tickets(); return sd;}
lserv2.c
/********************************************************** > File Name: lserv2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 14时23分06秒 ********************************************************/#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<signal.h>#include<sys/errno.h>#define MSGLEN 128int main(int ac,char *av[]){ struct sockaddr_in client_addr; socklen_t addrlen = sizeof(client_addr); char buf[MSGLEN]; int ret; int sock; unsigned time_left; sock = setup(); signal(SIGALRM,ticket_reclaim); alarm(RECLAIM_INTERVAL); while(1){ addrlen = sizeof(client_addr); ret = recvfrom(sock,buf,MSGLEN,0,&client_addr,&addrlen); if(ret!=-1){ buf[ret]='\0'; narrate("GOT:",buf,&client_addr); //当在调用alarm()前已经设置了一个闹钟,那么我们可以调用alarm(0)来取消此闹钟,并返回剩余时间。 time_left = alarm(0); handle_request(buf,&client_addr,addrlen); alarm(time_left); }else if(errno!=EINTR) perror("recvfrom"); } return 0;}
lsrv_funcs2.c
/********************************************************** > File Name: lsrv_funcs2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月18日 星期三 14时27分17秒 ***********************************************************/#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<netdb.h>#include<signal.h>#include<sys/errno.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#include<arpa/inet.h>#define RECLAIM_INTERVAL 60#define SERVER_PORTNUM 2020#define MSGLEN 128#define TICKET_AVAIL 0#define MAXUSERS 3#define oops(x) {perror(x);exit(-1);}int ticket_array[MAXUSERS];int sd = -1;int num_tickets_out = 0;char *do_hello();char *do_goodbye();void free_all_tickets(){ int i; for(i=0;i<MAXUSERS;++i){ ticket_array[i]=TICKET_AVAIL; }}void shut_down(){ close(sd);}void narrate(char *msg1,char *msg2,struct sockaddr_in *clientp){ fprintf(stderr,"\t\tSERVER:%s %s",msg1,msg2); if(clientp) fprintf(stderr,"(%s:%d)",inet_ntoa(clientp->sin_addr),ntohs(clientp->sin_port)); putc('\n',stderr);}//添加计时器处理,防止客户端断开失去连接,没有返回票的情况void ticket_reclaim(){ int i; char tick[BUFSIZ]; for(i=0;i<MAXUSERS;++i){ if((ticket_array[i]!=TICKET_AVAIL)&&(kill(ticket_array[i],0)==-1)&&(errno==ESRCH)){ sprintf(tick,"%d.%d",ticket_array[i],i); narrate("freeing",tick,NULL); ticket_array[i]=TICKET_AVAIL; num_tickets_out--; } } alarm(RECLAIM_INTERVAL);}char *do_hello(char *msg_p){ int x; static char replybuf[MSGLEN]; if(num_tickets_out>=MAXUSERS) return "FAIL no tickets available"; for(x=0;x<MAXUSERS&&ticket_array[x]!=TICKET_AVAIL;++x); if(x==MAXUSERS){ narrate("database corrupt","",NULL); return "FAIL database corupt"; } ticket_array[x] = atoi(msg_p+5); sprintf(replybuf,"TICK %d.%d",ticket_array[x],x); num_tickets_out++; return replybuf;}char *do_goodbye(char *msg_p){ int pid,slot; if((sscanf((msg_p+5),"%d.%d",&pid,&slot)!=2)|| (ticket_array[slot]!=pid)){ narrate("Bogus ticket",msg_p+5,NULL); return "FAIL invalid ticket"; } ticket_array[slot] = TICKET_AVAIL; num_tickets_out--; return "THNX See ya!";}static char *do_validate(char *msg){ int pid,slot; if(sscanf(msg+5,"%d.%d",&pid,&slot)==2&&ticket_array[slot]==pid) return "GOOD Valid ticket"; narrate("Bogus ticket",msg+5,NULL); return "FAIL invalid ticket";}void handle_request(char *req,struct sockaddr_in *client,socklen_t addlen){ char *response; int ret; if(strncmp(req,"HELO",4)==0) response = do_hello(req); else if(strncmp(req,"GBYE",4)==0) response = do_goodbye(req); else if(strncmp(req,"VALD",4)==0) response = do_validate(req); else response = "FAIL invalid request"; narrate("SAID:",response,client); ret = sendto(sd,response,strlen(response),0,client,addlen); if(ret==-1) perror("SERVER sendto failed");}int setup(){ sd = make_dgram_server_socket(SERVER_PORTNUM); if(sd==-1) oops("make socket"); free_all_tickets(); return sd;}
logfiled.c
/********************************************************** > File Name: logfiled.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 11时40分50秒 ********************************************************/#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/un.h>#include<time.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#define MSGLEN 512#define oops(m,x) {perror(m);exit(x);}#define SOCKNAME "/tmp/logfilesock"//使用Unix域的socket地址,只有同一台主机上的客户才能发消息给它int main(){ int sock; struct sockaddr_un addr; socklen_t addrlen; char msg[MSGLEN]; int l; char sockname[]=SOCKNAME; time_t now; int msgnum = 0; char *timestr; addr.sun_family = AF_UNIX; strcpy(addr.sun_path,sockname); addrlen = strlen(sockname)+sizeof(addr.sun_family); sock = socket(PF_UNIX,SOCK_DGRAM,0); if(sock==-1) oops("socket",2); if(bind(sock,(struct sockaddr*)&addr,addrlen)==-1) oops("bind",3); while(1){ l = read(sock,msg,MSGLEN); msg[l] = '\0'; time(&now); timestr = ctime(&now); timestr[strlen(timestr)-1]='\0'; printf("[%5d]%s %s\n",msgnum++,timestr,msg); fflush(stdout); } return 0;}
logfilec.c
/****************************************************** > File Name: logfilec.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 11时49分16秒 ******************************************************/#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/un.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#define SOCKET "/tmp/logfilesock"#define oops(m,x) {perror(m);exit(x);}int main(int ac,char *av[]){ int sock; struct sockaddr_un addr; socklen_t addrlen; char sockname[]=SOCKET; char *msg = av[1]; if(ac!=2){ fprintf(stderr,"usage:logfilec 'message'\n"); exit(1); } sock = socket(PF_UNIX,SOCK_DGRAM,0); if(sock==-1) oops("socket",2); addr.sun_family = AF_UNIX; strcpy(addr.sun_path,sockname); addrlen = strlen(sockname)+sizeof(addr.sun_family); if(sendto(sock,msg,strlen(msg),0,&addr,addrlen)==-1) oops("sendto",3); return 0;}
阅读全文
0 0
- Unix-Linux编程实践教程——第十三章
- Unix-Linux编程实践教程——第二章
- Unix-Linux编程实践教程——第三章
- Unix-Linux编程实践教程——第四章
- Unix-Linux编程实践教程——第五章
- Unix-Linux编程实践教程——第六章
- Unix-Linux编程实践教程——第七章
- Unix-Linux编程实践教程——第八章
- Unix-Linux编程实践教程——第九章
- Unix-Linux编程实践教程——第十章
- Unix-Linux编程实践教程——第十一章
- Unix-Linux编程实践教程——第十二章
- Unix-Linux编程实践教程——第十四章
- Unix-Linux编程实践教程——第十五章
- Unix/Linux编程实践教程
- Unix/Linux编程实践教程
- Unix-linux编程实践教程
- Unix/Linux 编程实践教程 第6章 笔记
- The Dominant Color (20)
- 自主订餐脚本
- 二叉树的递归遍历算法解析
- 生命3.0读书笔记
- 两个互相引用对象的垃圾回收
- Unix-Linux编程实践教程——第十三章
- 字符串截取(记一次工作总结)
- SpringMVC实现文件上传下载
- JZ2440 第6章 存储控制器
- ajax提交表单和文件上传
- tensorflow之可视化工具tesorboard的简单使用
- ACM学习总结之A+B问题
- 面试编程题3:元素去重
- IDENTITY_INSERT