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.\n");
        exit(-1);
    }
 
    //打开监听
    if (listen(serverFd, BACK_QUEUE)) {
        printf("Listen fail.\n");
        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.\n");
                }
                printf("Connect from %s:%d\n", 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.\n");
                            }
                            len = read(clientFd, buf, BUF_SIZE);
                        } while (len > 0);
                    } else if (len == 0) {
                        //出发了EPOLLIN事件,却没有可以读取的,表示断线
                        printf("Client closed at %d\n", 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.\n");
            }
        }
    }
 
    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 + '\n');
        }

        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;
    }
}

  

posted @ 2015-10-30 14:55  无心流泪  阅读(584)  评论(0编辑  收藏  举报