日期:2014-05-16  浏览次数:20635 次

epoll开发ftp服务器
这是我用作epoll_event.data.ptr的结构:

typedef struct buf
{
    int sock;
    void (* func)(int datasock);  //用于设置不同命令的处理函数
    int ptr[1024];
    int len;
}

如果只有两个socket,比较简单,一个msg_socket负责读用户命令,然后设置data_socket的处理函数。但是如果有多个监听套接字又怎么办呢(高性能的服务器经常这样)?当有socket可读时,把命令读出来,这个时候怎么知道设置哪个socket的处理函数呢?

ftp用两个socket分别进行数据读写,这点比较蛋疼啊,要是一个的话就没这么多事了...

------解决方案--------------------
epoll.data.fd存储socket就可以了,维护全局session数组(链表),维护全局O(1)访问的socekt_array为下标的socket信息。

对于一个client,创建一个session_st, 其内部有command_st和data_st,让command_st和data_st,给command_st做一个初始化,因为此刻还没创建data_st的sock进行数据通信。 将command_st放入sockinfo_st.sock的data,设置command_st的callback放入sockinfo_st,注册sockinfo_st到socket array,注册epoll对该sock的监听。

将来有从command_st的cb里意识到有data_st的需求,那么就可以根据comand_st->session->data_st来操作data相关的socket进行注册和监听了。

epoll返回fd,你用fd查socket array得到sockinfo, 回调cb传入data,你的cb执行cmd/data的业务逻辑,根据需要从cmd/data反查session得到其他信息。

struct sockinfo_st {
    void *data;
    callback_t cb;
};

struct session_st {
   index/next,prev;
   command_st;
   data_st;
};

struct command_st {
    session_st;
    buf,
    sock
    callback
};

struct data_st {
    session_st;
    buf,
    sock
    callback
};