void LocalPortForwarder::forward(Poco::Net::StreamSocket& socket)
{
	if (_logger.debug())
	{
		_logger.debug(Poco::format("Local connection accepted, creating forwarding connection to %s, remote port %hu", _remoteURI.toString(), _remotePort));
	}
	try
	{
		std::string path(_remoteURI.getPathEtc());
		if (path.empty()) path = "/";
		Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPRequest::HTTP_1_1);
		request.set(SEC_WEBSOCKET_PROTOCOL, WEBTUNNEL_PROTOCOL);
		request.set(X_WEBTUNNEL_REMOTEPORT, Poco::NumberFormatter::format(_remotePort));
		Poco::Net::HTTPResponse response;
		Poco::SharedPtr<Poco::Net::WebSocket> pWebSocket = _pWebSocketFactory->createWebSocket(_remoteURI, request, response);
		if (response.get(SEC_WEBSOCKET_PROTOCOL, "") != WEBTUNNEL_PROTOCOL)
		{
			_logger.error("The remote host does not support the WebTunnel protocol.");
			pWebSocket->shutdown(Poco::Net::WebSocket::WS_PROTOCOL_ERROR);
			pWebSocket->close();
			socket.close();
			return;
		}

		_pDispatcher->addSocket(socket, new StreamSocketToWebSocketForwarder(_pDispatcher, pWebSocket), _localTimeout);
		_pDispatcher->addSocket(*pWebSocket, new WebSocketToStreamSocketForwarder(_pDispatcher, socket), _remoteTimeout);
	}
	catch (Poco::Exception& exc)
	{
		_logger.error(Poco::format("Failed to open forwarding connection: %s", exc.displayText()));
		socket.close();
	}
}
int main()
{
	Poco::DateTime now;
	char szClientName[256] = { 0, };
	sprintf_s(szClientName, 256 - 1, "(%d-%d)", now.second(), now.millisecond());
		
	std::cout << "clinet(" << szClientName << ") 서버에 연결 시도..." << std::endl;
	Poco::Net::StreamSocket ss;

	try
	{
		ss.connect(Poco::Net::SocketAddress("localhost", PORT));

		for (int i = 0; i < 7; ++i)
		{
			char szMessage[256] = { 0, };
			sprintf_s(szMessage, 256 - 1, "%d, Send Message From %s", i, szClientName);
			auto nMsgLen = (int)strnlen_s(szMessage, 256 - 1);

			ss.sendBytes(szMessage, nMsgLen);

			std::cout << "서버에 보낸 메시지: " << szMessage << std::endl;


			char buffer[256] = { 0, };
			auto len = ss.receiveBytes(buffer, sizeof(buffer));

			if (len <= 0)
			{
				std::cout << "서버와 연결이 끊어졌습니다" << std::endl;
				break;
			}

			std::cout << "서버로부터 받은 메시지: " << buffer << std::endl;

			Poco::Thread::sleep(256);
		}

		ss.close();
	}
	catch (Poco::Exception& exc)
	{
		std::cout << "서버 접속 실패: " << exc.displayText() << std::endl;
	}
		
	getchar();
	return 0;
}
void AcceptThread::run() {
	Poco::Net::StreamSocket StrmSock;

	#ifndef _DEBUG
	string sNewConnectionIP;
	vector<std::pair<string,Poco::Timestamp::TimeDiff>> vConnections,vBannedIPs;
	vector<	std::pair<
						string,  /* IP */
						std::pair<
								Timestamp::TimeDiff, /* Ban time */
								Timestamp::TimeDiff /* Entry reset */
								 >
					>
	       > vBanLenght;

	Poco::Stopwatch Timer;
	Poco::Timestamp::TimeDiff lowest,actual;
	
	int x,i;
	short iCount;
	bool fExit;
	
	Timer.start();
	#endif

	_iThreadStatus = FC_THREADSTATUS_RUNNING;
	while(_iThreadStatus==FC_THREADSTATUS_RUNNING) {
		try {
			_ServerSock.listen();
			StrmSock = _ServerSock.acceptConnection(); 
			
			#ifndef _DEBUG
			cutOffPort(StrmSock.peerAddress().toString(),sNewConnectionIP);
			/* Check banlist */
			if (!vBannedIPs.empty()) {
				actual = (Timer.elapsed()/1000);
				fExit = false;

				for (x=vBannedIPs.size()-1;x>=0;x--){
					if (vBannedIPs[x].first.compare(sNewConnectionIP) != 0) {continue;}
					i = search(vBanLenght,sNewConnectionIP);

					if (actual - vBannedIPs[x].second >= vBanLenght[i].second.first) { /* Ban timed out */			
						/* Remove from connection list */
						if (!vConnections.empty()){
							for (i=vConnections.size()-1;i>=0;i--) { 
								if (vConnections[i].first.compare(vBannedIPs[x].first) == 0){vConnections.erase(vConnections.begin()+i);}
							}
						}

						vBannedIPs.erase(vBannedIPs.begin()+x); /* Remove from banlist */
						continue;
					}
					if (vBannedIPs[x].first.compare(sNewConnectionIP) == 0) {
						StrmSock.close();
						fExit = true;
						break;
					}
				}
				if (fExit) {continue;}
			}

			/* Remove old banlenght entries */
			if (!vBanLenght.empty()) {
				for (x = vBanLenght.size()-1;x>=0;x--) {
					if (vBanLenght[x].second.second < Timer.elapsed()/1000) { /* last ban was for 5 minutes -> remove it*/
						vBanLenght.erase( vBanLenght.begin()+x);
					}
				}
			}

			/* Manage connection list + ban if needed */
			vConnections.push_back(std::make_pair(sNewConnectionIP,Timer.elapsed()/1000L)); /* Add connection to list */
			iCount = 0;
			lowest = 30000;
			fExit = false;
			for (x=vConnections.size()-1;x>=0;x--) {
				if ((Timer.elapsed()/1000) - vConnections[x].second >= 30000){ /* Entry is old, remove it */
					vConnections.erase(vConnections.begin()+x);
					continue;
				}

				/* Timespan between actual time and connection time of this entry */
				actual = (Timer.elapsed()/1000) - vConnections[x].second;

				if (vConnections[x].first.compare(sNewConnectionIP) == 0) { /* This IP connected more than one time */
					iCount++;
					if (actual < lowest) {lowest = actual;}
				}

				/* More than four connections in a timespan of 10 seconds -> ban IP */
				if (iCount > 4 && lowest <= 10000) {
					StrmSock.close();
					vBannedIPs.push_back(std::make_pair(sNewConnectionIP,Timer.elapsed()/1000));

					/* Set banlenght */
					if ((x = search(vBanLenght,sNewConnectionIP)) == -1) {
						vBanLenght.push_back(std::make_pair(sNewConnectionIP,std::make_pair(10000,Timer.elapsed()/1000 + 5*60*1000)));
						/*x = vBanLenght.size()-1;*/
					}else{
						vBanLenght[x].second.first *= 2;
						vBanLenght[x].second.second = Timer.elapsed()/1000 + (5*60*1000) + vBanLenght[x].second.first;
					}
					/*cout<<vBanLenght[x].first<<" banned for:"<< (vBanLenght[x].second.first/1000)<<" seconds\n";*/

					fExit = true;
					break;
				}
			}
			if (fExit) {continue;}
			#endif

			if (!_pMinecraftServer->getPlayerPool()->isAnySlotFree()) { //There is no free slot
				StrmSock.sendBytes(_preparedServerFullMsg.c_str(),_preparedServerFullMsg.length());
				StrmSock.close();
				continue;
			}

			_pMinecraftServer->getPlayerPool()->Assign(StrmSock);
		}catch(...) {       /* Only happen if socket become closed */
			_iThreadStatus = FC_THREADSTATUS_DEAD;
			return;
		}
	}
}
Exemple #4
0
/// connect to an event mode control progam and read live events
int liveData(const std::string& host)
{
	static char* junk_buffer[10000];
	Poco::Net::StreamSocket s;
    Poco::UInt16 port = 10000;
	Poco::Net::SocketAddress address(host, port);
	s.connect(address);
	TCPStreamEventDataSetup setup;
    while( s.available() < static_cast<int>(sizeof(setup)) )
	{
		Poco::Thread::sleep(1000);
	}
	s.receiveBytes(&setup, sizeof(setup));
	if ( !setup.isValid() )
	{
		throw std::runtime_error("version wrong");
	}
	std::cerr << "run number " << setup.head_setup.run_number << std::endl; 
	TCPStreamEventDataNeutron events;
	while(true)
	{
        while(s.available() < static_cast<int>(sizeof(events.head)))
		{
			Poco::Thread::sleep(100);
		}
		s.receiveBytes(&events.head, sizeof(events.head));
		if ( !events.head.isValid() )
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
		if ( !(events.head.type == TCPStreamEventHeader::Neutron) )
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
        s.receiveBytes(junk_buffer, events.head.length - static_cast<uint32_t>(sizeof(events.head)));
        while(s.available() < static_cast<int>(sizeof(events.head_n)))
		{
			Poco::Thread::sleep(100);
		}
		s.receiveBytes(&events.head_n, sizeof(events.head_n));
		if ( !events.head_n.isValid() )
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
        s.receiveBytes(junk_buffer, events.head_n.length - static_cast<uint32_t>(sizeof(events.head_n)));
        events.data.resize(events.head_n.nevents);
        uint32_t nread = 0;
		while( nread < events.head_n.nevents )
		{
      uint32_t ntoread = static_cast<uint32_t>(s.available() / static_cast<int>(sizeof(TCPStreamEventNeutron)));
			if ( ntoread > (events.head_n.nevents - nread) )
			{
				ntoread = events.head_n.nevents - nread;
			}
			if (ntoread > 0)
			{
                s.receiveBytes(&(events.data[nread]), ntoread * static_cast<int>(sizeof(TCPStreamEventNeutron)));
				nread += ntoread;
			}
			else
			{
				Poco::Thread::sleep(100);
			}
		}
		if (!events.isValid())
		{
			throw std::runtime_error("corrupt stream - you should reconnect");
		}
        //TCPStreamEventHeader& head = events.head;
		TCPStreamEventHeaderNeutron& head_n = events.head_n;
		std::cerr << "Read " << nread << " events for frame number " << head_n.frame_number << " time " << head_n.frame_time_zero << std::endl;
		for(int i=0; i<10; ++i)
		{
			std::cerr << events.data[i].time_of_flight << " " << events.data[i].spectrum << std::endl;
		}
	}
	s.close();
	return 0;
}