基于resion实现epoll的Socket服务器

原创 2007年09月30日 15:17:00

最近用java开发了一个游戏服务,老板要求采用Epoll模式.现在项目已做完,把实现epoll的经验和大伙共享一下:

关于epoll的介绍这里就不多说,网上一大把.

1.从resion的官网上下载resin-3.0.22版本(里面就有一个例子,我就是用这例子改改而以)

2.创建ServerProtocol类

package com.wd.dzpk.SocketServer;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Logger;

import com.caucho.server.connection.Connection;
import com.caucho.server.port.Protocol;
import com.caucho.util.L10N;

/**
 *
 */
public class ServerProtocol extends Protocol {
 static protected final Logger log = Logger.getLogger(ServerProtocol.class
   .getName());

 static final L10N L = new L10N(ServerProtocol.class);

 private String _protocolName = "magic8ball";

 /**
  * Construct.
  */
 public ServerProtocol() {
 }

 /**
  * Returns the protocol name.
  */
 public String getProtocolName() {
  return _protocolName;
 }

 /**
  * Sets the protocol name.
  */
 public void setProtocolName(String name) {
  _protocolName = name;
 }

 /**
  * Create a Magic8BallRequest object for the new thread.
  */
 public MyServerRequest createRequest(Connection conn) {
  return new MyServerRequest(this, conn);
 }
 

}

关键是MyServerRequest 方法(),用于初始化

3.创建MyServerRequest 类

package com.wd.dzpk.SocketServer;

/**
 *
 * TODO 创建和管理消息类
 *
 */
import java.io.IOException;

import com.caucho.server.connection.Connection;
import com.caucho.server.port.ServerRequest;
import com.caucho.vfs.ReadStream;
import com.caucho.vfs.WriteStream;
import com.wd.dzpk.util.Constant;
import com.wd.dzpk.util.Log;

/**
 * Protocol specific information for each request. An instance of this object
 * may be reused to reduce memory allocations.
 */
public class MyServerRequest implements ServerRequest {

 // 连接
 Connection _conn;

 ServerProtocol _protocol;

 Parser _parser = new Parser();

 Magic8Ball _magic8ball = new Magic8Ball();

 /**
  * 在收连接请求,交给此方法处理所有消息
  *
  * @param ServerProtocol
  * @param Connection
  * @return void
  */
 public MyServerRequest(ServerProtocol protocol, Connection conn) {
  _protocol = protocol;
  _conn = conn;
 }

 /**
  * Initialize the connection. At this point, the current thread is the
  * connection thread.
  */
 public void init() {

 }

 /**
  * Handle a new connection. The controlling Server may call handleRequest
  * again after the connection completes, so the implementation must
  * initialize any variables for each connection.
  */
 public boolean handleRequest() throws IOException {
  Log.debugLog("收到" + _conn.getRemoteHost() + "的请求");
  ReadStream readStream = _conn.getReadStream();
  WriteStream writeStream = _conn.getWriteStream();
  try {
   _parser.init(readStream, writeStream);
   AbstractCommand cmd = null;
   do {
    cmd = _parser.nextCommand();
    // 如果是第一条消息,将连接和用户ID进行绑定保存
    if (null != cmd) {
     if (cmd.getIsFirstMsg()) {
      ConObj conObj = new ConObj();
      conObj.setConn(_conn);
      conObj.setUserId(cmd.getUserId());
      // 保存到系统常量中,供全局使用
      Constant.AllConnList.add(conObj);
      Log.debugLog("收到第一条消息,将连接对象进行保存.用户ID为:"
        + cmd.getUserId());
     } else if (cmd.getIsExitMsg()) {
      // 从连接列表删除相应的连接
      for (int i = 0; i < Constant.AllConnList.size(); i++) {
       if (cmd.getUserId()
         .equals(
           ((ConObj) Constant.AllConnList
             .get(i)).userId)) {
        Constant.AllConnList.remove(i);
        // 付值为null,会关闭与客户端的连接
        cmd = null;
        break;
       }
      }
      Log.debugLog("用户ID为:" + cmd.getUserId()
        + "客户端关闭了,删除连接成功");
     }
    }
   } while (null != cmd);
  } catch (Throwable e) {
   Log.warningLog("系统出错,原因:" + e.getMessage());
  }
  return false;

 }

 /*
  * (non-Javadoc)
  *
  * @see com.caucho.server.port.ServerRequest#isWaitForRead()
  */
 public boolean isWaitForRead() {
  // TODO Auto-generated method stub
  return false;
 }

 /*
  * (non-Javadoc)
  *
  * @see com.caucho.server.port.ServerRequest#protocolCloseEvent()
  */
 public void protocolCloseEvent() {
  // TODO Auto-generated method stub

 }
}
4.配置resin-3.0.22/conf/resin.conf,在resion启动时,会自动去调用ServerProtocol类来初始化

  打开resion.conf文件,找到<server>元素.插入以下代码

<port id='' host='*' port='13000'>
      <protocol resin:type="com.wd.dzpk.SocketServer.ServerProtocol"/>
    </port>

 如下:

<server>
    <port id='' host='*' port='13000'>
      <protocol resin:type="com.wd.dzpk.SocketServer.ServerProtocol"/>
    </port>

    <!-- adds all .jar files under the resin/lib directory -->
    <class-loader>
      <tree-loader path="${resin.home}/lib"/>
      <tree-loader path="${server.root}/lib"/>
    </class-loader>

就这么简单,如果需要源码,可以发邮件给我.

网络编程(10)基于epoll的服务器实现

关于epoll的相关知识我不就写了,只把我弄的例子写下,我整的这个epoll服务器其实就只是把man epoll中举得那个例子给做完善了。 主要参考了man epoll和百度百科中关于epoll的介绍...
  • xcltapestry
  • xcltapestry
  • 2014年02月16日 23:21
  • 1995

socket编程 -- epoll模型服务端/客户端通信的实现

本例实现如下功能: 支持多客户端与一个服务端进行通信,客户端给服务端发送字符串数据,服务端将字符串中小写转为大写后发送回客户端,客户端打印输出经转换后的字符串。 例如:发送abcde,打印输出AB...
  • y396397735
  • y396397735
  • 2016年02月17日 14:43
  • 2521

基于epoll的简单的http服务器

本人用epoll写了一个简单的http服务器,该服务器在客户端第一次发送数据时可以正确处理,但是当客户端不关闭继续发送数据时,服务器无法读取,请求大家帮忙看看哪里有问题,谢谢server.h/* *...
  • fangjian1204
  • fangjian1204
  • 2014年06月25日 10:04
  • 2682

基于的epoll模型的简单http服务器

epoll模型主要有2种工作方式:水平触发(LT)和边缘触发(ET),本文主要是关于边缘触发的。 本文实现的epoll多线程模型主要是,主线程等待事件触发,然后把相关事件放入队列,线程池从队列中取出数...
  • baudgg1992
  • baudgg1992
  • 2016年04月14日 21:13
  • 816

epoll+socket实现 socket并发 linux服务器 (c)

本次源代码为网络上转载的,若有侵权,请联系本人,QQ:1031893464,及时删除。 本次因为学习,参考参考别人的代码,下次才发表自己写的epoll并发服务器。 /* 实现功能:通过epoll,...
  • u012997311
  • u012997311
  • 2017年06月22日 10:52
  • 803

Linux下的socket编程实践(九) epoll实现高并发的原理及其使用

在 linux 没有实现 epoll 事件驱动机制之前,我们一般选择用 selec t或者 poll 等IO多路复用的方法来实现并发服务程序(详见此链接)。在大数据、高并发、集群等一些名词唱得火热...
  • NK_test
  • NK_test
  • 2015年10月22日 12:03
  • 4362

采用epoll实现echo server和client

转自 http://zhouxiaodan.blog.51cto.com/1177793/1176286 #include #include #include #include ...
  • boyhailong
  • boyhailong
  • 2014年01月17日 20:50
  • 1876

几种典型的服务器网络编程模型归纳(select poll epoll)

1、同步阻塞迭代模型 同步阻塞迭代模型是最简单的一种IO模型。其核心代码如下:bind(srvfd); listen(srvfd); for(;;) { clifd = accept(srv...
  • drdairen
  • drdairen
  • 2016年12月17日 10:52
  • 3171

利用socket自己实现基于HTTP协议的Web服务器

在开发网站的过程中,首先我们需要配置一个web服务器,一般会使用Apache这个开源的服务器软件,扩展性高,支持性也很好。实际上如果是windows系统的话那么也可以使用windows操作系统提供的I...
  • bobopeng
  • bobopeng
  • 2014年01月14日 11:26
  • 2760

简述epoll并发网络编程方法

本文简要对比了并发网络编程中常用的epoll和select方法,对epoll方法的api进行简单描述,提供了一个epoll编程的基本框架...
  • topgunliu
  • topgunliu
  • 2016年04月28日 22:16
  • 410
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:基于resion实现epoll的Socket服务器
举报原因:
原因补充:

(最多只允许输入30个字)