// #include <standard library headers>
#include <iostream>
// #include <other library headers>
#include <errno.h>
#include <fcntl.h>
// #include "customer headers"
#include "Socket.h"
namespace sock
{
// statics
#ifdef _WIN32
WSAInitial Socket::sWinsockInit;
#endif
// ctor && dtor
Socket::Socket()
: mSock(INVALID_SOCKET)
{
memset(&mAddr, 0, sizeof(mAddr));
}
Socket::~Socket()
{
if (IsValid())
{
::shutdown(mSock, SD_BOTH);
#ifdef WIN32
::closesocket(mSock);
#else
::close (mSock);
#endif
}
}
bool Socket::Create()
{
mSock = socket(AF_INET, SOCK_STREAM, 0);
if (!IsValid())
{
return false;
}
// TIME_WAIT - argh
int on = 1;
int ret = setsockopt(mSock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
return (ret != SOCKET_ERROR);
}
bool Socket::Bind(const int port)
{
if (!IsValid())
{
return false;
}
mAddr.sin_family = AF_INET;
mAddr.sin_addr.s_addr = INADDR_ANY;
mAddr.sin_port = htons ( port );
int ret = ::bind(mSock,
(struct sockaddr*)&mAddr,
sizeof(mAddr));
return (ret != SOCKET_ERROR);
}
bool Socket::Listen() const
{
if (!IsValid())
{
return false;
}
int ret = ::listen(mSock, SOMAXCONN);
return (ret != SOCKET_ERROR);
}
bool Socket::Accept(Socket& newSocket, int sec, int usec) const
{
int select = Select(true, sec, usec);
if (select <= 0)
{
return false;
}
int addr_length = sizeof(sockaddr_in);
newSocket.mSock = ::accept(mSock, (sockaddr*)&newSocket.mAddr, (socklen_t*)&addr_length);
#ifdef WIN32
return (newSocket.mSock != INVALID_SOCKET);
#else
return (newSocket.mSock > 0);
#endif
}
bool Socket::Send(const std::string s, int sec, int usec) const
{
return Send(s.c_str(), static_cast<int>(s.size()), sec, usec);
}
bool Socket::Send(const char* buf, int len, int sec, int usec) const
{
if (buf == NULL)
{
return false;
}
int select = Select(false, sec, usec);
if (select <= 0)
{
return false;
}
int totalSendLen = 0;
while (totalSendLen < len)
{
int leaveLen = len - totalSendLen;
int s = (leaveLen < MAXSEND) ? leaveLen : MAXSEND;
int sendLen = ::send(mSock, &buf[totalSendLen], s, 0);
if (sendLen == SOCKET_ERROR)
{
#ifdef _DEBUG
GetLastError();
#endif
return false;
}
std::cout << sendLen << std::endl;
totalSendLen += sendLen;
std::cout << totalSendLen << std::endl;
//int sel = Select(false, sec, usec);
//if (sel <= 0)
//{
// return false;
//}
}
return (totalSendLen == len);
}
int Socket::Recv(std::string& s, int sec, int usec) const
{
char buf[MAXRECV + 1];
s = "";
memset(buf, 0, MAXRECV + 1);
int status = Recv(buf, MAXRECV, sec, usec);
if (status > 0)
{
s += buf;
}
else
{
return status;
}
return static_cast<int>(s.size());
}
int Socket::Recv(char* buf, int len, int sec, int usec) const
{
if (buf == NULL)
{
return -1;
}
int select = Select(true, sec, usec);
#ifdef _DEBUG
if (select == SOCKET_ERROR)
{
GetLastError();
}
#endif
if (select <= 0)
{
return select;
}
memset(buf, 0, len);
int status = ::recv(mSock, buf, len, 0);
#ifdef _DEBUG
if (status == SOCKET_ERROR)
{
GetLastError();
}
#endif
return status;
}
bool Socket::Connect(const std::string host, const int port)
{
if (!IsValid())
{
return false;
}
mAddr.sin_family = AF_INET;
mAddr.sin_port = htons(port);
#ifdef WIN32
mAddr.sin_addr.s_addr = inet_addr(host.c_str());
if (mAddr.sin_addr.s_addr == INADDR_NONE)
{
return false;
}
#else
int changestatus = inet_pton(AF_INET, host.c_str(), &mAddr.sin_addr);
if (changestatus < 0 && errno == EAFNOSUPPORT)
{
return false;
}
#endif
int status = ::connect(mSock, (sockaddr*)&mAddr, sizeof(mAddr));
#ifdef _DEBUG
if (status == SOCKET_ERROR)
{
GetLastError();
}
#endif
/*
if (status != SOCKET_ERROR)
{
linger m_sLinger;
m_sLinger.l_onoff = 1;
m_sLinger.l_linger = 0;
status = ::setsockopt(mSock, SOL_SOCKET, SO_LINGER,
(const char*)&m_sLinger, sizeof(linger));
}
//*/
return (status != SOCKET_ERROR);
}
void Socket::SetNonBlocking(const bool b)
{
#ifdef _WIN32
u_long opts = b ? 1 : 0;
ioctlsocket(mSock, FIONBIO, &opts);
#else
int opts = fcntl(mSock, F_GETFL);
if (opts < 0)
{
return;
}
opts = b ? (opts | O_NONBLOCK) : (opts & ~O_NONBLOCK);
fcntl(mSock, F_SETFL,opts);
#endif
}
bool Socket::IsValid() const
{
return (mSock != INVALID_SOCKET);
}
// protected
int Socket::Select(bool read, long sec, long usec) const
{
timeval timeout;
timeout.tv_sec = sec;
timeout.tv_usec = usec;
timeval* tv = ((sec < 0) || (usec < 0)) ? NULL : &timeout;
fd_set fds;
FD_ZERO(&fds);
FD_SET(mSock, &fds);
int error = 0;
if (read)
{
error = ::select(1, &fds, 0, 0, tv);
}
else
{
error = ::select(1, 0, &fds, 0, tv);
}
#ifdef _DEBUG
if (error == SOCKET_ERROR)
{
GetLastError();
}
#endif
return error;
}
void Socket::GetLastError()
{
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable : 4996)
int err = ::WSAGetLastError();
TCHAR buf[10];
swprintf(buf, L"%d: ", err);
::OutputDebugString(buf);
#pragma warning(pop)
#endif
}
}
Socket封装4
最新推荐文章于 2022-09-19 17:42:44 发布