尝试新思路——跨平台Select模型
来源:互联网 发布:淘宝moschino 编辑:程序博客网 时间:2024/06/07 23:44
Select模型头文件
#ifndef __SELECT_H__#define __SELECT_H__#define ERROR_SELECT_MAXFD 1#define ERROR_SELECT_INVALID 2#define ERROR_SELECT_SOCKET 3namespace LinWin{ class CNetworkEvent; class CError; class CExit; class CSelectImpl { private: net_socket_fd m_fdListen; fd_set m_fdSocket; public: explicit CSelectImpl(net_socket_fd fdListen); void SetListenFd(net_socket_fd fdListen); int Select(CNetworkEvent* pEvent, CError* pError, CExit* pExit); };}#endif
实现文件
#include "Platform.h"#include "Select.h"#include "NetworkEvent.h"#include "Error.h"#include "Exit.h"#define MAX_CLIENT_NUM 16LinWin::CSelectImpl::CSelectImpl(net_socket_fd fdListen) : m_fdListen(fdListen){}void LinWin::CSelectImpl::SetListenFd(net_socket_fd fdListen){ if (m_fdListen == NET_INVALID_SOCKET) m_fdListen = fdListen;}int LinWin::CSelectImpl::Select(CNetworkEvent* pEvent, CError* pError, CExit* pExit){ int ret; int i, j; int nClientCount = 1; fd_set fdReads; if (m_fdListen == NET_INVALID_SOCKET) return ERROR_SELECT_SOCKET; FD_ZERO(&m_fdSocket); FD_SET(m_fdListen, &m_fdSocket); if (!pEvent || !pError || !pExit) return ERROR_SELECT_INVALID; net_socket_fd client_fd[MAX_CLIENT_NUM]; client_fd[0] = m_fdListen; for (int i = 1; i < MAX_CLIENT_NUM; i++) client_fd[i] = -1;#ifndef WINDOWS_FAMILY int maxfd;#endif while (1) { ret = 0; if (pExit->OnExit()) break; fdReads = m_fdSocket;#ifdef WINDOWS_FAMILY ret = ::select(0, &fdReads, NULL, NULL, NULL);#else maxfd = m_fdListen; for(i = 0; i < MAX_CLIENT_NUM; i++) { if (maxfd < client_fd[i]) maxfd = client_fd[i]; } ret = ::select(maxfd + 1, &fdReads, NULL, NULL, NULL);#endif if (ret > 0) { for (i = 0; i < MAX_CLIENT_NUM; i++) { if (FD_ISSET(client_fd[i], &fdReads)) { if (client_fd[i] == m_fdListen) { if (nClientCount < MAX_CLIENT_NUM) { net_socket_fd fdAccept = NET_INVALID_SOCKET; pEvent->OnAccept(fdAccept); if (fdAccept != NET_INVALID_SOCKET) { for (j = 1; j < MAX_CLIENT_NUM; j++) { if (client_fd[j] == -1) { client_fd[j] = fdAccept; FD_SET(fdAccept, &m_fdSocket); nClientCount++; break; } } } } else { pError->OnError(ERROR_SELECT_MAXFD, ELEVEL_WARNING); } } else { if (pEvent->OnRead(client_fd[i]) != 0) { if (pEvent->OnClose(client_fd[i]) != 0) closesocket(client_fd[i]); FD_CLR(client_fd[i], &m_fdSocket); client_fd[i] = -1; nClientCount--; } } } } } else { if (pError->OnError(ELEVEL_ERROR) != 0) break; } } return ret;}
测试文件main.cpp
#include <iostream>#include "Platform.h"#include "SocketImpl.h"#include "MyError.h"#include "MyExit.h"#include "MySelectEvent.h"#include "Select.h"using namespace std;int main(int argc, char* argv[]){ LinWin::CSocketAddress addr(NET_DEFAULT_IP, 6666); LinWin::CSocketImpl server; do { if (server.Create() != 0) { cout << "Create socket error." << endl; break; } if (server.Bind(addr) != 0) { cout << "Bind address errror." << endl; break; } if (server.Listen(2) != 0) { cout << "Listen error." << endl; break; } LinWin::CSelectImpl mySelect(server.Sockfd()); CMyError myError; CMyExit myExit; CMySelectEvent mySelectEvent(&server, &myExit); mySelect.Select(&mySelectEvent, &myError, &myExit); } while (0); return 0;}
测试程序给出的是服务器端的例子,客户端还可以用之前给出的客户端的例子。
0 0
- 尝试新思路——跨平台Select模型
- 尝试新思路——Select模型的另一种实现
- 尝试新思路——CError和CExit
- 尝试新思路——网络事件类CNetworkEvent
- 尝试新思路——CError的另一种实现方式
- 尝试新思路——CError、CExit和CNetworkEvent的一种实现
- 随笔——新思路
- 跨平台视频播放器——jplayer初尝试
- Iconfont——图标新思路
- Winsock——select模型
- select模型Client——》Server
- WinSocket模型的探讨——select模型
- WinSocket模型的探讨——select模型
- WinSocket模型的探讨——select模型
- WinSocket模型的探讨——select模型详解
- WinSocket模型的探讨——select模型
- WinSock I/O编程模型之——Select模型
- WinSocket模型的探讨——select模型
- 关于prefrenceactivity和preferencefragment的作用
- 【Gradle】gradle构建加速
- C++primer第4版第八章标准IO库
- JQuery 百度地图
- Exynos 4412 看门狗定时器中断
- 尝试新思路——跨平台Select模型
- python web前端后端页面详解
- avalon对象、对象数组、数组的基本操作
- Java笔记目录
- 订单的附件相关表关系
- Git过滤问题件(gitignore)下载地址
- Mining Twitter Data with Python Part 2: Text Pre-processing
- java自定义注解
- Android Model正确使用姿势——AutoValue