Socket 类

.h文件

 

#pragma once
#include "xobject.h"
#include "sockdef.h"
class CXSocket : public CXObject
{
public:
    SOCKET m_Socket;
    long m_iTimeOut;
private:
    void Init()
    {
        m_Socket = INVALID_SOCKET;
        m_iTimeOut = DEFAULT_TIMEOUT;
    }   
public:
    CXSocket(void);
    ~CXSocket(void);
public:
    char* GetLocalIP(char *szIP); 
    int CloseSocket(bool bForce);
public:
    bool operator != (CXSocket& sockfd)
    {
     return (sockfd.m_Socket != this->m_Socket);
    }
    bool operator == (CXSocket& sockfd)
    {
     return (sockfd.m_Socket == this->m_Socket); 
    }
public:
    int SetTimeOut(long sec)
    {
     m_iTimeOut = sec;
     return OK;
    }
    int SetNonBlock(unsigned long  iNonBlock = 1)
    { 
     unsigned long NonBlock = 1;
     return 0 > IOCtlSocket(FIONBIO, &NonBlock) ? FAIL : OK;
    }
    int SetLinger(u_short l_onoff = 1,  u_short l_linger = 0)
    {
     //设 SO_LINGER 设置为零(linger结构成员l_onoff不为0,但l-linger为0),
     //便不担心closesocket调用进入“锁定”状态(等待完成状态。),
     //即使队列中的数据尚未发送。或者尚未发出收到确认,也不担心。
     //“强行关闭”,因为SOCKET 虚拟通信回路会立即重设,
     //尚未发出的所有数据都会丢失。而远端,正在接受的调用都失败,同时返回
     //WSAECONNRESET错误。
     struct linger stSndOver;
     memset(&stSndOver, 0, sizeof(struct linger));
     stSndOver.l_onoff = l_onoff;
     stSndOver.l_linger = l_linger;
     int iLen = (int)sizeof(stSndOver);  
     return 0 > SetSockOpt(SOL_SOCKET, SO_LINGER, (char*)&stSndOver, iLen) ? FAIL : OK;
    }
    int SetReuseAddr(int iReuseAddr = 1)
    {
     return 0 > SetSockOpt(SOL_SOCKET, SO_REUSEADDR, (char*)&iReuseAddr, (int)sizeof(iReuseAddr)) ? FAIL : OK;
    }
    //SO_KEEPALIVE
    //程序请求基层服务提供者在TCP连接上使用“保持活动”的数据包。
    //假如由于“保持活动”造成连接的中断(很长时间没有发数据了。),
    //便会向SOCKET上正在进行的任何一个调用
    //返回一个WSAENETRESET错误代码。而后续的调用都会返回WSAENOTCONN错误。
    //发送时间间隔2小时。
    //2000 使用SIO_KEEPALIVE_VALS可以设置发送时间间隔。 
    int SetKeepAlive(int iAliveFlag = 1)
    {
     return 0 > SetSockOpt(SOL_SOCKET, SO_KEEPALIVE, (char*)&iAliveFlag, (int)sizeof(iAliveFlag)) ? FAIL : OK;
    }
    int SelectSend(long timeout);
    int SelectRecv(long timeout);
    int SelectExcept(long timeout);
protected:
    int GetSockOpt(int level, int optname, char *optval, int *optlen)
    {
        return getsockopt (m_Socket, level,optname, optval, optlen);
    }
    int SetSockOpt(int level, int optname, const char *optval, int len)
    {
        return setsockopt(m_Socket, level, optname, optval, len);
    }
    int GetLastError()
    {
        return ::WSAGetLastError();
    }
    /*
    返回
    <  0:调用失败
    == 0:超时
    */
    int Select(fd_set* readset, fd_set* writeset, fd_set* exceptset, long timeout)
    {
        timeout = timeout <= 0 ? m_iTimeOut : timeout;
        struct timeval stTimeOut;
        stTimeOut.tv_sec = timeout;
        stTimeOut.tv_usec = 0;
        return select(m_Socket, readset, writeset, exceptset, &stTimeOut);
    }
    int IOCtlSocket(long cmd, u_long *argp)
    {
        return ioctlsocket(m_Socket, cmd, argp)
    }
    int CreateSocket();
    bool IsVaildSocket();
protected: 
 void InitSockAddr(struct sockaddr_in &internetAddr, const char* szIP, unsigned int iport);
 int Bind(sockaddr_in &sockAddr_in);
};

.cpp文件:

#include "StdAfx.h"
#include "XSocket.h"

CXSocket::CXSocket(void)
{
    Init();
}

CXSocket::~CXSocket(void)
{
    CloseSocket();
}
int CXSocket::CloseSocket(bool bForce)

    if (!IsVaildSocket())
    {
     return SEL_FAIL;
    }
    if(bForce)
    { 
     //强行关闭[主机强迫关闭],WSAECONNRESET
     SetLinger();
    }
    closesocket(m_Socket);
    m_Socket = INVALID_SOCKET;
    return OK;
}
char* CXSocket::GetLocalIP(char *szIP)
{
    char szhostname[512+1] = {0};
    char *pIP = NULL;
    hostent* phostent;
    ::gethostname(szhostname, sizeof(szhostname) - 1);
    phostent = gethostbyname(szhostname);
    if (NULL != phostent->h_addr_list)
    {
     in_addr addr;
     memset((void*)&addr, 0, sizeof(in_addr));
     memcpy((void*)&addr, phostent->h_addr_list[0], 4);
     pIP = inet_ntoa(addr);
     strncpy(szIP, pIP, strlen(pIP));
    }
    return szIP;
}

int CXSocket::SelectRecv(long timeout)
{
    if (!IsVaildSocket())
    {
     return SEL_FAIL;
    }
    fd_set freadset;
    memset(&freadset, 0, sizeof(struct fd_set));
    FD_CLR(m_Socket, &freadset);
    FD_SET(m_Socket, &freadset);
    return Select(&freadset, NULL, NULL, timeout);
}

int CXSocket::SelectSend(long timeout)
{
    if (!IsVaildSocket())
    {
     return SEL_FAIL;
    }
    fd_set writeset;
    memset(&writeset, 0, sizeof(struct fd_set));
    FD_CLR(m_Socket, &writeset);
    FD_SET(m_Socket, &writeset);
    return Select(NULL, &writeset, NULL, timeout);
}

int CXSocket::SelectExcept(long timeout)
{
    if (!IsVaildSocket())
    {
     return SEL_FAIL;
    }
    fd_set except;
    memset(&except, 0, sizeof(struct fd_set));
    FD_CLR(m_Socket, &except);
    FD_SET(m_Socket, &except);
    return Select(NULL, NULL, &except, timeout);
}
int CXSocket::CreateSocket()
{
    m_Socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (!IsVaildSocket())
    {
     return FAIL;
    }
    return OK;
}
bool CXSocket::IsVaildSocket()
{
 return (m_Socket != INVALID_SOCKET);
}
void CXSocket::InitSockAddr(struct sockaddr_in &stInternetAddr, const char* szIP, unsigned int iPort)
{
    memset(&stInternetAddr, 0, sizeof(stInternetAddr));
    stInternetAddr.sin_family = AF_INET;
    if(NULL == szIP || "/0" == szIP[0])
    {
     stInternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    }
    else
    {
     stInternetAddr.sin_addr.s_addr = (unsigned int)inet_addr(szIP);
    }
    stInternetAddr.sin_port = htons(iPort);
}
int CXSocket::Bind(struct sockaddr_in &stSockAddr_in)
{
    return bind(m_Socket, (const struct sockaddr)&stSockAddr_in, sizeof(stSockAddr_in));
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值