⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.cpp

📁 linux下网络编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -