使用epoll,完成简单http消息回显,并用浏览器测试

epoll_tcp.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/epoll.h>

static int startup(const char *_ip,int _port)
{
 int sock=socket(AF_INET,SOCK_STREAM,0);
 if(sock<0){
  perror("socket");
  exit(2);
 }

struct sockaddr_in local;
 local.sin_family=AF_INET;
 local.sin_port=htons(_port);
 local.sin_addr.s_addr=inet_addr(_ip);

if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0){
  perror("bind");
  exit(3);
 }

if(listen(sock,5)<0){
  perror("listen");
  exit(4);
 }
 return sock;
}

static int set_noblock(int sock)
{
 int fl=fcntl(sock,F_GETFL);
 return fcntl(sock,F_SETFL,fl|O_NONBLOCK);
}

static void usage(const char *proc )
{
 printf("usage: %s [ip] [port]\n",proc);
}

int main(int argc,char *argv[])
{
 if(argc!=3){
  usage(argv[0]);
  exit(1);
 }
 int listen_sock=startup(argv[1],atoi(argv[2])); //cteate listen socket

int epfd=epoll_create(256);
 if(epfd<0){
  perror("epoll_create");
  exit(5);
 }

struct epoll_event _ev;
 _ev.events=EPOLLIN;
 _ev.data.fd=listen_sock;

epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &_ev);

struct epoll_event _ready_ev[128];
 int  _ready_evs=128;
 int _timeout=-1; //block

int nums=0;
 int done=0;
 while(!done){
  switch( (nums=epoll_wait(epfd, _ready_ev,\
      _ready_evs, _timeout)) ){
   case 0:
    printf("timeout...\n");
    break;
   case -1:
    perror("epoll_wait");
    break;
   default:
    {
     int i=0;
     for(; i< nums; ++i){
      int _fd=_ready_ev[i].data.fd;
      if(_fd==listen_sock && \
        _ready_ev[i].events & EPOLLIN){
       //get a new link...
       struct sockaddr_in peer;
       socklen_t len=sizeof(peer);
       int new_sock=accept(listen_sock,(struct sockaddr*)&peer, &len);
       if(new_sock > 0){
        printf("client info, socket: %s:%d\n", inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
        _ev.events=EPOLLIN | EPOLLET;//ET
        _ev.data.fd=new_sock;

set_noblock(new_sock);

epoll_ctl(epfd, EPOLL_CTL_ADD,\
          new_sock, &_ev);
       }
      }else{
       if(_ready_ev[i].events & EPOLLIN){
        char buf[102400];
        memset(buf, ‘\0‘, sizeof(buf));
        //read/write
        ssize_t _s=recv(_fd, buf,\
          sizeof(buf)-1,0);//while need recv done...

if( _s > 0){
         printf("client# %s\n",buf);
         _ev.events=EPOLLOUT | EPOLLET;
         _ev.data.fd=_fd;
         epoll_ctl(epfd, EPOLL_CTL_MOD,\
           _fd, &_ev);
        }else if( _s==0 ){
         printf("client close...\n");
         epoll_ctl(epfd,EPOLL_CTL_DEL,\
           _fd, NULL);
         close(_fd);
        }else{
         perror("recv");
        }
       }else if(_ready_ev[i].events &\
         EPOLLOUT){
        const char *msg="HTTP/1.1 200 OK\r\n\r\n<h1>hello world  =_=|| </h1>\r\n";
        send(_fd, msg, strlen(msg),0);
        epoll_ctl(epfd,EPOLL_CTL_DEL,_fd, NULL);
        close(_fd);
       }
      }
     }
    }
    break;
  }
 }
}

时间: 2024-10-26 18:09:57

使用epoll,完成简单http消息回显,并用浏览器测试的相关文章

SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显

在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/

《UNIX网络编程》TCP客户端服务器:并发、消息回显

经过小小改动,把前面基础的例子做出一点修改. 并发服务器,服务器每accept一个请求就fork()一个新的子进程. 编译运行方法同前一篇. /*client_tcp.c*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #incl

SpringMVC09 Converter变流器、数据回显、异常测试

1.配置web.xml文件 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name>

基于epoll的简单服务器

一.epoll 1.epoll只有epoll_create,epoll_ctl,epoll_wait 3个系统调用 (1)int epoll_create(int size); 创建一个epoll的句柄.自从linux2.6.8之后,size参数是被忽略的.需要注意的是,当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽. (2)int epoll

springmvc学习笔记(15)-数据回显

springmvc学习笔记(15)-数据回显 springmvc学习笔记15-数据回显 pojo数据回显方法 简单类型数据回显 本文介绍springmvc中数据回显的几种实现方法 数据回显:提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面. pojo数据回显方法 1.springmvc默认对pojo数据进行回显. pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写) 使用@ModelAttribute

【SSH项目实战】国税协同平台-25.查询条件回显

我们上次完成了信息发布管理模块的条件查询功能,但是我们有一些问题没有解决,比如信息的"回显"功能. 解释一下回显,例如你翻到100页,这一页有一个信息需要修改,当你点击修改并修改完毕的时候,发现并没有回到之前的第100页,而是回到了第1页!!你是不是就抓狂了?而且你在输入框中的的查询条件也可能改变或消失,这就是没有做数据回显的后果.所以,我们要为我们的这个模块做数据回显功能. 我们去分类查询的依据就是info.title值,如果有,我们就按照那个排序并列出结果,如果没有我们就去取所有的

epoll 回显服务器源码

在写epoll回显服务器代码之前,可以先看看上一篇文章:select poll epoll三者之间的比较.最近在继续学习网络编程中的服务端编程中,了解到很多网游服务器是在IOMP(IO完成端口)框架下写的,但是这种方式只能在 Windows 下使用,奇了怪了,这么好的东西为什么不在Linux下也实现一套呢?这个问题我继续学习IOMP再来谈一谈! epoll是linux下高并发服务器的完美方案,因为是基于事件触发的,所以比select快的不只是一个数量级.单线程epoll,触发量可达到15000,

Linux终端下简单的登录程序 密码不回显

在Linux进行登录是输入密码不会被回显,所以我也写了个简单的登入程序,使得在输入密码时不再进行回显. #include <stdio.h> #include <stdlib.h> #include <termios.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdbool.h> #define USER_NAME &qu

socket编写简单回显server

socket在公司代码中应用比较广,比如接口调用的IPCRPC机制,经常看到这样的代码,但是一直也没有动手写过. 在某个比较大的进程中创建一个子进程,由于父子进程复制会浪费内存,可以将创建进程的命令通过socket发送到另一个轻量级的进程来创建. 在lighttpd和airplay的源码中,socket的框架是类似的. 下面参照lighttpd和airplay写个简单的回显server,以后有空再完善. server.c #include <stdio.h>#include <strin