转:sock_ev——linux平台socket事件框架(基于字节流的测试程序) .

原文:http://blog.csdn.net/gdutliuyun827/article/details/8257186

由于工作与学习的需要,写了一个socket的事件处理框架,在公司写的已经使用了一段时间,下班后回家抽出时间又重写了一下,并进行了完善,起名为:sock_ev;

最近正在调试阶段,源代码暂且不提供,以防误人子弟,会尽快提供出来;先把最基本的测试程序贴上来,让感兴趣的同仁可以有个感性的认识,希望大家多加关注
 
支持以下功能:
1、三种事件监听方式:select、poll、epoll
2、对读、写事件进行监控
3、实现了inet域、unix域的通信
4、支持字节流、数据包两种方式
 
地址格式采取以下形式:
stream://192.168.2.10:8080
dgram://192.168.2.10:8080
stream://unix.domain.ipc
dgram://unix.domain.ipc

注:地址形式采取字符串的形式;stream与dgram分别表示收发数据时采用字节流与数据报的形式。在inet域进行数据传输时要指定ip地址与端口号,注意ip地址与端口号之间用“:”分割,我是用冒号区分的inet域还是unix域;在unix域传输数据时指定一个合法的路径(不要求路径真是存在,我会把它放在/proc下面)。对于inet域服务器端的ip地址支持“*”(i.e: stream://*:8888).

 
基于字节流的client端测试程序:
/***************************************************************************************
****************************************************************************************
* FILE        : client_test.h
* Description    :
*            
* Copyright (c) 2012 by Liu Yanyun(E-mail:liuyun827@foxmail.com). All Rights Reserved.
* Without permission, shall not be used for any commercial purpose
*
* History:
* Version        Name         Date            Description
   0.1        Liu Yanyun        2012/12/03        Initial Version


****************************************************************************************
****************************************************************************************/

#include "socket.h"
#include "log_trace.h"
#include "socket_addr.h"
#include "socket_base.h"
#include <iostream>

using namespace std;

int main()
{
  Socket *clt = Socket::create();//Socket类封装的socket相关的操作,创建一个Socket
  bool ret = clt->connect("stream://192.168.2.10:8080");//向服务器发起连接
  ret = ret;

  char buf[100] = {0};
  clt->recv(buf, sizeof(buf));//发送数据到server端
  cout<<buf<<endl;

  sprintf(buf, "%s", "hello too");
  clt->send(buf, strlen(buf));//接受server发送来的数据

  sleep(20);

  Socket::destroy(clt);//通讯结束销毁创建的Socket

  return 0;
}

server端测试程序:

/***************************************************************************************
****************************************************************************************
* FILE        : server_test.cc
* Description    :
*            
* Copyright (c) 2012 by Liu Yanyun(E-mail:liuyun827@foxmail.com). All Rights Reserved.
* Without permission, shall not be used for any commercial purpose
*
* History:
* Version        Name         Date            Description
   0.1        Liu Yanyun        2012/12/03        Initial Version

****************************************************************************************
****************************************************************************************/

#include "socket.h"
#include "log_trace.h"
#include "socket_addr.h"
#include "socket_base.h"
#include "event_loop.h"
#include <iostream>

using namespace std;

//有可读事件发生(有数据发送过)调用的callback
void readCb(EventLoop *loop_, Socket *sock_, EventType evt_, void *arg_)
{
  char buf[100] = {0};
  int ret = sock_->recv(buf, sizeof(buf));
  if(0 == ret)
  {
    loop_->removeEvt(sock_, evRead);
    Socket::destroy(sock_);
    printf("the other is connection is closed,destroy it ");
  }

  printf("buf:%s;arg:%s ", buf, (char*)arg_);
}

/*
接受新的连接请求的callback;loop_:所在的监听loop,sock_此处是server的Socket,evt_触发的事件,
arg_注册callback是传递的参数,类似于pthread_create()
*/
void acceptCb(EventLoop *loop_, Socket *sock_, EventType evt_, void *arg_)
{
  printf("accept callback trigger:%s ", (char*)arg_);
  Socket *conn = Socket::create();
  sock_->accept(conn);//接受客户端的连接,
  char *test = "test arg sock read";
  loop_->addEvt(conn, readCb, evRead, test);

  char buf[100] = {"hello"};
  conn->send(buf, strlen(buf));
}

int main()
{
  EventLoop loop;//EventLoop用于管理监听的事件,实现了select poll epoll
  loop.initialize(pollLoop);//此处使用poll方式; epollLoop:epoll; selectLoop:select

  Socket *ser = Socket::create();
  bool ret = ser->open("stream://192.168.2.10:8080");//在这个地址打开监听端口,可以用;stream://*:8080

  /*
   添加到事件监听框架中,采取使用callback的形式,下面注册的是read事件,最后的参数是当callback调用的时候回传递过去。
  */
  char *test = "test arg accept";
  loop.addEvt(ser, acceptCb, evRead, test);

  loop.listen(3000);//此处是循环监听事件的,内部会调用select、poll或epoll;有事件触发,会调用注册的callback

  Socket::destroy(ser);

  return 0;
}
上面的例子是inet域的数据传输,假如换成unix域的只需要把"stream://192.168.2.10:8080"修改为:"stream://unixDomainTest"即可。

原文地址:https://www.cnblogs.com/skyofbitbit/p/3672860.html