📄 socket.cpp
字号:
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_RCVBUF, &val, &size) != 0 )
throw NetConfigException("Socket Option: get RCVBUF");
return val;
}
void Socket::SetReceiveSize(int Bytes)
{
if ( setsockopt(SD, SOL_SOCKET, SO_RCVBUF, &Bytes, sizeof(Bytes)) != 0 )
throw NetConfigException("Socket Option: set RCVBUF");
}
int Socket::GetSendSize(void)
{
int val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_SNDBUF, &val, &size) != 0 )
throw NetConfigException("Socket Option: get SNDBUF");
return val;
}
void Socket::SetSendSize(int Bytes)
{
if ( setsockopt(SD, SOL_SOCKET, SO_SNDBUF, &Bytes, sizeof(Bytes)) != 0 )
throw NetConfigException("Socket Option: set SNDBUF");
}
int Socket::GetMinReceive(void)
{
int val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_RCVLOWAT, &val, &size) != 0 )
throw NetConfigException("Socket Option: get RCVLOWAT");
return val;
}
void Socket::SetMinReceive(int Bytes) //---Not yet implemented in Linux
{
if ( setsockopt(SD, SOL_SOCKET, SO_RCVLOWAT, &Bytes, sizeof(Bytes)) != 0 )
throw NetConfigException("Socket Option: set RCVLOWAT");
}
int Socket::GetMinSend(void)
{
int val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_SNDLOWAT, &val, &size) != 0 )
throw NetConfigException("Socket Option: get SNDLOWAT");
return val;
}
void Socket::SetMinSend(int Bytes) //---Not yet implemented in Linux
{
if ( setsockopt(SD, SOL_SOCKET, SO_SNDLOWAT, &Bytes, sizeof(Bytes)) != 0 )
throw NetConfigException("Socket Option: set SNDLOWAT");
}
struct timeval Socket::GetReceiveTimeout(void)
{
struct timeval val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_RCVTIMEO, &val, &size) != 0 )
throw NetConfigException("Socket Option: get RCVTIMEO");
return val;
}
void Socket::SetReceiveTimeout(struct timeval& val) //---Not yet implemented in Linux
{
if ( setsockopt(SD, SOL_SOCKET, SO_RCVTIMEO, &val, sizeof(val)) != 0 )
throw NetConfigException("Socket Option: set RCVTIMEO");
}
struct timeval Socket::GetSendTimeout(void)
{
struct timeval val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_SNDTIMEO, &val, &size) != 0 )
throw NetConfigException("Socket Option: get SNDTIMEO");
return val;
}
void Socket::SetSendTimeout(struct timeval& val) //---Not yet implemented in Linux
{
if ( setsockopt(SD, SOL_SOCKET, SO_SNDTIMEO, &val, sizeof(val)) != 0 )
throw NetConfigException("Socket Option: set SNDTIMEO");
}
ENetwork Socket::GetType(void)
{
int val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_TYPE, &val, &size) != 0 )
throw NetConfigException("Socket Option: get TYPE");
return (ENetwork)val;
}
int Socket::GetTTL(void)
{
int val;
socklen_t size=sizeof(val);
if ( GetType() == eIPv4 )
{
if ( getsockopt(SD, SOL_IP, IP_TTL, &val, &size) != 0 )
throw NetConfigException("IP Option: get TTL");
}
else if ( GetType() == eIPv6 )
{
if ( getsockopt(SD, SOL_IPV6, IPV6_UNICAST_HOPS, &val, &size) != 0 )
throw NetConfigException("IP Option: get MULTICAST_TTL");
}
return val;
}
void Socket::SetTTL(int Hops)
{
if ( GetType() == eIPv4 )
{
if ( setsockopt(SD, SOL_IP, IP_TTL, &Hops, sizeof(Hops)) != 0 )
throw NetConfigException("IP Option: set TTL");
}
else if ( GetType() == eIPv6 )
{
if ( setsockopt(SD, SOL_IPV6, IPV6_UNICAST_HOPS, &Hops, sizeof(Hops)) != 0 )
throw NetConfigException("IP Option: set MULTICAST_TTL");
}
}
int Socket::GetError(void)
{
int val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_SOCKET, SO_ERROR, &val, &size) != 0 )
throw NetConfigException("Socket Option: get ERROR");
return val;
}
///////////////////////////////////////////////////////////////////////////////
/// SocketStream
//-----------------------------------------------------------------------------
//--- Class configuration (CRUD)
int SocketStream::GetMaxSegmentSize(void)
{
int val;
socklen_t size=sizeof(val);
if ( getsockopt(SD, SOL_TCP, TCP_MAXSEG, &val, &size) != 0 )
throw NetConfigException("Socket Option: get TCP_MAXSEG");
return val;
}
void SocketStream::SetMaxSegmentSize(short Bytes)
{
if ( setsockopt(SD, SOL_TCP, TCP_MAXSEG, &Bytes, sizeof(Bytes)) != 0 )
throw NetConfigException("Socket Option: set TCP_MAXSEG");
}
void SocketStream::DontDelay(bool Setting)
{
if ( setsockopt(SD, SOL_TCP, TCP_NODELAY, &Setting, sizeof(Setting)) != 0 )
throw NetConfigException("Socket Option: DONTDELAY ");
}
///////////////////////////////////////////////////////////////////////////////
/// SocketServer
//-----------------------------------------------------------------------------
//--- Constructors & Destructors
SocketServer::SocketServer(int Port, ENetwork Network, int QLen): SocketStream(Network)
{
type = eNone;
task_fn = 0;
HostAddress Addr(0);
Addr.SetPort(Port);
Bind(Addr);
if ( listen(SD, QLen) != 0 )
throw NetConnectException("Listen");
struct sigaction act;
memset(&act, 0 , sizeof(act));
act.sa_handler = SigChild;
act.sa_flags = SA_NOCLDSTOP;
if ( sigaction(SIGCHLD, &act, 0) != 0 )
throw Exception("Sigaction -- processes");
}
SocketServer::SocketServer(HostAddress& Me, int QLen): SocketStream(Me.GetNetwork())
{
type = eNone;
task_fn = 0;
Bind(Me);
if ( listen(SD, QLen) != 0 )
throw NetConnectException("Could not convert to listening socket");
struct sigaction act;
memset(&act, 0 , sizeof(act));
act.sa_handler = SigChild;
act.sa_flags = SA_NOCLDSTOP;
if ( sigaction(SIGCHLD, &act, 0) != 0 )
throw Exception("Sigaction -- processes");
}
SocketServer::~SocketServer(void)
{
}
//-----------------------------------------------------------------------------
//--- Specific Implementation
void SocketServer::Accept(void (*Server)(const Socket&))
{
int client = accept(SD, 0, 0);
if ( client < 0 )
throw NetConnectException("Problems with accepting a connection");
switch ( type )
{
case eCallback:
case eProcess:
case eThread: break;
}
(*Server)(Socket(client));
}
void SocketServer::Accept(HostAddress& Addr, void (*Server)(const Socket&))
{
socklen_t size=Addr.GetSize();
int client = accept(SD, Addr.GetAddress(), &size);
if ( client < 0 )
throw NetConnectException("Problems with accepting a connection");
switch ( type )
{
case eCallback:
case eProcess:
case eThread: break;
}
(*Server)(Socket(client));
}
//-----------------------------------------------------------------------------
//--- Class configuration (CRUD)
void SocketServer::RegTask(void (*FN)(Socket& socket, HostAddress& addr))
{
}
///////////////////////////////////////////////////////////////////////////////
/// SocketClient
//-----------------------------------------------------------------------------
//--- Constructors & Destructors
SocketClient::SocketClient(HostAddress& Host, ENetwork Network): SocketStream(Network)
{
Connect(Host);
}
//-----------------------------------------------------------------------------
//--- Specific Implementation
void SocketClient::Connect(HostAddress& Address)
{
if ( connect(SD, Address.GetAddress(), Address.GetSize()) != 0 )
throw NetConnectException("Connect");
}
///////////////////////////////////////////////////////////////////////////////
/// Datagram
//-----------------------------------------------------------------------------
//--- Constructors & Destructors
Datagram::Datagram(HostAddress& Me, ENetwork Network, EProtocol Protocol): Socket(Network, Protocol)
{
Bind(Me);
}
Datagram::Datagram(ENetwork Network, EProtocol Protocol): Socket(Network, Protocol)
{}
//-----------------------------------------------------------------------------
//--- Private class configuration (CRUD)
void Datagram::SetTOS(bool Setting, int Val)
{
int tos;
socklen_t size=sizeof(tos);
if ( getsockopt(SD, SOL_IP, IP_TOS, &tos, &size) != 0 )
throw NetConfigException("Socket Option: get IP_TOS");
if ( Setting != 0 )
tos |= Val;
else
tos &= ~Val;
if ( setsockopt(SD, SOL_IP, IP_TOS, &tos, sizeof(tos)) != 0 )
throw NetConfigException("Socket Option: set IP_TOS");
}
//-----------------------------------------------------------------------------
//--- Class configuration (CRUD)
void Datagram::MinimizeDelay(bool Setting)
{
SetTOS(Setting, IPTOS_LOWDELAY);
}
void Datagram::MaximizeThroughput(bool Setting)
{
SetTOS(Setting, IPTOS_THROUGHPUT);
}
void Datagram::MaximizeReliability(bool Setting)
{
SetTOS(Setting, IPTOS_RELIABILITY);
}
void Datagram::MinimizeCost(bool Setting)
{
SetTOS(Setting, IPTOS_LOWCOST);
}
void Datagram::PermitFragNegotiation(EFrag Setting)
{
if ( setsockopt(SD, SOL_IP, IP_MTU_DISCOVER, &Setting, sizeof(Setting)) != 0 )
throw NetConfigException("Socket Option: set MTU_DISCOVER");
}
///////////////////////////////////////////////////////////////////////////////
/// Broadcast
//-----------------------------------------------------------------------------
//--- Constructors & Destructors
Broadcast::Broadcast(HostAddress& Me): Datagram(Me)
{
const int on=1;
if ( setsockopt(SD, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) != 0 )
throw NetConfigException("Socket Option: set BROADCAST");
}
///////////////////////////////////////////////////////////////////////////////
/// MessageGroup
//-----------------------------------------------------------------------------
//--- Constructors & Destructors
MessageGroup::~MessageGroup(void)
{
HostAddress NoAddr(0, GetType());
for ( int i = 0; i < MAXGROUPS; i++ )
if ( Addr[i] != NoAddr )
Drop(Addr[i]);
}
//-----------------------------------------------------------------------------
//--- Specific Implementation
void MessageGroup::Connect(HostAddress& Address)
{
if ( connect(SD, Address.GetAddress(), Address.GetSize()) != 0 )
throw NetConnectException("Connect");
}
int MessageGroup::FindSlot(HostAddress& Host)
{ int slot=-1;
for ( int i = 0; i < MAXGROUPS && slot < 0; i++ )
if ( Addr[i] == Host )
slot = i;
return slot;
}
void MessageGroup::Join(HostAddress& Address, int IFIndex)
{ int slot=-1;
HostAddress NoAddr(0, Address.GetNetwork());
slot = FindSlot(NoAddr);
if ( slot < 0 )
throw RangeException("Multicast table full");
if ( GetType() == eIPv4 )
{ struct ip_mreqn mreq;
bzero(&mreq, sizeof(mreq));
void* src = &(reinterpret_cast<struct sockaddr_in *>(Address.GetAddress())->sin_addr);
memcpy(&mreq.imr_multiaddr, src, sizeof(mreq.imr_multiaddr));
mreq.imr_ifindex = IFIndex;
if ( setsockopt(SD, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != 0 )
throw NetConfigException("Socket Option: Join Multicast");
}
else if ( GetType() == eIPv6 )
{ struct ipv6_mreq mreq;
bzero(&mreq, sizeof(mreq));
void* src = &(reinterpret_cast<struct sockaddr_in *>(Address.GetAddress())->sin_addr);
memcpy(&mreq.ipv6mr_multiaddr, src, sizeof(mreq.ipv6mr_multiaddr));
mreq.ipv6mr_interface = IFIndex;
if ( setsockopt(SD, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != 0 )
throw NetConfigException("Socket Option: Join Multicast");
}
Addr[slot] = Address;
}
void MessageGroup::Drop(HostAddress& Address)
{ int slot=-1;
for ( int i = 0; i < MAXGROUPS && slot < 0; i++ )
if ( Addr[i] == Address )
slot = i;
if ( slot == -1 )
throw RangeException("Group not joined");
if ( GetType() == eIPv4 )
{ struct ip_mreq mreq;
struct sockaddr_in *inet = reinterpret_cast<struct sockaddr_in *>(Addr[slot].GetAddress());
mreq.imr_multiaddr = inet->sin_addr;
mreq.imr_interface.s_addr = INADDR_ANY;
if ( setsockopt(SD, SOL_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) != 0 )
throw NetConfigException("Socket Option: Drop Multicast");
}
else if ( GetType() == eIPv6 )
{ struct ipv6_mreq mreq;
struct sockaddr_in6 *inet6 = reinterpret_cast<struct sockaddr_in6 *>(Addr[slot].GetAddress());
mreq.ipv6mr_multiaddr = inet6->sin6_addr;
mreq.ipv6mr_interface = INADDR_ANY;
if ( setsockopt(SD, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) != 0 )
throw NetConfigException("Socket Option: Drop Multicast");
}
Addr[slot] = HostAddress();
}
//-----------------------------------------------------------------------------
//--- Class configuration (CRUD)
void MessageGroup::Loopback(bool Setting)
{
int val = (Setting != 0);
if ( GetType() == eIPv4 )
{
if ( setsockopt(SD, SOL_IP, IP_MULTICAST_LOOP, &val, sizeof(val)) != 0 )
throw NetConfigException("IP Option: set MULTICAST_TTL");
}
else if ( GetType() == eIPv6 )
{
if ( setsockopt(SD, SOL_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val)) != 0 )
throw NetConfigException("IP Option: set MULTICAST_TTL");
}
}
int MessageGroup::GetTTL(void)
{
int val;
socklen_t size=sizeof(val);
if ( GetType() == eIPv4 )
{
if ( getsockopt(SD, SOL_IP, IP_MULTICAST_TTL, &val, &size) != 0 )
throw NetConfigException("IP Option: get MULTICAST_TTL");
}
else if ( GetType() == eIPv6 )
{
if ( getsockopt(SD, SOL_IPV6, IPV6_MULTICAST_HOPS, &val, &size) != 0 )
throw NetConfigException("IP Option: get MULTICAST_TTL");
}
return val;
}
void MessageGroup::SetTTL(int Hops)
{
if ( GetType() == eIPv4 )
{
if ( setsockopt(SD, SOL_IP, IP_MULTICAST_TTL, &Hops, sizeof(Hops)) != 0 )
throw NetConfigException("IP Option: set MULTICAST_TTL");
}
else if ( GetType() == eIPv6 )
{
if ( setsockopt(SD, SOL_IPV6, IPV6_MULTICAST_HOPS, &Hops, sizeof(Hops)) != 0 )
throw NetConfigException("IP Option: set MULTICAST_TTL");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -