redhat enterprise 5 下的boost::asio 库应用(3)

既然asio以epoll为网络核心,为了认识epoll,我们来看看libev是如何工作的。


相比asio庞大的boost依赖,libev却是小巧轻便,高效。


列个demo


client:

#include "stdio.h"
#include "stdlib.h"
#include <iostream>
#include "netinet/in.h"
#include "sys/socket.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "arpa/inet.h"
#include "string.h"

int _clientsock;

struct sockaddr_in c_addr;

int main(int argc, char *argv[])
{
        int port = atoi(argv[1]);

        _clientsock = socket(AF_INET,SOCK_STREAM,0);

        c_addr.sin_family=AF_INET;

        c_addr.sin_port=htons(port);//6001);

        c_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

        connect(_clientsock,(struct sockaddr*)&c_addr,sizeof(struct sockaddr));

        //char str[32]="123456";
        static int x = 0;
        while(1)//x < 3)
        {
          char str[32]="123456";
          char c[32];
          sprintf(c,"%d\n",x);
          strcat(str,c);
          send(_clientsock,str,strlen(str)+1,0);
          char buffer[128]={'\0'};
          recv(_clientsock,buffer,128,0);
          printf(buffer);
          x++;
          //sleep(1000);
          getchar();
        }

        //char buffer[128]={'\0'};
        //recv(_clientsock,buffer,128,0);
        //printf(buffer);
        //close(_clientsock);
        getchar();
        return 0;
}

echoserver.cpp


编译命令:g++ -g -o echoserver -lev echoserver.cpp


注意链接上libev的静态库/动态库,究竟是哪个啊,还不清楚。


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
#include "arpa/inet.h"
#include <ev.h>
#define MAXLEN 1023
#define PORT 9999
#define ADDR_IP "127.0.0.1"


int socket_init();
void accept_callback(struct ev_loop *loop, ev_io *w, int revents);
void recv_callback(struct ev_loop *loop, ev_io *w, int revents);
void write_callback(struct ev_loop *loop, ev_io *w, int revents);


int main(int argc ,char** argv)
{
 int listen;
 ev_io ev_io_watcher;
 listen=socket_init();
 struct ev_loop *loop = ev_loop_new(EVBACKEND_EPOLL);
 ev_io_init(&ev_io_watcher, accept_callback,listen, EV_READ);
 ev_io_start(loop,&ev_io_watcher); 
 ev_loop(loop,0);
 ev_loop_destroy(loop);
 return 0;
 
}

 

int socket_init()
{
 struct sockaddr_in my_addr;
 int listener;
 if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
 {
  perror("socket");
  exit(1);
 } 
 else
 {
  printf("SOCKET CREATE SUCCESS!/n");
 }
 //setnonblocking(listener);
 int so_reuseaddr=1;
 setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&so_reuseaddr,sizeof(so_reuseaddr));
 bzero(&my_addr, sizeof(my_addr));
 my_addr.sin_family = PF_INET;
 my_addr.sin_port = htons(PORT);
 my_addr.sin_addr.s_addr = inet_addr(ADDR_IP);

 if (bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -1) 
 {
  perror("bind error!/n");
  exit(1);
 } 
 else
 {
  printf("IP BIND SUCCESS,IP:%s/n",ADDR_IP);
 }

 if (listen(listener, 1024) == -1) 
 {
  perror("listen error!/n");
  exit(1);
 } 
 else
 {
  printf("LISTEN SUCCESS,PORT:%d/n",PORT);
 }
 return listener;
}

 

void accept_callback(struct ev_loop *loop, ev_io *w, int revents)
{
 int newfd;
 struct sockaddr_in sin;
 socklen_t addrlen = sizeof(struct sockaddr);
 ev_io* accept_watcher=(ev_io*)malloc(sizeof(ev_io));
 while ((newfd = accept(w->fd, (struct sockaddr *)&sin, &addrlen)) < 0)
 {
  if (errno == EAGAIN || errno == EWOULDBLOCK) 
  {
   //these are transient, so don't log anything.
   continue; 
  }
  else
  {
   printf("accept error.[%s]/n", strerror(errno));
   break;
  }
 }
 ev_io_init(accept_watcher,recv_callback,newfd,EV_READ);
 ev_io_start(loop,accept_watcher);
 printf("accept callback : fd :%d/n",accept_watcher->fd);
 
}

void recv_callback(struct ev_loop *loop, ev_io *w, int revents)
{
 char buffer[1024]={0};
 int ret =0;
 //ev_io write_event;
loop:
 ret=recv(w->fd,buffer,MAXLEN,0);
 if(ret > 0)
 {
  printf("recv message :%s  /n",buffer);
  
 }
 else if(ret ==0)
 {
  printf("remote socket closed!socket fd: %d/n",w->fd);
  close(w->fd);
  ev_io_stop(loop, w);
  free(w);
  return;
 }
 else
 {
  if(errno == EAGAIN ||errno == EWOULDBLOCK)
  {
    goto loop;
  }
  else
  {
   printf("ret :%d ,close socket fd : %d/n",ret,w->fd);
   close(w->fd);
   ev_io_stop(loop, w);
   free(w);
   return;
  }
 }
 int fd=w->fd;
 ev_io_stop(loop,  w);
 ev_io_init(w,write_callback,fd,EV_WRITE);
 ev_io_start(loop,w);
 printf("socket fd : %d, turn read 2 write loop! ",fd);
 
}


void write_callback(struct ev_loop *loop, ev_io *w, int revents)
{
 char buffer[1024]={0};
 //ev_io read_event;
 snprintf(buffer,1023,"this is a test!");
 write(w->fd,buffer,strlen(buffer));
 int fd=w->fd;
 ev_io_stop(loop,  w);
 ev_io_init(w,recv_callback,fd,EV_READ);
 ev_io_start(loop,w);
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值