TcpClient.h
#ifndef __TCPSERVER_H__
#define __TCPSERVER_H__
namespace LinWin
{
class CSocketImpl;
class CSocketAddress;
class CTcpClient
{
private:
int m_SndTimeOut;
int m_RcvTimeOut;
CSocketImpl* m_sock;
public:
CTcpClient();
CTcpClient(CSocketImpl* sock);
~CTcpClient();
int Create(bool bAccept = false);
void Close();
int Connect(const CSocketAddress& addr);
int SetSendTimeOut(int timeout);
int SetRecvTimeOut(int timeout);
int SetSendBufferSize(int size);
int SetRecvBufferSize(int size);
int Send(const void* lpBuf, unsigned int len);
int Recv(void*lpBuf, unsigned int len);
int Sendn(const void* lpBuf, unsigned int len);
int Recvn(void*lpBuf, unsigned int len);
int ReadLine(void*lpBuf, unsigned int len);
net_socket_fd Sockfd() const;
CSocketImpl* Handle();
private:
int RealSend(const void*lpBuf, unsigned int len);
int RealRecv(void* lpBuf, unsigned int len);
};
}
#endif
TcpClient.cpp类
#include "Platform.h"
#include "SocketImpl.h"
#include "TcpClient.h"
//
LinWin::CTcpClient::CTcpClient() : m_SndTimeOut(NET_INFINITE), m_RcvTimeOut(NET_INFINITE), m_sock(NULL)
{
}
LinWin::CTcpClient::CTcpClient(CSocketImpl* sock) : m_SndTimeOut(NET_INFINITE), m_RcvTimeOut(NET_INFINITE), m_sock(sock)
{
}
LinWin::CTcpClient::~CTcpClient()
{
Close();
}
int LinWin::CTcpClient::Create(bool bAccept/* = false */)
{
if (!m_sock)
{
m_sock = new CSocketImpl;
if (!m_sock)
return -1;
if (!bAccept)
return m_sock->Create();
}
return 0;
}
void LinWin::CTcpClient::Close()
{
if (m_sock)
{
m_sock->Close();
delete m_sock;
m_sock = NULL;
}
}
int LinWin::CTcpClient::Connect(const CSocketAddress& addr)
{
if (Create() != 0)
return -1;
return m_sock->Connect(addr);
}
int LinWin::CTcpClient::SetSendTimeOut(int timeout)
{
if (Create() != 0)
return -1;
if (timeout < 0)
timeout = NET_INFINITE;
m_SndTimeOut = timeout;
#ifdef WINDOWS_FAMILY
return m_sock->SetRawOption(SOL_SOCKET, SO_SNDTIMEO, &m_SndTimeOut, sizeof(m_SndTimeOut));
#else
struct timeval tv;
tv.tv_sec = m_SndTimeOut / 1000;
tv.tv_usec = m_SndTimeOut % 1000 * 1000;
return m_sock->SetRawOption(SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval));
#endif
}
int LinWin::CTcpClient::SetRecvTimeOut(int timeout)
{
if (Create() != 0)
return -1;
if (timeout < 0)
timeout = NET_INFINITE;
m_RcvTimeOut = timeout;
#ifdef WINDOWS_FAMILY
return m_sock->SetRawOption(SOL_SOCKET, SO_RCVTIMEO, &m_RcvTimeOut, sizeof(m_RcvTimeOut));
#else
struct timeval tv;
tv.tv_sec = m_SndTimeOut / 1000;
tv.tv_usec = m_SndTimeOut % 1000 * 1000;
return m_sock->SetRawOption(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
#endif
}
int LinWin::CTcpClient::SetSendBufferSize(int size)
{
if (Create() != 0)
return -1;
return m_sock->SetOption(SOL_SOCKET, SO_SNDBUF, size);
}
int LinWin::CTcpClient::SetRecvBufferSize(int size)
{
if (Create() != 0)
return -1;
return m_sock->SetOption(SOL_SOCKET, SO_RCVBUF, size);
}
int LinWin::CTcpClient::Send(const void* lpBuf, unsigned int len)
{
return RealSend(lpBuf, len);
}
int LinWin::CTcpClient::Recv(void* lpBuf, unsigned int len)
{
return RealRecv(lpBuf, len);
}
int LinWin::CTcpClient::Sendn(const void* lpBuf, unsigned int len)
{
unsigned int offset = 0;
const char* ptr = reinterpret_cast<const char*>(lpBuf);
int ret = NET_NO_ERROR;
do
{
ret = RealSend(ptr, len - offset);
if (ret != NET_SOCKET_ERROR)
{
offset += ret;
ptr += ret;
}
else break;
} while (offset < len);
return ret;
}
int LinWin::CTcpClient::Recvn(void* lpBuf, unsigned int len)
{
unsigned int offset = 0;
char* ptr = reinterpret_cast<char*>(lpBuf);
int ret = NET_NO_ERROR;
do
{
ret = RealRecv(ptr, len - offset);
if (ret != NET_SOCKET_ERROR)
{
if (ret == 0)
break;
offset += ret;
ptr += ret;
}
else break;
} while (offset < len);
return ret;
}
int LinWin::CTcpClient::ReadLine(void*lpBuf, unsigned int len)
{
memset(lpBuf, 0, len);
char* ptr = reinterpret_cast<char*>(lpBuf);
unsigned int offset = 0;
int ret = NET_NO_ERROR;
do
{
ret = RealRecv(ptr, 1);
if (ret != 1)
break;
char ch = *ptr;
if (ch == '\n')
break;
offset++;
ptr++;
} while (offset < len);
if (offset == len)
ret = -1;
return offset;
}
int LinWin::CTcpClient::RealSend(const void*lpBuf, unsigned int lpLen)
{
return m_sock->SendBytes(lpBuf, lpLen, 0);
}
int LinWin::CTcpClient::RealRecv(void* lpBuf, unsigned int lpLen)
{
return m_sock->RecvBytes(lpBuf, lpLen);
}
net_socket_fd LinWin::CTcpClient::Sockfd() const
{
return m_sock->Sockfd();
}
LinWin::CSocketImpl* LinWin::CTcpClient::Handle()
{
return m_sock;
}
设置发送超时和接收超时,Windows下单位是毫秒ms,Linux下是秒s。此实现,统一为毫秒单位。
2016/12/12修改ReadLine的返回值为offset。