zoukankan      html  css  js  c++  java
  • Linux下的echo服务器

    epoll模式下的echo服务器,忘记从哪个网页上粘贴过来的了,学习一下

     /*
     * main.cc
     *
     *  Created on: 2009-11-30
     *      Author: liheyuan
     *    Describe: epoll实现阻塞模式服务器(Echo服务器)
     *
     *   Last Date: 2009-11-30
     *   CopyRight: 2009 @ ICT LiHeyuan
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <sys/epoll.h>
    #include <errno.h>
     
    #define EPOLL_SIZE 10
    #define EVENT_ARR 20
    #define BACK_QUEUE 10
    #define PORT 18001
    #define BUF_SIZE 16
     
    void setnonblocking(int sockFd) {
        int opt;
     
        //获取sock原来的flag
        opt = fcntl(sockFd, F_GETFL);
        if (opt < 0) {
            printf("fcntl(F_GETFL) fail.");
            exit(-1);
        }
     
        //设置新的flag,非阻塞
        opt |= O_NONBLOCK;
        if (fcntl(sockFd, F_SETFL, opt) < 0) {
            printf("fcntl(F_SETFL) fail.");
            exit(-1);
        }
    }
     
    int main() {
     
        int serverFd;
     
        //创建服务器fd
        serverFd = socket(AF_INET, SOCK_STREAM, 0);
        setnonblocking(serverFd);
     
        //创建epoll,并把serverFd放入监听队列
        int epFd = epoll_create(EPOLL_SIZE);
        struct epoll_event ev, evs[EVENT_ARR];
        ev.data.fd = serverFd;
        ev.events = EPOLLIN | EPOLLET;
        epoll_ctl(epFd, EPOLL_CTL_ADD, serverFd, &ev);
     
        //绑定服务器端口
        struct sockaddr_in serverAddr;
        socklen_t serverLen = sizeof(struct sockaddr_in);
        serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        serverAddr.sin_port = htons(PORT);
        if (bind(serverFd, (struct sockaddr *) &serverAddr, serverLen)) {
            printf("bind() fail.
    ");
            exit(-1);
        }
     
        //打开监听
        if (listen(serverFd, BACK_QUEUE)) {
            printf("Listen fail.
    ");
            exit(-1);
        }
     
        //死循环处理
        int clientFd;
        sockaddr_in clientAddr;
        socklen_t clientLen;
        char buf[BUF_SIZE];
        while (1) {
            //等待epoll事件的到来,最多取EVENT_ARR个事件
            int nfds = epoll_wait(epFd, evs, EVENT_ARR, -1);
            //处理事件
            for (int i = 0; i < nfds; i++) {
                if (evs[i].data.fd == serverFd && evs[i].data.fd & EPOLLIN) {
                    //如果是serverFd,表明有新连接连入
                    if ((clientFd = accept(serverFd,
                            (struct sockaddr *) &clientAddr, &clientLen)) < 0) {
                        printf("accept fail.
    ");
                    }
                    printf("Connect from %s:%d
    ", inet_ntoa(clientAddr.sin_addr),
                            htons(clientAddr.sin_port));
                    setnonblocking(clientFd);
                    //注册accept()到的连接
                    ev.data.fd = clientFd;
                    ev.events = EPOLLIN | EPOLLET;
                    epoll_ctl(epFd, EPOLL_CTL_ADD, clientFd, &ev);
                } else if (evs[i].events & EPOLLIN) {
                    //如果不是serverFd,则是client的可读
                    if ((clientFd = evs[i].data.fd) > 0) {
                        //先进行试探性读取
                        int len = read(clientFd, buf, BUF_SIZE);
                        if (len > 0) {
                            //有数据可以读,Echo写入
                            do {
                                if (write(clientFd, buf, len) < 0) {
                                    printf("write() fail.
    ");
                                }
                                len = read(clientFd, buf, BUF_SIZE);
                            } while (len > 0);
                        } else if (len == 0) {
                            //出发了EPOLLIN事件,却没有可以读取的,表示断线
                            printf("Client closed at %d
    ", clientFd);
                            epoll_ctl(epFd, EPOLL_CTL_DEL, clientFd, &ev);
                            close(clientFd);
                            evs[i].data.fd = -1;
                            break;
                        } else if (len == EAGAIN) {
                            continue;
                        } else {
                            //client读取出错
                            printf("read() fail.");
                        }
                    }
                } else {
                    printf("other event.
    ");
                }
            }
        }
     
        return 0;
    }
    

    由于网页问题,粘贴过来的时候带着很多行号

    写了个程序解决这个问题

    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * @author 作者 E-mail:
     * @version 创建时间:2015-10-30 下午02:38:17 类说明 处理从网页上粘贴过来的代码
     */
    public class Test
    {
        public static void main(String[] args) throws IOException
        {
            FileInputStream inputStream = new FileInputStream("source");
    
            FileOutputStream outputStream = new FileOutputStream("res");
    
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
    
            int linenum = 0;
            final StringBuilder builder = new StringBuilder();
            String tempstr = null;
            String subStr = null;
            while ((tempstr = br.readLine()) != null)
            {
    
                subStr = tempstr.substring(getSize(++linenum));
                builder.append(subStr + '
    ');
            }
    
            outputStream.write(builder.toString().getBytes("gbk"));
        }
    
        public static int getSize(int lineNum)
        {
            int res = 1;
            while (lineNum / 10 > 0)
            {
                lineNum = lineNum / 10;
                res++;
            }
            return res;
        }
    }
    

      

  • 相关阅读:
    计算数组的逆序对个数
    处理类型(typedef,uisng,auto,decltype)
    constexpr与常量表达式(c++11标准)
    const的限定
    void*类型的指针
    linux终端拖动鼠标总是产生ctrl+c
    Linux hrtimer分析(2)
    Linux hrtimer分析(一)
    Alarm(硬件时钟) init
    第十一章 Android 内核驱动——Alarm
  • 原文地址:https://www.cnblogs.com/wuxinliulei/p/4923291.html
Copyright © 2011-2022 走看看