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

来源:互联网 发布:湘北对陵南数据 编辑:程序博客网 时间:2024/09/21 09:02
//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;}else send_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;        else            flag_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;}


原创粉丝点击