📄 tcpsocket.cpp.svn-base
字号:
size_t TcpSocket::GetOutputLength()
{
return m_output_length;
}
uint64_t TcpSocket::GetBytesReceived(bool clear)
{
uint64_t z = m_bytes_received;
if (clear)
m_bytes_received = 0;
return z;
}
uint64_t TcpSocket::GetBytesSent(bool clear)
{
uint64_t z = m_bytes_sent;
if (clear)
m_bytes_sent = 0;
return z;
}
#ifdef ENABLE_RECONNECT
bool TcpSocket::Reconnect()
{
return m_b_reconnect;
}
void TcpSocket::SetIsReconnect(bool x)
{
m_b_is_reconnect = x;
}
bool TcpSocket::IsReconnect()
{
return m_b_is_reconnect;
}
#endif
#ifdef HAVE_OPENSSL
const std::string& TcpSocket::GetPassword()
{
return m_password;
}
#endif
void TcpSocket::DisableInputBuffer(bool x)
{
m_b_input_buffer_disabled = x;
}
void TcpSocket::OnOptions(int family,int type,int protocol,SOCKET s)
{
DEB( fprintf(stderr, "Socket::OnOptions()\n");)
#ifdef SO_NOSIGPIPE
SetSoNosigpipe(true);
#endif
SetSoReuseaddr(true);
SetSoKeepalive(true);
}
void TcpSocket::SetLineProtocol(bool x)
{
StreamSocket::SetLineProtocol(x);
DisableInputBuffer(x);
}
bool TcpSocket::SetTcpNodelay(bool x)
{
#ifdef TCP_NODELAY
int optval = x ? 1 : 0;
if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1)
{
Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
return false;
}
return true;
#else
Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO);
return false;
#endif
}
TcpSocket::CircularBuffer::CircularBuffer(size_t size)
:buf(new char[2 * size])
,m_max(size)
,m_q(0)
,m_b(0)
,m_t(0)
,m_count(0)
{
}
TcpSocket::CircularBuffer::~CircularBuffer()
{
delete[] buf;
}
bool TcpSocket::CircularBuffer::Write(const char *s,size_t l)
{
if (m_q + l > m_max)
{
return false; // overflow
}
m_count += (unsigned long)l;
if (m_t + l > m_max) // block crosses circular border
{
size_t l1 = m_max - m_t; // size left until circular border crossing
// always copy full block to buffer(buf) + top pointer(m_t)
// because we have doubled the buffer size for performance reasons
memcpy(buf + m_t, s, l);
memcpy(buf, s + l1, l - l1);
m_t = l - l1;
m_q += l;
}
else
{
memcpy(buf + m_t, s, l);
memcpy(buf + m_max + m_t, s, l);
m_t += l;
if (m_t >= m_max)
m_t -= m_max;
m_q += l;
}
return true;
}
bool TcpSocket::CircularBuffer::Read(char *s,size_t l)
{
if (l > m_q)
{
return false; // not enough chars
}
if (m_b + l > m_max) // block crosses circular border
{
size_t l1 = m_max - m_b;
if (s)
{
memcpy(s, buf + m_b, l1);
memcpy(s + l1, buf, l - l1);
}
m_b = l - l1;
m_q -= l;
}
else
{
if (s)
{
memcpy(s, buf + m_b, l);
}
m_b += l;
if (m_b >= m_max)
m_b -= m_max;
m_q -= l;
}
if (!m_q)
{
m_b = m_t = 0;
}
return true;
}
bool TcpSocket::CircularBuffer::SoftRead(char *s, size_t l)
{
if (l > m_q)
{
return false;
}
if (m_b + l > m_max) // block crosses circular border
{
size_t l1 = m_max - m_b;
if (s)
{
memcpy(s, buf + m_b, l1);
memcpy(s + l1, buf, l - l1);
}
}
else
{
if (s)
{
memcpy(s, buf + m_b, l);
}
}
return true;
}
bool TcpSocket::CircularBuffer::Remove(size_t l)
{
return Read(NULL, l);
}
size_t TcpSocket::CircularBuffer::GetLength()
{
return m_q;
}
const char *TcpSocket::CircularBuffer::GetStart()
{
return buf + m_b;
}
size_t TcpSocket::CircularBuffer::GetL()
{
return (m_b + m_q > m_max) ? m_max - m_b : m_q;
}
size_t TcpSocket::CircularBuffer::Space()
{
return m_max - m_q;
}
unsigned long TcpSocket::CircularBuffer::ByteCounter(bool clear)
{
if (clear)
{
unsigned long x = m_count;
m_count = 0;
return x;
}
return m_count;
}
std::string TcpSocket::CircularBuffer::ReadString(size_t l)
{
char *sz = new char[l + 1];
if (!Read(sz, l)) // failed, debug printout in Read() method
{
delete[] sz;
return "";
}
sz[l] = 0;
std::string tmp = sz;
delete[] sz;
return tmp;
}
void TcpSocket::OnConnectTimeout()
{
Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL);
#ifdef ENABLE_SOCKS4
if (Socks4())
{
OnSocks4ConnectFailed();
// retry direct connection
}
else
#endif
if (GetConnectionRetry() == -1 ||
(GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
{
IncreaseConnectionRetries();
// ask socket via OnConnectRetry callback if we should continue trying
if (OnConnectRetry())
{
SetRetryClientConnect();
}
else
{
SetCloseAndDelete( true );
/// \todo state reason why connect failed
OnConnectFailed();
}
}
else
{
SetCloseAndDelete(true);
/// \todo state reason why connect failed
OnConnectFailed();
}
//
SetConnecting(false);
}
#ifdef _WIN32
void TcpSocket::OnException()
{
if (Connecting())
{
#ifdef ENABLE_SOCKS4
if (Socks4())
OnSocks4ConnectFailed();
else
#endif
if (GetConnectionRetry() == -1 ||
(GetConnectionRetry() &&
GetConnectionRetries() < GetConnectionRetry() ))
{
// even though the connection failed at once, only retry after
// the connection timeout
// should we even try to connect again, when CheckConnect returns
// false it's because of a connection error - not a timeout...
}
else
{
SetConnecting(false); // tnx snibbe
SetCloseAndDelete();
OnConnectFailed();
}
return;
}
// %! exception doesn't always mean something bad happened, this code should be reworked
// errno valid here?
int err = SoError();
Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL);
SetCloseAndDelete();
}
#endif // _WIN32
int TcpSocket::Protocol()
{
return IPPROTO_TCP;
}
void TcpSocket::SetTransferLimit(size_t sz)
{
m_transfer_limit = sz;
}
void TcpSocket::OnTransferLimit()
{
}
#ifdef SOCKETS_NAMESPACE
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -