#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;
}