| |
来源: ChinaUnix博客 日期: 2008.08.31 15:20 (共有条评论) 我要评论 | |
/* common_talk.h */ #include #include #include #include #include #include #include #include #define MAXMSG 1024 #define MSG_FD_NUM 2 #define MSG_FD_STDIN 0 #define MSG_FD_SOCK 1 char msgbuf[MAXMSG+2]; // \r \0 void do_talk(int new_fd) { fd_set rfds; struct timeval tv; int maxfd; int fdsets[MSG_FD_NUM]; fdsets[MSG_FD_STDIN] = STDIN_FILENO; fdsets[MSG_FD_SOCK] = new_fd; int len,i; printf("input the message you want,then press Enter(\"quit\"---end this talk)\n"); while(1){ FD_ZERO(&rfds); FD_SET(fdsets[MSG_FD_STDIN],&rfds); FD_SET(fdsets[MSG_FD_SOCK],&rfds); //检测标准输入和通话套接字 tv.tv_sec = 1; tv.tv_usec = 0; //等待一秒; maxfd = fdsets[MSG_FD_STDIN] > fdsets[MSG_FD_SOCK] ? fdsets[MSG_FD_STDIN]:fdsets[MSG_FD_SOCK]; if(select(maxfd+1,&rfds,NULL,NULL,&tv)>%s",msgbuf); printf("\t\tsend message sucess ---- totally send %d bytes message\n",len); break; case MSG_FD_SOCK: memset(msgbuf,0x00,sizeof(msgbuf)); if((len=recv(new_fd,msgbuf,MAXMSG,0))>0){ printf("server received>> %s \n",msgbuf); printf("\t\treceived message success ----totally received %d bytes messages\n",len); }else{ if(len ==0) printf("client exited\n"); else printf("receive error,errno=%d error information:%s",errno,strerror(errno)); return ; } break; } } }//for }//while } void sig_chld(int signum) { pid_t pid; int status; printf("recived SIGCHLD,child process exited,"); while((pid = waitpid(-1,&status,WNOHANG))>0){ printf("pid =%d\n",pid); } return; } /* server.c*/ #include"common_talk.h" void usage(void) { fprintf(stderr,"\nmyserver usage:\n"); fprintf(stderr,"./myserver -p -b [-h]\n"); fprintf(stderr," -p server's port\n");\ fprintf(stderr," -b queue number of pending connections\n"); fprintf(stderr," -h how to use\n"); return; } void getmyopt(int *port, int *backlog,int argc, char *argv[]) { char ch; *port =0; *backlog =0; while( (ch=getopt(argc,argv,":p:b:h")) != -1 ){ switch(ch){ case 'p': *port = atoi(optarg); break; case 'b': *backlog = atoi(optarg); break; case 'h': usage(); break; case ':': printf("%s:option -%c requires an argument\n",argv[0],optopt); exit(1); case '?': printf("%s:option -%c is an invalid argument\n",argv[0],optopt); exit(1); } } if(*port ==0 || *backlog==0){ printf("option -p and -b must be given\n"); usage(); exit(1); } } int main(int argc, char *argv[]) { struct sockaddr_in srvaddr,cliaddr; int sock_fd,new_fd; int opt = 1,len; int sin_size; pid_t pid; char hostname[20]; int status; int n,ret; int srvport,backlog; getmyopt(&srvport,&backlog,argc,argv); sock_fd = socket(AF_INET, SOCK_STREAM,0); if(sock_fd==-1){ perror("socket\n"); exit(1); } memset(&srvaddr,0x00,sizeof(srvaddr)); memset(&cliaddr,0x00,sizeof(cliaddr)); memset(msgbuf,0x00,sizeof(msgbuf)); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(srvport); srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); len = sizeof(opt); if(setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,&opt,len) -a [-h]\n"); fprintf(stderr," -p server's port\n");\ fprintf(stderr," -a server's address\n"); fprintf(stderr," -h how to use\n"); return; } void getmyopt(int *port, char *ip,int argc, char *argv[]) { char ch; *port =0; while( (ch=getopt(argc,argv,":p:a:h")) != -1 ){ switch(ch){ case 'p': *port = atoi(optarg); break; case 'a': printf("optarg=%s\n",optarg); sprintf(ip,"%s",optarg); break; case 'h': usage(); break; case ':': printf("%s:option -%c requires an argument\n",argv[0],optopt); exit(1); case '?': printf("%s:option -%c is an invalid argument\n",argv[0],optopt); exit(1); } } if(*port ==0 || *ip==0){ printf("option -p and -a must be given\n"); usage(); exit(1); } } int main(int argc, char *argv[]){ struct sockaddr_in srvaddr; int sockfd,new_fd; int opt = 1,len; int sin_size; char ip[20]; int srvport; int n; memset(ip,0x00,20); memset(&srvaddr,0x00,sizeof(srvaddr)); sockfd = socket(AF_INET, SOCK_STREAM,0); if(sockfd==-1){ perror("socket\n"); exit(1); } getmyopt(&srvport,ip,argc,argv); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(srvport); srvaddr.sin_addr.s_addr = inet_addr(ip); sockfd = socket(AF_INET, SOCK_STREAM,0); if(sockfd==-1){ perror("socket\n"); exit(1); } len = sizeof(opt); if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,len) < 0){ perror("setsockopt"); exit(1); } printf("client socket initilize success\n"); if(connect(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr)) < 0){ printf("connect:%s",strerror(errno)); close(sockfd); exit(1); } printf("connect to a server success\n"); do_talk(sockfd); close(sockfd); } 主要知识点: 1.在命令行方式下的参数处理,使用getopt()函数可以处理短参数方式,如果参数后跟一个参数值,则optarg指向这个参数值,如果为无效参数,getopt返回“:”,如果需要跟一个参数值而没有跟,则返回“?” 可以使用getopt_long处理长参数方式。 2.网络中处理客户端通常采用多进程方式,采用select轮询,不过现在为支持大吞吐量好像使用epoll很好。 3.信号量的捕捉,通常是不建议在信号函数中使用printf等不可重入函数,例子只是为了演示。 |
网络编程第一篇:客户--服务器通信(非阻塞,多进程)
最新推荐文章于 2020-08-18 13:39:04 发布