// MySocket.h: 套接字封装,网络数据发送、接收 // 包 名: 套接字类 // 依 赖 组 件: ws2_32.lib,winsock2.h // // ------------------------------------ // * 类 名:CSockAddr // * 包 名:网络套接字 // * 功 能:封装套接字地址 // * 作 者:fusx // * 依赖组件: winsock.h // * 开发日期:2003/06/11 //* 修改日期:2004/06/06 // * 项目名称: // * 版 权: // ------------------------------------ //目的:封装套接字,可以用来向网络发送、接收数据。阻塞调用函数。 //说明:本类从《VC++6.0技术内幕》中摘录并修改
#if !defined(MY_SOCKET_H) #define MY_SOCKET_H
#include <winsock2.h> #pragma comment(lib, "ws2_32.lib")
class CSockAddr : public sockaddr_in { public: //构造函数 CSockAddr() { sin_family = AF_INET; sin_port = 0; sin_addr.s_addr = 0; } // Default CSockAddr(const SOCKADDR& sa) { memcpy(this, &sa, sizeof(SOCKADDR)); } CSockAddr(const SOCKADDR_IN& sin) { memcpy(this, &sin, sizeof(SOCKADDR_IN)); } //ulAddr为INADDR_ANY时默认为本机任一IP CSockAddr(const ULONG ulAddr, const USHORT ushPort = 0) // parms are host byte ordered { sin_family = AF_INET; sin_port = htons(ushPort); sin_addr.s_addr = htonl(ulAddr); } CSockAddr(const char* pchIP, const USHORT ushPort = 0) // dotted IP addr string { sin_family = AF_INET; sin_port = htons(ushPort); sin_addr.s_addr = inet_addr(pchIP); } // already network byte ordered //以点的格式返回地址 LPCTSTR GetIPDottedDecimal(LPTSTR strIP = NULL,int nLen = 16) { if ( strIP != NULL) memcpy(strIP,inet_ntoa(sin_addr),nLen); return inet_ntoa(sin_addr); } //获取端口及地址(主机顺序) USHORT Port() const { return ntohs(sin_port); } //获取IP地址(主机顺序) ULONG IPAddr() const { return ntohl(sin_addr.s_addr); } //转换及赋值 const CSockAddr& operator=(const SOCKADDR& sa) { memcpy(this, &sa, sizeof(SOCKADDR)); return *this; } const CSockAddr& operator=(const SOCKADDR_IN& sin) { memcpy(this, &sin, sizeof(SOCKADDR_IN)); return *this; } operator SOCKADDR() { return *((LPSOCKADDR) this); } operator LPSOCKADDR() { return (LPSOCKADDR) this; } operator LPSOCKADDR_IN() { return (LPSOCKADDR_IN) this; } };
// // ------------------------------------ // * 类 名:CMySocket // * 包 名:网络套接字 // * 功 能:封装网络套接字 // * 作 者:fusx // * 依赖组件:wsock32.lib // * 开发日期:2003/06/11 // * 修改日期:2004/06/06 // * 版 权:sishine // ------------------------------------ //目的: // 封装套接字,可以用来向网络发送、接收数据。阻塞调用函数。 //说明:本类从《VC++6.0技术内幕》中摘录并修改 // //////////////////////////////////////////////////////////////////////
typedef const struct sockaddr* LPCSOCKADDR;
class AFX_EXT_CLASS CMySocket { public: CMySocket(); virtual ~CMySocket();
//参数说明: //返回值:成功返回true,失败返回false //char *pch为待发送或接收数据的首地址,nSize为数据大小(字节) //int& nErrCode 为返回false时的错误代码.返回true时nErrCode无效 //LPCSOCKADDR psa为套接字地址 //int nSecs为超时设置时间,单位为秒,nMillSecs单位为微秒,当两者为0时为不考虑超时,即阻塞调用
//如果自己关闭了套接字,则返回false,nErrcode=WSAENOTSOCK //如果超时时返回false,nErrCode = WSAETIMEDOUT; //接收数据时,如果对方关闭连接,则返回true,且nBytesReceived = 0 public: void operator=(SOCKET sck);
//创建套接字,成功返回真,否则假,默认创建类型为SOCK_STREAM bool Create(int nType=SOCK_STREAM/* SOCK_STREAM or SOCK_DGRAM*/); //绑定地址 bool Bind(LPCSOCKADDR psa); bool Bind(LPCTSTR strIP, int nPort);
//侦听(服务器端用) bool Listen();
//连接服务器地址 bool Connect(LPCSOCKADDR psa); bool Connect(LPCTSTR strIP, int nPort); //默认为阻塞操作,接受客户端连接(服务器端用),新套接字为s,客户端地址在psa中 //侦听被取消时,返回false,但nErrCode=WSAEINTR,超时时返回false,nErrCode = 0; bool Accept(CMySocket& s, LPSOCKADDR psa,int nSecs=0); //发送数据,nBytesSent为实际发送出去的字节数 bool Send(const char* pch, const int nSize, int& nBytesSent,int nSecs = 0);
//发送全部数据,直到所有的数据发送完毕或者出错、超时才返回 bool Write(const char* pch, const int nSize,int nSecs = 0); //如果对方套接字被关闭,则返回true,且nBytesReceived为0字符,其余错误见上面描述 bool Receive(char* pch, const int nSize,int& nBytesReceived,int nSecs = 0);
//发送数据报,实际发送出去的数据大小为nBytesSent bool SendDatagram( LPCSOCKADDR psa,const char* pch, const int nSize, int& nBytesSent, int nSecs = 0);
//接收数据报,实际接收到的数据大小为nBytesReceived bool ReceiveDatagram( LPSOCKADDR psa, char* pch, const int nSize, int& nBytesReceived, int nSecs = 0);
//获取对方的套接字地址 bool GetPeerAddr(LPSOCKADDR psa);
//获取本地的套接字地址 bool GetSockAddr(LPSOCKADDR psa);
//根据名字获取主机地址,失败返回地址为0 static CSockAddr GetHostByName(const char* pchName, const USHORT ushPort = 0);
//根据地址获取主机名,调用者需要删除char*内存;失败返回NULL。 static const char* GetHostByAddr(LPCSOCKADDR psa);
//获取本地计算机的IP及主机名 static bool GetLocalHostInfo(LPTSTR strHostName,LPTSTR strHostIP);
//关闭套接字,并可能返回错误 bool Close();
//本套接字可以与SOCKET通用 operator SOCKET() { return m_hSocket; }
private: SOCKET m_hSocket; int m_nErrCode; public: //根据错误代码获取错误字符串 bool GetErrorMessage(const int nErrCode, char *pErrMsg,int nMaxLen); inline int GetErrorCode(){return m_nErrCode;}; // 判断是否有效(非空) inline bool IsValid(void){return m_hSocket!=INVALID_SOCKET;};
};
#endif //

|