📄 dpsocketmodel.h
字号:
//DPEventSocket.h: interface for the CDPSocketModel class.
//功能描述:该类是SOCKET通讯综合模型,该类完成后将包装各种SOCKET
// 通讯模式(阻塞select,异步窗口,异步事件,重叠I/O,完成I/O)
// 等.它可以被各种通讯程序方便采用.尤其是基于SERVER/CLIENT
// 的SERVER程序会提高大幅度性能.如果使用人要完成特定的通讯
// 功能可以从该类继承,增加对线程池的支持功能。
//
//开发时间:2001.5.16 至 2001.xx.xx
//
//作者:高越 邮箱:darkprince@v.cn
//QQ:1738387 (本人只接受技术探讨以及软件项目合作事宜,其他误扰)
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DPEVENTSOCKET_H__8790D406_A2C2_4446_90B1_AC06156DDA73__INCLUDED_)
#define AFX_DPEVENTSOCKET_H__8790D406_A2C2_4446_90B1_AC06156DDA73__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifdef _NEED_ATL
#define ASSERT ATLASSERT
#endif
#include <winsock2.h>
//宏
#define Min(a, b) (((a) < (b)) ? (a): (b))
#define Max(a, b) (((a) > (b)) ? (a): (b))
#define INext(i, n) ((((i) + 1) < (n)) ? ((i) + 1): 0)
#define IPrev(i, n) (((i) > 0) ? ((i) - 1): ((n) - 1))
const int SOCKET_SUCCESS = 0;//与SOCKET_ERROR对应的成功标志
const DWORD DP_SHUTDOWN_RECV_TIMEOUT = 4*1000; // 优雅关闭时延迟4秒
const DWORD DP_DEFAULT_TIMEOUT = 120*1000;// 120秒 缺省超时
const int DP_SOCKET_BUFFER_SIZE = 4096;// 缓冲区缺省大小
const DWORD DP_CONNECT_TIMEOUT = 120*1000;// 120秒 连接超时
const DWORD DP_SEND_TIMEOUT = 120*1000;// 120秒 发送超时
const DWORD DP_RECV_TIMEOUT = 120*1000;// 120秒 接收超时
const int DP_EOF = 0x100;// 无效接收字符
const DWORD DP_BLOCKED_SNDRCV_SLEEP = 100; // 100毫秒(发生阻塞时等待[睡眠]时间)
const int DP_SOCKET_MAJOR_VERSION = 2;
const int DP_SOCKET_MINOR_VERSION = 2;
const UINT ERR_CONNECT_BASE=200;
const UINT ERR_CONNECT_SUCCESS=ERR_CONNECT_BASE; //与对方服务器连接正常
const UINT ERR_CONNECT_PROXY=ERR_CONNECT_BASE+5;
const UINT ERR_CONNECT_HOST =ERR_CONNECT_BASE+6;
const UINT ERR_CONNECT_SYSTEM =ERR_CONNECT_BASE+7;
const UINT ERR_CONNECT_NOTSUSTAIN=ERR_CONNECT_BASE+8;
const UINT ERR_CONNECT_PROXYAUTH =ERR_CONNECT_BASE+9;
// 数据结构(缓冲区循环使用)
typedef struct _tagBUFSOCKETDATA
{
SOCKET hSocket; // SOCKET
int iBufferSize; // 数据缓冲大小
char* pszBuffer; // 数据缓冲
int iBytesInBuffer; // 缓冲区已有数据长度(字节)
int iReadIndex; // 可以读取的下一缓冲区位置
int iBufferIndex; // 可以使用的下一缓冲区位置
}TAG_BSD,*LPTAG_BSD;
class CDPSocketModel
{
public:
CDPSocketModel();
virtual ~CDPSocketModel();
private:
int m_nErrorNo;
CRITICAL_SECTION m_csErrorNo;
public:
void DPCleanupLibrary(void);
int DPInitLibrary(void);
protected:
int DPSetSocketOption(SOCKET hSocket);
int DPBlockSocket(SOCKET hSocket, BOOL bBlock);
//发送一次缓冲区数据,不过有可能没有全部发送
int DPSend_Event(SOCKET hSocket, char const * pszBuffer,
int nBufferSize, DWORD dwTimeout=DP_SEND_TIMEOUT);
int DPSendTo_Event(SOCKET hSocket, const struct sockaddr * pTo,
int nAddrLen,char const * pszBuffer, int nBufferSize,
DWORD dwTimeout=DP_SEND_TIMEOUT);
int DPSend_Block(SOCKET hSocket,char const * pszBuffer,
int nBufferSize, DWORD dwTimeout=DP_SEND_TIMEOUT);
int DPSendTo_Block(SOCKET hSocket, const struct sockaddr * pTo,
int nAddrLen,char const * pszBuffer, int nBufferSize,
DWORD dwTimeout=DP_SEND_TIMEOUT);
//异步
int DPRecvLL(SOCKET hSocket, char *pszBuffer, int nBufferSize);
int DPSendLL(SOCKET hSocket, char const * pszBuffer, int nBufferSize);
inline int DPGetLastError()//获取最近一次操作的错误代码
{return (m_nErrorNo);};
int DPBindSocket(SOCKET hSocket, struct sockaddr * pSocketAddress,
int nAddrLen);
int DPBindSocketEx(SOCKET hSocket,int nPort);
int DPListenSocket(SOCKET hSocket, int nConnections);
SOCKET DPCreateSocket(int nAddressFamily= AF_INET,
int nType=SOCK_STREAM,int nProtocol= 0);
void DPCloseSocket(SOCKET hSocket, BOOL bHardClose=FALSE);
DWORD DPGetIP(const char* name,BOOL bFixNtDNS= FALSE);
//(阻塞模型)
SOCKET DPAccept_Block(SOCKET hSocket, struct sockaddr * pSocketAddress,
int *nAddrLen);
int DPConnect_Block(SOCKET hSocket, const struct sockaddr * pSocketAddress,
int nAddrLen);
//发送全部缓冲区数据,直到超时或发送完毕
int DPSendData_Block(SOCKET hSocket,char const * pszBuffer,
int nBufferSize, DWORD dwTimeout=DP_SEND_TIMEOUT);
//阻塞接收数据,该函数停止是在该端口被关闭(接收长度为0),或出错误的时候
int DPRecvData_Block(SOCKET hSocket, char *pszBuffer, int nBufferSize,
DWORD dwTimeout= DP_RECV_TIMEOUT);
int DPRecvDataFrom_Block( SOCKET hSocket, struct sockaddr * pFrom,
int nAddrlen,char *pszBuffer, int nBufferSize,
DWORD dwTimeout=DP_RECV_TIMEOUT);
//(事件模型)一个线程等待一个事件
SOCKET DPAccept_Event(SOCKET hSocket, struct sockaddr * pSocketAddress,
int *nAddrLen,DWORD dwTimeout=DP_DEFAULT_TIMEOUT);
SOCKET DPAcceptEx_Event(SOCKET hSocket, struct sockaddr * pSocketAddress,
int *nAddrLen,HANDLE hEndEvent,DWORD dwTimeout=DP_DEFAULT_TIMEOUT);
int DPConnectEx_Event(SOCKET hSocket, char const * pszServer, int nPort,
DWORD dwTimeout=DP_CONNECT_TIMEOUT,BOOL fFixNtDNS=FALSE);
int DPConnect_Event(SOCKET hSocket, const struct sockaddr * pSocketAddress,
int nAddrLen,DWORD dwTimeout=DP_CONNECT_TIMEOUT);
int DPRecvData_Event(SOCKET hSocket, char *pszBuffer,
int nBufferSize, DWORD dwTimeout= DP_RECV_TIMEOUT);
int DPRecvDataFrom_Event( SOCKET hSocket, struct sockaddr * pFrom,
int nAddrlen,char *pszBuffer, int nBufferSize,
DWORD dwTimeout=DP_RECV_TIMEOUT);
//发送所有数据或超时
int DPSendData_Event(SOCKET hSocket, char const * pszBuffer,
int nBufferSize, DWORD dwTimeout=DP_SEND_TIMEOUT);
inline void DPSetLastError(int iErrorCode)//设置错误代码
{
::EnterCriticalSection(&m_csErrorNo);
m_nErrorNo = iErrorCode;
::LeaveCriticalSection(&m_csErrorNo);
};
//缓冲区函数
public:
LPTAG_BSD DPBSocketAttach(SOCKET hSocket,
int iBufferSize= DP_SOCKET_BUFFER_SIZE);
SOCKET DPBSocketDetach(LPTAG_BSD pBSD, BOOL bCloseSocket= FALSE);
int DPBSocketReadData(LPTAG_BSD pBSD, DWORD dwTimeout= DP_RECV_TIMEOUT);
int DPBSocketGetChar(LPTAG_BSD pBSD, DWORD dwTimeout= DP_RECV_TIMEOUT);
int DPBSocketGetString(LPTAG_BSD pBSD, char *pszBuffer, int iBufferSize,
int* iStatus, DWORD dwTimeout= DP_RECV_TIMEOUT);
int DPBSocketGetStringEx(LPTAG_BSD pBSD, char *pszBuffer, int iBufferSize,
int* iStatus, DWORD dwTimeout= DP_RECV_TIMEOUT);
int DPBSocketSendString(LPTAG_BSD pBSD, const char *pszBuffer,
DWORD dwTimeout= DP_SEND_TIMEOUT);
SOCKET DPBSocketGetAttachedSocket(LPTAG_BSD pBSD);
int DPBSocketGetData(LPTAG_BSD pBSD, char *pszBuffer, int iBufferSize,
DWORD dwTimeout= DP_RECV_TIMEOUT);
static CString GetLocalHostIp(void);
};
#endif // !defined(AFX_DPEVENTSOCKET_H__8790D406_A2C2_4446_90B1_AC06156DDA73__INCLUDED_)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -