예제 #1
0
int SctpSocket::Bind(SocketAddress& ad)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
		return -1;
	}
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), m_type, "sctp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		int n = bind(GetSocket(), ad, ad);
		if (n == -1)
		{
			Handler().LogError(this, "SctpSocket", -1, "bind() failed", LOG_LEVEL_ERROR);
#ifdef ENABLE_EXCEPTIONS
			throw Exception("bind() failed for SctpSocket, port: " + Utility::l2string(ad.GetPort()));
#endif
		}
		return n;
	}
	return -1;
}
예제 #2
0
//----------------------------------------------------------------------------
void SocketImpl::Bind6(const SocketAddress& address, bool reuseAddress, 
	bool ipV6Only)
{
#if defined(PX2_HAVE_IPV6)
	if (address.GetFamily() != IPAddress::IPv6)
	{
		assertion(false, "SocketAddress must be an IPv6 address");
	}

	if (mSocket == PX2_INVALID_SOCKET)
	{
		Init(address.GetAF());
	}
#ifdef IPV6_V6ONLY
	SetOption(IPPROTO_IPV6, IPV6_V6ONLY, ipV6Only ? 1 : 0);
#else
	if (ipV6Only)
	{
		assertion(false, "IPV6_V6ONLY not defined.");
	}
#endif
	if (reuseAddress)
	{
		SetReuseAddress(true);
		SetReusePort(true);
	}
	int rc = ::bind(mSocket, address.GetAddr(), address.GetAddrLength());
	if (rc != 0)
	{
		NetError::Error(address.ToString());
	}
#else
	assertion(false, "No IPv6 support available.\n");
#endif
}
예제 #3
0
int UdpSocket::Bind(SocketAddress& ad, int range)
{
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		SetNonblocking(true);
		int n = bind(GetSocket(), ad, ad);
		int tries = range;
		while (n == -1 && tries--)
		{
			ad.SetPort(ad.GetPort() + 1);
			n = bind(GetSocket(), ad, ad);
		}
		if (n == -1)
		{
			Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL);
			SetCloseAndDelete();
#ifdef ENABLE_EXCEPTIONS
			throw Exception("bind() failed for UdpSocket, port:range: " + Utility::l2string(ad.GetPort()) + ":" + Utility::l2string(range));
#endif
			return -1;
		}
		m_bind_ok = true;
		m_port = ad.GetPort();
		return 0;
	}
	return -1;
}
예제 #4
0
bool
SocketDescriptor::CreateConnectUDP(const char *host, const char *port)
{
  const int socktype = SOCK_DGRAM;

  SocketAddress address;
  if (!address.Lookup(host, port, socktype))
    return false;

  return Create(address.GetFamily(), socktype, 0) && Connect(address);
}
예제 #5
0
bool Ipv4Address::operator==(SocketAddress& a)
{
	if (a.GetFamily() != GetFamily())
		return false;
	if ((socklen_t)a != sizeof(m_addr))
		return false;
	struct sockaddr *sa = a;
	struct sockaddr_in *p = (struct sockaddr_in *)sa;
	if (p -> sin_port != m_addr.sin_port)
		return false;
	if (memcmp(&p -> sin_addr, &m_addr.sin_addr, 4))
		return false;
	return true;
}
예제 #6
0
void UdpSocket::SendToBuf(SocketAddress& ad, const char *data, int len, int flags)
{
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		SetNonblocking(true);
		if ((m_last_size_written = sendto(GetSocket(), data, len, flags, ad, ad)) == -1)
		{
			Handler().LogError(this, "sendto", Errno, StrError(Errno), LOG_LEVEL_ERROR);
		}
	}
}
예제 #7
0
bool UdpSocket::Open(SocketAddress& ad)
{
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		SetNonblocking(true);
		if (connect(GetSocket(), ad, ad) == -1)
		{
			Handler().LogError(this, "connect", Errno, StrError(Errno), LOG_LEVEL_FATAL);
			SetCloseAndDelete();
			return false;
		}
		SetConnected();
		return true;
	}
	return false;
}
예제 #8
0
int SctpSocket::Open(SocketAddress& ad)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
		return -1;
	}
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), m_type, "sctp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		if (!SetNonblocking(true))
		{
			return -1;
		}
		int n = connect(GetSocket(), ad, ad);
		if (n == -1)
		{
			// check error code that means a connect is in progress
#ifdef _WIN32
			if (Errno == WSAEWOULDBLOCK)
#else
			if (Errno == EINPROGRESS)
#endif
			{
				Handler().LogError(this, "connect: connection pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
				SetConnecting( true ); // this flag will control fd_set's
			}
			else
			{
				Handler().LogError(this, "SctpSocket", -1, "connect() failed", LOG_LEVEL_ERROR);
			}
		}
		return n;
	}
	return -1;
}
bool AcceptSocket::Init(SocketAddress bindAddress)
{
	bool result = socket.Init(bindAddress->GetFamily());
	if (!result)
	{
		return result;
	}

	result = socket.Bind(bindAddress);
	if (!result)
	{
		Close();
		return result;
	}

	result = socket.Listen();
	if (!result)
	{
		Close();
		return result;
	}

	return result;
}
예제 #10
0
bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL);
		SetCloseAndDelete();
		return false;
	}
	if (Handler().GetCount() >= Handler().MaxCount())
	{
		Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL);
		SetCloseAndDelete();
		return false;
	}
	SetConnecting(false);
#ifdef ENABLE_SOCKS4
	SetSocks4(false);
#endif
	// check for pooling
#ifdef ENABLE_POOL
	if (Handler().PoolEnabled())
	{
		ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad);
		if (pools)
		{
			CopyConnection( pools );
			delete pools;

			SetIsClient();
			SetCallOnConnect(); // ISocketHandler must call OnConnect
			Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO);
			return true;
		}
	}
#endif
	// if not, create new connection
	SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp");
	if (s == INVALID_SOCKET)
	{
		return false;
	}
	// socket must be nonblocking for async connect
	if (!SetNonblocking(true, s))
	{
		SetCloseAndDelete();
		closesocket(s);
		return false;
	}
#ifdef ENABLE_POOL
	SetIsClient(); // client because we connect
#endif
	SetClientRemoteAddress(ad);
	int n = 0;
	if (bind_ad.GetPort() != 0)
	{
		bind(s, bind_ad, bind_ad);
	}
#ifdef ENABLE_SOCKS4
	if (!skip_socks && GetSocks4Host() && GetSocks4Port())
	{
		Ipv4Address sa(GetSocks4Host(), GetSocks4Port());
		{
			std::string sockshost;
			Utility::l2ip(GetSocks4Host(), sockshost);
			Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" +
				Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO);
		}
		SetSocks4();
		n = connect(s, sa, sa);
		SetRemoteAddress(sa);
	}
	else
#endif
	{
		n = connect(s, ad, ad);
		SetRemoteAddress(ad);
	}
	if (n == -1)
	{
		// check error code that means a connect is in progress
#ifdef _WIN32
		if (Errno == WSAEWOULDBLOCK)
#else
		if (Errno == EINPROGRESS)
#endif
		{
			Attach(s);
			SetConnecting( true ); // this flag will control fd_set's
		}
		else
#ifdef ENABLE_SOCKS4
		if (Socks4() && Handler().Socks4TryDirect() ) // retry
		{
			closesocket(s);
			return Open(ad, true);
		}
		else
#endif
#ifdef ENABLE_RECONNECT
		if (Reconnect())
		{
			Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
			Attach(s);
			SetConnecting( true ); // this flag will control fd_set's
		}
		else
#endif
		{
			Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL);
			SetCloseAndDelete();
			closesocket(s);
			return false;
		}
	}
	else
	{
		Attach(s);
		SetCallOnConnect(); // ISocketHandler must call OnConnect
	}

	// 'true' means connected or connecting(not yet connected)
	// 'false' means something failed
	return true; //!Connecting();
}
	void SimpleStreamEchoServer_ImplementedWithSocket(unsigned short port)
	{
		if (InitWinSock())
		{
			return;
		}

		std::cout << "Hello World!" << std::endl;
		
		PackageFactory::getInstance().registerPackage(0, []() { return new PackableClass; });

		SocketAddress bindAddress = SocketAddressFactory::Create("0.0.0.0", port);
		StreamSocket socket;
		if (!socket.Init(bindAddress->GetFamily()))
		{
			std::cout << "Error initializing socket" << std::endl;
			socket.Close();
			ShutdownWinSock();
			return;
		}

		if (!socket.Bind(bindAddress))
		{
			std::cout << "Error binding socket" << std::endl;
			socket.Close();
			ShutdownWinSock();
			return;
		}

		if (!socket.Listen())
		{
			std::cout << "Error listening on socket" << std::endl;
			socket.Close();
			ShutdownWinSock();
			return;
		}

		std::cout << "Waiting to accept a client" << std::endl;

		StreamConnection client;
		client = socket.Accept();
		if (!client.IsConnected())
		{
			std::cout << "Error accepting client" << std::endl;
			socket.Close();
			ShutdownWinSock();
			return;
		}
		//No longer need server socket
		socket.Close();

		std::cout << "Client connected: " << client.GetSocket().GetSocket() << std::endl;

		int result = 0;
		do
		{
			auto package = client.RecvAll();
			if (package->getId() >= 0)
			{
				std::cout << "Bytes received: " << result << std::endl;

				auto person = dynamic_cast<PackableClass*>(package.get());
				person->print();

				result = client.SendAll(*person);
				if (result == SOCKET_ERROR)
				{
					std::cout << "Send failed with error: " << WSAGetLastError() << std::endl;
				}
				else
				{
					std::cout << "Bytes send: " << result << std::endl;
				}
			}
			else
			{
				auto errorPackage = dynamic_cast<ErrorPackage*>(package.get());
				std::cout << "Recv failed with error: " << errorPackage->getErrorCode() << std::endl;
				std::cout << "StreamConnection closing..." << std::endl;
				client.Disconnect();
			}

		} while (result > 0);

		client.Disconnect();
		ShutdownWinSock();
	}