socket编程:多路复用之select

来源:互联网 发布:ae软件中文版免费版 编辑:程序博客网 时间:2024/04/29 04:52


server_select.c

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#define BLOCK 6int fds[64];void usage(char * proc){    printf("%s [ip] [port]\n",proc);}int create_sock(char *port,const char * inaddr){    //1.    int listenfd=socket(AF_INET,SOCK_STREAM,0);    if(listenfd<-1){        perror("listenfd");        exit(1);    }    //2.    struct sockaddr_in local;    local.sin_family=AF_INET;    int _port=atoi(port);    local.sin_port=htons(_port);    local.sin_addr.s_addr=inet_addr(inaddr);    struct linger lig;    int iLen;    lig.l_onoff=1;    lig.l_linger=0;    iLen=sizeof(struct linger);    setsockopt(listenfd,SOL_SOCKET,SO_LINGER,(char *)&lig,iLen);    //3.    if(bind(listenfd,(struct sockaddr*)&local,sizeof(local))<0){        perror("bind");        exit(2);    }    //4.    if(listen(listenfd,BLOCK)<0){        perror("listen");        exit(3);    }    return listenfd;}int main(int argc,char* argv[]){    if(argc!=3){        usage(argv[0]);        exit(1);    }    int listen_fd=create_sock(argv[2],argv[1]);    //  printf("fd_set=%d\n",sizeof(fd_set));    struct sockaddr_in client;    socklen_t len=sizeof(client);    int max_fd=listen_fd;    char buf[1024];    //initialize fds[]    int fds_num=sizeof(fds)/sizeof(fds[0]);    int i=0;    for(i=0;i<fds_num;++i){        fds[i]=-1;    }    fds[0]=listen_fd;    int done=0;    while(!done){        //define and initialize parameter of select()         fd_set readset;        FD_ZERO(&readset);        FD_SET(listen_fd,&readset);                struct timeval timeout;        timeout.tv_sec=5;        timeout.tv_usec=0;        //        for(i=1;i<fds_num;++i){            if(fds[i]>0){                FD_SET(fds[i],&readset);                if(fds[i]>max_fd)                    max_fd=fds[i];            }            else                break;        }        switch(select(max_fd+1,&readset,NULL,NULL,&timeout)){            case -1:                perror("select");                break;            case 0:                printf("timeout...\n");                break;            default:                for(i=0;i<fds_num;++i){                    //listen_fd happen                    if(fds[i]==listen_fd && FD_ISSET(fds[i],&readset)){                        int connfd=accept(listen_fd,(struct sockaddr*)&client,&len);                        if(connfd<0){                            perror("accept");                            break;                        }else{                            printf("get a connect...\n");                            for(i=0;i<fds_num;++i){                                if(fds[i]==-1){                                    fds[i]=connfd;                                    FD_SET(connfd,&readset);                                    break;                                }                            }                        }                    }                    //normal event happen                    else if(fds[i]>0 && FD_ISSET(fds[i],&readset)){                            ssize_t _size=read(fds[i],buf,sizeof(buf)-1);                            if(_size<0){                                perror("read");                            }else if(_size==0){//client closed                                printf("client shutdown...\n");                                close(fds[i]);                                fds[i]=-1;                                continue;                            }else{                                buf[_size]='\0';                                printf("client# %s",buf);                                while(write(fds[i],buf,sizeof(buf)-1)<0){                                    perror("write");                                }                            }                    }                    else{                    }                }                break;        }    }    return 0;}
<span style="color:#cc0000;"><strong>client_select.c</strong></span>
<pre name="code" class="cpp">#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <errno.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <arpa/inet.h>#include <netinet/in.h>void usage(char *proc){    printf("%s [ip] [port]\n",proc);}int creat_socket(){    int fd=socket(AF_INET,SOCK_STREAM,0);    if(fd<0){        perror("socket");        exit(1);    }       return fd;}
int main(int argc,char* argv[]){    if(argc!=3){        usage(argv[0]);        exit(1);    }    int fd=creat_socket();    int _port=atoi(argv[2]);    struct sockaddr_in addr;    addr.sin_family=AF_INET;    addr.sin_port=htons(_port);    inet_aton(argv[1],&addr.sin_addr);    socklen_t addrlen=sizeof(addr);    if(connect(fd,(struct sockaddr*)&addr,addrlen)<0){        perror("connect");        exit(2);    }        char buf[1024];    while(1){        memset(buf,'\0',sizeof(buf));        printf("Please Enter:");        fgets(buf,sizeof(buf)-1,stdin);        if(send(fd,buf,sizeof(buf)-1,0)<0){            perror("send");            continue;        }        ssize_t _size=recv(fd,buf,sizeof(buf)-1,0);        if(_size>0){            buf[_size]='\0';            printf("echo->%s\n",buf);        }    }       return 0;}


运行结果:

服务器端结果

客户端运行结果


0 0
原创粉丝点击