网络模块(1) 一.服务端: 暂时就以libevent模块,共享内存等下 1.GS打开,首先创建4个libevent子线程,当然为每个线程设置连接通知回调函数,这个是基于sockpair的,然后再创建一个监听线程,专门负责监听 2.监听线程收到一个连接后,通过轮询选择一个线程,然后向这个线程的conn_queue连接队列中插入一个libevent封装的一个socket,然后向socketpair中发送一个字节的数据 3.此时子线程会收到通知,从连接队列中弹出一个socket,然后创建一个基于此socket的bufferevnet,然后设置读事件和socket状态改变事件,此时服务器就准备好了客户端的连接 二.客户端: 打开客户端,对于客户端libevent是单线程的,客户端会调用libevent的接口, init--->创建m_base,调用windows初始化函数,设置回调函数指针 listen--->看了这么久,终于知道咋回事了,客户端是不需要监听,但他创建一个线程取循环eventbase是必须的 connectserver--->创建基于socket的bufferevent,然后连接,然后设置读写,事件回调 bool TcpLinkEx::Connect(int ip, int port) { { //关于此处加锁,个人觉得是因为此处是主线程操作g_curTcpLinkEx,等libevent线程回调也会操作这个g_curTcpLinkEx,所以加锁 std::lock_guard<std::mutex> lock(g_mux);//libevent回调TcpServer直接操作g_curTcpLinkEx,里面有m_event,调用NGP g_curTcpLinkEx = this;//这个设置成this,到时会调用同样的对象的,TcpLink的直接回调和libevent回调的会在一个客户端发生 } if(!m_tcpServer->connet_to(ip, port)) { m_event->OnConnectFailed();//直接操作M_EVENT,调用NGP return false; } return true; } bool NGP::OnConnectFailed() { std::lock_guard<std::mutex> lock(m_PktMutex);//此处加锁肯定是因为ngp里面应该有个线程取m_queFunctions中的数据 m_queFunctions.push(std::bind(&NGP::Connect2ServerFailed, this)); return true; } //这个是libevent回调的 void on_connect(int channel_id) { std::lock_guard<std::mutex> lock(g_mux); auto link = g_curTcpLinkEx; g_curTcpLinkEx = nullptr; g_TcpLinkExs[channel_id] = link; link->m_channel_id = channel_id; link->m_event->OnConnected();//到时会调用NGP的相关函数 }