分析的代码来自飞天絮雪的博文处理大并发之二 对epoll的理解,epoll客户端服务端代码
服务器程序
1.创建epoll,epoll_create,得到m_EpollFd,并对其设置,设置非阻塞,fcntl
2. 创建socket,得到m_isock,socket;对m_isock进行设置,设置socket套接字级别的复用,setsockopt
3. 对m_isock进行操作,绑定IP及端口,bind
4. 对m_isock进行操作,监听该socket,并设置等待连接队列的最大长度,listen
5. 创建监听线程,注册ListenThread函数用于监听,pthread_create
6. 在ListenThread中对m_isock进行接收,得到客户端socket标识符client_socket 并把客户端地址保存于remote_addr,accept
7. 在epoll中添加该客户端的“数据进”等事件,epoll_ctl
8. 运行run函数,在其中对epoll事件进行处理
9. 对epoll事件进行查询,返回事件数目nfds,epoll_wait
10. 若是EPOLLIN事件则对该客户端进行数据读取,recv,读取成功后需在epoll中修改该客户端的事件条目,为“数据出”等事件,若读取失败,则删除该事件epoll_ctl
11. 若是“数据出”事件,对该客户端进行数据发送,send,若发送成功,则在epoll中修改该客户端的事件条目为“数据进”等事件,则若发送失败,删除该客户端的事件监听条目epoll_ctl
12. 若是其他事件,则是“错误”事件,在epoll中删除该客户端
13. 关闭监听socket放在析构函数中,但run中没有返回的语句,无法析构该对象,close
客户端程序
- 创建epoll,epoll_create
- 初始化m_pAllUserStatus,并用于存放Socket状态,设置状态为“FREE”
- socket创建,socket,设置复用setsockopt,并设置socket为非阻塞式,ioctl,设置Socket状态为“CONNECT_OK”
- 在epoll中添加该客户端的“数据进”等事件,epoll_ctl
- 对epoll事件进行查询,返回事件数目nfds,epoll_wait
- 当收到“数据进”事件,接收数据,recv,更改该标识符的事件条目为“数据出”事件
- 当收到“数据出”事件,查找该socket标识符对应的userid并发送相应数据,send,发送成功后更改该标识符的事件条目为“数据进”事件
- 在接收错误或者发送错误时,删除事件,释放user资源并关闭socket,close
m_iSockFd_UserId用于通过socket标识符查找userid,在epoll事件触发的时候使用,id传给SendToServerData,以发送对应id的UserStatus中的对应内容
m_pAllUserStatus用于创建并指向不同id的UserStatus
m_pAllUserStatus保证了不同的socket有不同的用户数据,m_iSockFd_UserId提供了查找到id号的方法,是用于定位相应用户数据的映射数组
此处在客户端使用此方法,可用于实现多socket通道下载
若把类似方法改造并应用在服务器,可实现对不同客户端的数据管理