zoukankan      html  css  js  c++  java
  • socket TCP服务 epoll



    // 服务器端 server.c #include
    <unistd.h> #include <sys/types.h> /* basic system data types */ #include <sys/socket.h> /* basic socket definitions */ #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */ #include <arpa/inet.h> /* inet(3) functions */ #include <sys/epoll.h> /* epoll function */ #include <fcntl.h> /* nonblocking */ #include <sys/resource.h> /*setrlimit */ #include <stdlib.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <signal.h>
    #define PORT 6888 #define MAXCLIENT 1000 #define MAXEPOLLSIZE 10000 #define MAXLINE 10240 int handle(int connfd); int setnonblocking(int sockfd) { if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) { return -1; } return 0; } int main(int argc, char **argv) { int listenq = 1024; int listenport = PORT; int listenfd, connfd, kdpfd, nfds, n, nread, curfds,acceptCount = 0; struct sockaddr_in servaddr, cliaddr; socklen_t socklen = sizeof(struct sockaddr_in); struct epoll_event ev; struct epoll_event events[MAXCLIENT]; struct rlimit rt; char buf[MAXLINE]; if (argc == 2) { listenport = atoi(argv[1]); } /* 设置每个进程允许打开的最大文件数 */ rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE; if (setrlimit(RLIMIT_NOFILE, &rt) == -1) { perror("setrlimit error"); return -1; } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); servaddr.sin_port = htons (listenport); listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenfd == -1) { perror("can't create socket file"); return -1; } int opt = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); signal(SIGPIPE,SIG_IGN); if (setnonblocking(listenfd) < 0) { perror("setnonblock error"); } if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1) { perror("bind error"); return -1; } if (listen(listenfd, MAXCLIENT) == -1) { perror("listen error"); return -1; } /* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */ kdpfd = epoll_create(MAXCLIENT); ev.events = EPOLLIN | EPOLLET; ev.data.fd = listenfd; if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev) < 0) { fprintf(stderr, "epoll set insertion error: fd=%d ", listenfd); return -1; } curfds = 1; printf("epollserver startup,port %d, max connection is %d, backlog is %d ", listenport, MAXCLIENT, listenq); for (;;) { /* 等待有事件发生 */ nfds = epoll_wait(kdpfd, events, curfds, -1); if (nfds == -1) { perror("epoll_wait"); continue; } /* 处理所有事件 */ for (n = 0; n < nfds; ++n) { if (events[n].data.fd == listenfd) { connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen); if (connfd < 0) { perror("accept error"); continue; } sprintf(buf, "accept form %s:%d ", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port); printf("%d:%s", ++acceptCount, buf); if (curfds > MAXCLIENT) { fprintf(stderr, "too many connection, more than %d ", MAXCLIENT); close(connfd); continue; } if (setnonblocking(connfd) < 0) { perror("setnonblocking error"); } ev.events = EPOLLIN | EPOLLET; ev.data.fd = connfd; if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev) < 0) { fprintf(stderr, "add socket '%d' to epoll failed: %s ", connfd, strerror(errno)); return -1; } curfds++; continue; } // 处理客户端请求 if (handle(events[n].data.fd) < 0) { epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev); curfds--; } } } close(listenfd); return 0; } int handle(int connfd) { int nread; char buf[MAXLINE]; memset(buf,0,sizeof(buf)); nread = read(connfd, buf, MAXLINE);//读取客户端socket流  struct sockaddr_in serv,guest; char serv_ip[20]; char guest_ip[20]; socklen_t serv_len = sizeof(serv); socklen_t guest_len = sizeof(guest); getsockname(connfd, (struct sockaddr *)&serv, &serv_len); getpeername(connfd, (struct sockaddr *)&guest, &guest_len); inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip)); inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip)); printf("guest %s:%d ",guest_ip, ntohs(guest.sin_port)); if (nread == 0) { printf("client close the connection "); close(connfd); return -1; } if (nread < 0) { perror("read error"); close(connfd); return -1; } printf(">> %s",buf); fflush(stdout); write(connfd, buf, nread);//响应客户端 return 0; }
    客户端 client.c
    
    #include  <unistd.h>
    #include  <sys/types.h>       /* basic system data types */
    #include  <sys/socket.h>      /* basic socket definitions */
    #include  <netinet/in.h>      /* sockaddr_in{} and other Internet defns */
    #include  <arpa/inet.h>       /* inet(3) functions */
    #include <netdb.h> /*gethostbyname function */
    
    #include <stdlib.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    
    #define MAXLINE 1024
    
    void handle(int connfd);
    
    int main(int argc, char **argv)
    {
        char * servInetAddr = "127.0.0.1";
        int servPort = 6888;
        char buf[MAXLINE];
        int connfd;
        struct sockaddr_in servaddr;
    
        if (argc == 2) {
            servInetAddr = argv[1];
        }
        if (argc == 3) {
            servInetAddr = argv[1];
            servPort = atoi(argv[2]);
        }
        if (argc > 3) {
            printf("usage: echoclient <IPaddress> <Port>
    ");
            return -1;
        }
    
        connfd = socket(AF_INET, SOCK_STREAM, 0);
    
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(servPort);
        inet_pton(AF_INET, servInetAddr, &servaddr.sin_addr);
    
        if (connect(connfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
            perror("connect error");
            return -1;
        }
        printf("welcome to echoclient
    ");
        handle(connfd);     /* do it all */
        close(connfd);
        printf("exit
    ");
        exit(0);
    }
    
    void handle(int sockfd)
    {
        char sendline[MAXLINE], recvline[MAXLINE];
        int n;
        for (;;) {
            if (fgets(sendline, MAXLINE, stdin) == NULL) {
                break;//read eof
            }
            /*
            //也可以不用标准库的缓冲流,直接使用系统函数无缓存操作
            if (read(STDIN_FILENO, sendline, MAXLINE) == 0) {
                break;//read eof
            }
            */
    
            n = write(sockfd, sendline, strlen(sendline));
            n = read(sockfd, recvline, MAXLINE);
            if (n == 0) {
                printf("echoclient: server terminated prematurely
    ");
                break;
            }
            write(STDOUT_FILENO, recvline, n);
            //如果用标准库的缓存流输出有时会出现问题
            //fputs(recvline, stdout);
        }
    }
    Talk is cheap, show me the code
  • 相关阅读:
    查看python中SQLite版本和sqlite3版本
    ubuntu系统安装与卸载
    CentOS下如何使用yum查看安装过的软件包
    【linux】CentOS7 升级sqlite3
    什么是Python的metaclass
    Python
    Python对字典分别按键(key)和值(value)进行排序
    python 用正则表达式去除特殊字符的两种方法
    从思维导图中学习javascript第五章字符串函数
    从思维导图中学习javascript第三章数组
  • 原文地址:https://www.cnblogs.com/birdBull/p/15156520.html
Copyright © 2011-2022 走看看