使用socket封装的同步连接TCP类

#pragma once

#define IP_BUFFSIZE_DEFAULT 4096

class CJGIPClient
{
public:
CJGIPClient(void);
~CJGIPClient(void);

private:
SOCKET m_socketClient;
BOOL m_bConnect;
int m_nSendTimeOut;
int m_nRecvTimeOut;
timeval m_tvSelect;

BOOL m_bWSAStart;

public:
int SetTimeOut(int nSendTimeOut, int nRecvTimeOut, int nSelectTimeOut);
int WSAStart();
int WSAClean();
int ConnectServer(char *pIPAddr, int nPort);
int DisConnectServer();
int SendData(char *pData, int nSendSize);
int RecvData(char *pData, int nRecvSize);

};

#include "StdAfx.h"
#include "JGIPClient.h"


CJGIPClient::CJGIPClient(void)
{
m_socketClient = INVALID_SOCKET;
m_bConnect = FALSE;
m_nSendTimeOut = 0;
m_nRecvTimeOut = 0;
ZeroMemory(&m_tvSelect, sizeof(m_tvSelect));

m_bWSAStart = FALSE;
}


CJGIPClient::~CJGIPClient(void)
{
DisConnectServer();
}

int CJGIPClient::SetTimeOut(int nSendTimeOut, int nRecvTimeOut, int nSelectTimeOut)
{
if(nSendTimeOut >= 0) m_nSendTimeOut = nSendTimeOut*1000;
if(nRecvTimeOut >= 0) m_nRecvTimeOut = nRecvTimeOut*1000;
if(nSelectTimeOut >= 0) m_tvSelect.tv_sec = nSelectTimeOut;

return 0;
}

int CJGIPClient::WSAStart()
{
if(m_bWSAStart == TRUE)
return 0;

WSADATA wsaData;
WORD wVersion = MAKEWORD(2, 2); //希望使用的WinSock DLL的版本
if(WSAStartup(wVersion, &wsaData) != 0)
{
//printf("WSAStartup() failed!\n");
return -1;
}
//确认WinSock DLL支持版本2.2
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
WSACleanup();
//printf("Invalid WinSock version!\n");
return -2;
}

m_bWSAStart = TRUE;

return 0;
}

int CJGIPClient::WSAClean()
{
if(m_bWSAStart == TRUE)
{
WSACleanup();
m_bWSAStart = FALSE;
}

return 0;
}

int CJGIPClient::ConnectServer(char *pIPAddr, int nPort)
{
if(m_bConnect == TRUE)
{
DisConnectServer();
}

if(WSAStart() != 0)
return -1;

m_socketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if(m_socketClient == INVALID_SOCKET)
{
WSAClean();
return -2;
}

struct sockaddr_in saServer;
saServer.sin_family = AF_INET;
saServer.sin_port = htons(nPort);
saServer.sin_addr.s_addr = inet_addr(pIPAddr);

if(saServer.sin_addr.s_addr == INADDR_NONE)
{
struct hostent *pHost = gethostbyname(pIPAddr);
if(pHost == NULL)
{
return -3;
}
memcpy(&saServer.sin_addr, pHost->h_addr_list[0], pHost->h_length);
}

linger sLinger;
sLinger.l_onoff = 0;
sLinger.l_linger = 0;
int nReUse = 1;
int nNoDelay = 1;

setsockopt(m_socketClient, SOL_SOCKET, SO_LINGER, (const char*)&sLinger, sizeof(sLinger));
setsockopt(m_socketClient, SOL_SOCKET, SO_REUSEADDR, (const char*)&nReUse, sizeof(nReUse));
setsockopt(m_socketClient, IPPROTO_TCP, TCP_NODELAY, (const char *)&nNoDelay, sizeof(nNoDelay));
if(m_nSendTimeOut > 0)
{
setsockopt(m_socketClient, SOL_SOCKET, SO_SNDTIMEO, (const char*)&m_nSendTimeOut, sizeof(m_nSendTimeOut));
}
if(m_nRecvTimeOut > 0)
{
setsockopt(m_socketClient, SOL_SOCKET, SO_RCVTIMEO, (const char*)&m_nRecvTimeOut, sizeof(m_nRecvTimeOut));
}

if(connect(m_socketClient, (struct sockaddr *)&saServer, sizeof(saServer)) == SOCKET_ERROR)
{
closesocket(m_socketClient); //关闭套接字
m_socketClient = INVALID_SOCKET;
WSAClean();
return -4;
}

m_bConnect = TRUE;

return 0;
}

int CJGIPClient::DisConnectServer()
{
if(m_socketClient != INVALID_SOCKET)
{
closesocket(m_socketClient);
m_socketClient = INVALID_SOCKET;
}

WSAClean();

m_bConnect = FALSE;

return 0;
}

int CJGIPClient::SendData(char *pData, int nSendSize)
{
if(m_socketClient == INVALID_SOCKET || m_bConnect == FALSE)
return -1;

if(pData == NULL || nSendSize <= 0)
return -2;

int nRealSendSize = 0;
int nRet = 0;
for(nRealSendSize = 0;nRealSendSize < nSendSize;nRealSendSize += nRet)
{
nRet = send(m_socketClient, &pData[nRealSendSize], nSendSize-nRealSendSize, 0);
if(nRet == 0) return -3;
else if(nRet == INVALID_SOCKET) return -4;
else if(nRet < 0) return -5;
}

return nRealSendSize;
}

int CJGIPClient::RecvData(char *pData, int nRecvSize)
{
if(m_socketClient == INVALID_SOCKET || m_bConnect == FALSE)
return -1;

if(pData == NULL)
return -2;

int nRealRecvSize = 0;
int nRet = 0;
int nError = 0;
if(nRecvSize == -1)
{
nRet = recv(m_socketClient, pData, IP_BUFFSIZE_DEFAULT, 0);
if(nRet == 0) return -3;
else if(nRet == INVALID_SOCKET) return -4;
else if(nRet < 0) return -5;

nRealRecvSize = nRet;
}
else
{
for(nRealRecvSize = 0;nRealRecvSize < nRecvSize;nRealRecvSize += nRet)
{
nRet = recv(m_socketClient, &pData[nRealRecvSize], nRecvSize-nRealRecvSize, 0);
if(nRet == 0) return -3;
else if(nRet == INVALID_SOCKET) return -4;
else if(nRet < 0) return -5;
}
}

return nRealRecvSize;
}


 
//linux 下接收socket数据
readn(SOCKET fd, char *bp, size_t len)
{
   int cnt;
   int rc;

   cnt = len;
   while( cnt > 0)
   {
       rc = recv(fd, bp, cnt , 0);
       if (rc < 0)
       {
           if (errno == EINTR)
               continue;
           return -1;
       }

       if (rc == 0)
           return len - cnt;
       bp += rc;
       cnt -= rc;
   }

   return len;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值