阻塞套接字封装类-头文件

// 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 //

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值