您的位置:首页 > 理论基础 > 计算机网络

小试牛刀TCP 网络编程模式,单线程多路复用实例

2013-11-05 11:12 281 查看
//server.c

#define USERNAME 0
#define USERPASS 1
#define PORT_SERV 8899
#define LISTENL 12
#define BUFSIZE 1024
typedef struct ClientRequest_t{int socet_in;int flog;int user_id;}ClientRequest;
struct userinfo{char username[32];char userpass[32];};typedef struct userinfo userinfo_c;userinfo_c users[]={{"linux","unix"},{"787","007"},{"gyeve","gaoyi"}};int send_data(int con,char *buf){int ret;int buf_size = strlen(buf);while(buf_size >0){ret=send(con,buf,buf_size,0);if(ret<=0){printf("send is wrong\n");return ret;}buf_size-= ret;buf+= ret;}return ret;}int find_name(char *name){int index=0;for(index=0;index<3;index++){printf("name = %s username = %s\n",name,users[index].username);if(strcmp(users[index].username,name)==0)return index;}return -1;}int main(int argc,char** argv){int socket_id,optval,accpt_len;struct sockaddr_in server_ad,client_ad;int acc_res, ret;pid_t pid;char buf[BUFSIZE];struct timeval tv;int i, maxi, maxfd,sockfd;int nready;ClientRequest client[FD_SETSIZE];fd_set readfds, allset;int HS_Socket_fd = -1;init_Textsignals();tv.tv_sec = 60;tv.tv_usec = 0;socket_id = socket(AF_INET,SOCK_STREAM,0);if(socket_id <=0) {perror("socket");exit(1);}optval=1;if(setsockopt(socket_id,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int))<0){/*设置窗口重新绑定*/perror("setsockopt");exit(1);}memset(&server_ad,0,sizeof(struct sockaddr_in));server_ad.sin_family = AF_INET; /*ipv4 of the tcp/ip protocol */server_ad.sin_port = htons(PORT_SERV);server_ad.sin_addr.s_addr = htonl(INADDR_ANY);/* the localhost ip address */if(bind(socket_id,(struct sockaddr *)&server_ad,sizeof(struct sockaddr_in))<0){perror("bind");exit(3);}if(listen(socket_id,LISTENL)<0){perror("listen");exit(4);}accpt_len= sizeof(struct sockaddr_in);maxfd = socket_id;                     /* initialize */maxi = -1;                           /* index into client[] array */for(i = 0; i < FD_SETSIZE; i++){client[i].socet_in = -1; /* -1 indicates available entry */client[i].user_id = -1;client[i].flog = USERNAME;}//memset(&client[i],-1,sizeof(ClenitRequset));FD_ZERO(&allset);FD_SET(socket_id, &allset);while(1){fprintf(stderr,"Waiting....\n");readfds = allset;  /* structure assignment */nready = select(maxfd+1, &readfds, NULL, NULL, NULL);if (nready < 0)perror("select error");if (FD_ISSET(socket_id, &readfds)) { /* new client connection */acc_res = accept(socket_id,(struct sockaddr *)&client_ad,&accpt_len);if(acc_res <0){if(errno == EINTR){continue;}perror("1accept");exit(1);}fprintf(stderr,"accept a new client ,the ip = %s\n",inet_ntoa(client_ad.sin_addr));for (i = 0; i < FD_SETSIZE; i++)if (client[i].socet_in < 0) {client[i].socet_in = acc_res; /* save descriptor */break;}if (i == FD_SETSIZE) {fprintf(stderr,"too many clients\n");exit(1);}FD_SET(acc_res, &allset);             /* add new descriptor to set */if (acc_res > maxfd)maxfd = acc_res; /* for select */if (i > maxi)maxi = i;          /* max index in client[] array */if (--nready == 0)continue;          /* no more readable descriptors */}for (i = 0; i <= maxi; i++) {          /* check all clients for data*/if ( (sockfd = client[i].socet_in) < 0)continue;if (FD_ISSET(sockfd, &readfds)) {memset(buf,0,BUFSIZE);if((ret=recv(sockfd,buf,BUFSIZE,0))<0){perror("recv");exit(1);}else if(!ret){client[i].flog = USERNAME;client[i].socet_in= -1;close(sockfd);FD_CLR(sockfd, &allset);fprintf(stderr,"client is die\n");break;}buf[ret]=0;fprintf(stderr,"buf = %s\n",buf);if(client[i].flog == USERNAME){client[i].user_id=find_name(buf);switch(client[i].user_id){case -1:send_data(sockfd,"n\n");break;default:send_data(sockfd,"y\n");client[i].flog = USERPASS;}}else if( client[i].flog == USERPASS ){if(strcmp(users[client[i].user_id].userpass,buf)==0){send_data(sockfd,"y\n");send_data(sockfd,"welcome login my cp server\n");fprintf(stderr,"%s login\n",users[client[i].user_id].username);client[i].flog = USERNAME;break;}elsesend_data(sockfd,"n\n");}if (--nready == 0)break;  /* no more readable  descriptors */}}fprintf(stderr,"again.............\n");}}//client.c#include<netinet/in.h>#include<sys/socket.h>#include<stdio.h>#include<strings.h>#include<arpa/inet.h>#define LEN 1024#define VALID 1#define INVALID 0int my_recv(int con, char buf[], int len){int ll;ll = recv(con,buf,len,0);if(ll<0){perror("recv");exit(1);}return ll;}void input_mess(int con, const char *string){char input_buf[32];char recv_buf[LEN];int flag_userinfo;int rev_len;do{printf("%s:",string);gets(input_buf);input_buf[strlen(input_buf)]=0;printf("%s:",input_buf);if(send(con,input_buf,strlen(input_buf),0)<0){perror("send");exit(1);}printf("send to server\n");if((rev_len = my_recv(con,recv_buf,sizeof(recv_buf)))<0){perror("my_recv");exit(1);}else if(rev_len == 0){printf("server is die\n");exit(1);}printf("recv = %s\n",recv_buf);if(recv_buf[0]=='y')flag_userinfo = VALID;elseflag_userinfo = INVALID;memset(recv_buf,0,sizeof(recv_buf));}while(flag_userinfo == INVALID);}int main(int argc, char *argv[]){int i,ret;int conn_fd,socketd;char recvbuf[LEN]={0};struct sockaddr_in serv_addr;if(argc!=5){printf("the argc is not equals 5\n");return -1;}memset(recvbuf,0,LEN);memset(&serv_addr,0,sizeof(struct sockaddr_in));serv_addr.sin_family=AF_INET;for(i=0;i<argc;i++){if(strcmp(argv[i],"-a")==0){i++;if(inet_aton(argv[i],&serv_addr.sin_addr)==0){printf("invaild server ip address \n");exit(1);}/*如果该for中两个条件的判定是通过两个if链接的,那么要使用continue*/}else if(strcmp(argv[i],"-p")==0){i++;int port = atoi(argv[i]);if(port<0||port>=65536) {printf("the port is overwiding\n");break;}else{serv_addr.sin_port = htons(port);}}}if(serv_addr.sin_addr.s_addr == 0||serv_addr.sin_port == 0){printf("usage [-a] [address] [-p] [port]\n");exit(1);}socketd = socket(AF_INET,SOCK_STREAM,0);conn_fd = connect(socketd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr));if(conn_fd<0){perror("connect");exit(1);}input_mess(socketd,"username");input_mess(socketd,"userpass");if((ret=my_recv(socketd,recvbuf,LEN))<0){printf("data is too long");exit(1);}recvbuf[ret]=0;printf("%s\n",recvbuf);return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: