clientsocket 类

.h文件

#pragma once
#include "xsocket.h"
#define SOCKET_IO_FLAG 0
class CClientSocket :
 public CXSocket
{
public:
    SOCKADDR_IN m_stClientSockAddr;
    char m_szClientIP[IP_LEN];
    int m_iClientPort;
public:
 CClientSocket(void);
 virtual ~CClientSocket(void);
public:
    /*
    iSend 为每次发送字节数
    iTotal 为需要发送的字节数
    */
    int Send(char* pPack, int iSend, int iTotal, int iFlag = SOCKET_IO_FLAG);
    int Recv(char* pPack, int iRecv, int iTotal, int iFlag = SOCKET_IO_FLAG);
    int Connect(char* pRemoteIP, unsigned int iRemotePort, unsigned int iLocalPort = 0);
    char* GetClientSockAddrInfo();
    char* GetClientIP()
    {
        return GetClientSockAddrInfo();
    }
protected:
 /*
 iLen 为每次接受字节数
 */
 int Recv(char* pPack, int iLen, int iFlag = SOCKET_IO_FLAG);
 /*
    iLen 为每次发送字节数
 */
 int Send(char* pPack, int iLen, int iFlag = SOCKET_IO_FLAG);
 int Connect(const struct sockaddr_in* name, int namelen);
};

.CPP文件

#include "StdAfx.h"
#include "clientsocket.h"

CClientSocket::CClientSocket(void)
{
    memset(m_stClientSockAddr, 0, sizeof(SOCKADDR_IN));
    memset(m_szClientIP, 0, sizeof(m_szClientIP) - 1);
    m_iClientPort = 0;
}

CClientSocket::~CClientSocket(void)
{
}
int CClientSocket::Recv(char* sPack, int iLen, int iFlag)
{
    return ::recv(m_Socket, sPack, iLen, iFlag);
}
int CClientSocket::Recv(char* sPack, int iRecv, int iTotalLen, int iFlag)
{
    int err = 0;
    int iTotal = 0;//累计已经发送(接受)的数据
    int iLeave = iTotalLen; //剩余数据长度
    while(1)
    {
        if((err = SelectRecv()) < 0)
        {
            return FAIL;
        }
        else if (SEL_TIMEOUT == err)
        {  
            //超时
            return SEL_TIMEOUT;
        }
        if((err = Recv(sPack + iTotal, iRecv, iFlag)) <= 0)
        {
            break;
        }
            //累计"接收数据"
        iTotal += err;
        iLeave = iTotalLen - iTotal; //剩余数据长度 = 需要发送(接受)的数据 - 已经发送(接受)的数据
        if(iLeave < iRecv)
        {
            iRecv = iLeave; 
        }
        else if(iLeave <= 0)
        {
            //"累计已经发送(接受)的数据"大于"需要发送(接受)的数据",提示错误
            if(iTotal > iTotalLen)
            {
                Err("接受数据内存溢出:累计已经接受的数据大于需要接受的数据.");
            }
            break;
        }
    }
    //返回"累计已经接受的数据"
    return iTotal;
}
int CClientSocket::Send(char* sPack, int iLen, int iFlag)
{
    return ::send(m_Socket, sPack, iLen, iFlag);
}
int  CClientSocket::Send(char* sPack, int iSend, int iTotalLen, int iFlag)
{
    int err = 0;
    int iTotal = 0;//累计已经发送(接受)的数据
    int iLeave = iTotalLen; //剩余数据长度
    while(1)
    {
        if((err = SelectSend()) < 0)
        {
            return FAIL;
        }
        else if (SEL_TIMEOUT == err)
        {
            // 超时
            return SEL_TIMEOUT;
        } 
        if((err = Send(sPack + iTotal, iSend, iFlag)) <= 0)
        {
            break;
        }
            //累计"发送数据" 
        iTotal += err;
        iLeave = iTotalLen - iTotal; //剩余数据长度 = 需要发送(接受)的数据 - 已经发送(接受)的数据
        if(iLeave < iSend)
        {
            iSend = iLeave;
        }
        else if(iLeave <= 0)
        {
            //"累计已经发送(接受)的数据"大于"需要发送(接受)的数据",提示错误
            if(iTotal > iTotalLen)
            {
             Err("发送数据内存溢出:累计已经发送的数据大于需要发送的数据.");
            }
            break;
        }
    }
    //返回"累计已经发送的数据"
    return iTotal;
}

int CClientSocket::Connect(const struct sockaddr_in* internetRemoteAddr, int namelen)
{
    return SOCKET_ERROR == connect(m_Socket, (struct sockaddr*)internetRemoteAddr, namelen) ? FAIL : OK;
}

int CClientSocket::Connect(char* szRemoteIP, unsigned int iRemotePort, unsigned int iLocalPort)
{  
    if(iRemotePort <= 0)
    {
        return FAIL;
    }
    //创建SOCKET失败,返回
    if(FAIL == CreateSocket())
    {
        Err("CClientSocket::Connect-CreateSocket 失败[%d]", GetLastError());
        return FAIL;
    }
    SetNonBlock();
    SetReuseAddr();
    SetKeepAlive();
    //iret = SetLinger();
    if (iLocalPort > 0)
    {
        //char szLocalIP[IP_LEN+1] = {0};
        struct sockaddr_in stLocalSockAddr; 
        //InitSockAddr(stLocalSockAddr, GetLocalIP(szLocalIP),  iLocalPort);
        InitSockAddr(stLocalSockAddr, NULL,  iLocalPort);
        if (FAIL == Bind(stLocalSockAddr))
        {
            Err("CClientSocket::Connect-Bind 本地地址失败[%d]", GetLastError());
            return FAIL;
        }
    }
    struct sockaddr_in stInternetRemoteAddr; 
    InitSockAddr(stInternetRemoteAddr, szRemoteIP, iRemotePort);
    //说明:
    //如果 TCPGetLastErr () != WSAEWOULDBLOCK
    //那么是真的连接失败了。比如端口错误产生的10061就是真的连接有问题。
    //如果等于WSAEWOULDBLOCK,那么就要开始
    //连接等待了。
    //连接等待一定时间返回后有又如下几种
    //0,连接超时,决定是否需要在等待。
    //1,连接成功(即使当前SOCKET可度),
    //-1,select调用失败,具体分析要看失败的ERROR。
    if(SOCKET_ERROR == Connect(&stInternetRemoteAddr, (int)sizeof(stInternetRemoteAddr)))
    {
        Err("CClientSocket::Connect-Connect  失败[%d]", GetLastError());
        return FAIL;
    }
    return OK;
}

char* CClientSocket::GetClientSockAddrInfo()
{
    struct in_addr&  stIn_Addr = m_stClientSockAddr.sin_addr;
    char *pIP = inet_ntoa(stIn_Addr);
    m_iClientPort = htons(m_stClientSockAddr.sin_port);
    memset(m_szClientIP, 0, sizeof(m_szClientIP) - 1);
    strncpy(m_szClientIP, pIP, strlen(pIP));
    return m_szClientIP;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值