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
};