Example #1
0
void thread_client()
{
	try
	{
		printf("[Client] Started\n");
		CClientTCPSocket	sock;

		printf("[Client] Connecting\n");

		sock.connect( "127.0.0.1", 15000 );

		printf("[Client] Connected. Waiting for a message...\n");

//		cout << "pending: " << sock.getReadPendingBytes() << endl;
//		mrpt::system::sleep(4000);
//		cout << "pending: " << sock.getReadPendingBytes() << endl;

		CMessage	msg;
		bool ok = sock.receiveMessage( msg, 2000,2000);

		if (!ok)
		{
			printf("[Client] Error receiving message!!\n");
		}
		else
		{
			printf("[Client] Message received OK!:\n");
			printf("  MSG Type: %i\n", msg.type );
			printf("  MSG Length: %u bytes\n", (unsigned int)msg.content.size() );

			printf("[Client] Parsing image...\n");
			CImage		img;
			msg.deserializeIntoExistingObject( &img );

			printf("[Client] Saving image...\n");
			img.saveToFile("received_frame.jpg");
			printf("[Client] Done!!\n");
		}

		printf("[Client] Finish\n");
	}
	catch(std::exception &e)
	{
		cerr << e.what() << endl;
	}
	catch(...)
	{
		cerr << "[thread_client] Runtime error!" << endl;;
	}
}
Example #2
0
void thread_server()
{
	try
	{
		printf("[Server] Started\n");

		CServerTCPSocket		server( 15000, "127.0.0.1" , 10, true );
		CClientTCPSocket		*client;

		client = server.accept( 2000 );

		if (client)
		{
			printf("[Server] Conection accepted\n");

			// Load test image:
			CImage	img;
			img.loadFromFile(myDataDir+string("frame_color.jpg"));

			// Send a message with the image:
			CMessage	msg;
			msg.type	= 0x10;
			msg.serializeObject( &img );

			printf("[Server] Sending message...\n");
			client->sendMessage( msg );
			printf("[Server] Message sent!!\n");

			mrpt::system::sleep(50);

			delete client;
		}

		printf("[Server] Finish\n");
	}
	catch(std::exception &e)
	{
		cerr << e.what() << endl;
	}
	catch(...)
	{
		printf("[thread_server] Runtime error!\n");
	}
}
Example #3
0
void CListenSocket::OnAccept(int nErrorCode)
{
	// 0.42e
	if (!nErrorCode) {
		m_nPendingConnections++;
		if (m_nPendingConnections < 1) {
			wxFAIL;
			m_nPendingConnections = 1;
		}
		if (TooManySockets(true) && !theApp->serverconnect->IsConnecting()) {
			StopListening();
			return;
		} else if (bListening == false) {
			// If the client is still at maxconnections,
			// this will allow it to go above it ...
			// But if you don't, you will get a lowID on all servers.
			ReStartListening();
		}
		// Deal with the pending connections, there might be more than one, due to
		// the StopListening() call above.
		while (m_nPendingConnections) {
			m_nPendingConnections--;
			// Create a new socket to deal with the connection
			CClientTCPSocket* newclient = new CClientTCPSocket();
			// Accept the connection and give it to the newly created socket
			if (!AcceptWith(*newclient, false)) {
				newclient->Safe_Delete();
			} else {
				wxASSERT(theApp->IsRunning());
				if (!newclient->InitNetworkData()) {
					// IP or port were not returned correctly
					// from the accepted address, or filtered.
					newclient->Safe_Delete();
				}
			}
		}
	}
}
Example #4
0
/*---------------------------------------------------------------
							http_get
  ---------------------------------------------------------------*/
ERRORCODE_HTTP  BASE_IMPEXP
mrpt::utils::net::http_get(
	const string	&url,
	vector_byte		&out_content,
	string			&out_errormsg,
	int				port,
	const string	&auth_user,
	const string	&auth_pass,
	int				*out_http_responsecode,
	mrpt::utils::TParameters<string>  *extra_headers,
	mrpt::utils::TParameters<string>  *out_headers,
	int  timeout_ms
	)
{
	// Reset output data:
	out_content.clear();
	if (out_http_responsecode) *out_http_responsecode=0;
	if (out_headers) out_headers->clear();

	// URL must be:
	// http://<SERVER>/<LOCAL_ADDR>

	if (0!=::strncmp(url.c_str(),"http://",7))
	{
		out_errormsg="URL must start with 'http://'";
		return net::erBadURL;
	}

	string server_addr = url.substr(7);
	string get_object = "/";

	// Remove from the first "/" on:
	size_t pos = server_addr.find("/");
	if (pos==0)
	{
		out_errormsg="Server name not found in URL";
		return net::erBadURL;
	}
	if (pos!=string::npos)
	{
		get_object = server_addr.substr(pos);
		server_addr.resize(pos);
	}


	CClientTCPSocket	sock;

	try {
		// Connect:
		sock.connect(server_addr,port, timeout_ms);
	}
	catch (std::exception &e) {
		out_errormsg = e.what();
		return net::erCouldntConnect;
	}

	try {
		// Set the user-defined headers (we may overwrite them if needed)
		TParameters<string>  headers_to_send;
		if (extra_headers)
			headers_to_send=*extra_headers;

		headers_to_send["Connection"]="close"; // Don't keep alive

		if (!headers_to_send.has("User-Agent"))
			headers_to_send["User-Agent"]="MRPT Library";

		// Implement HTTP Basic authentication:
		// See: http://en.wikipedia.org/wiki/Basic_access_authentication
		if (!auth_user.empty())
		{
			string auth_str = auth_user+string(":")+auth_pass;
			vector_byte  v(auth_str.size());
			::memcpy(&v[0],&auth_str [0],auth_str .size());

			string encoded_str;
			mrpt::system::encodeBase64(v,encoded_str);

			headers_to_send["Authorization"]=string("Basic ")+encoded_str;
		}


		// Prepare the request string
		// ---------------------------------
		string req = format(
		  "GET %s HTTP/1.1\r\n"
          "Host: %s\r\n",
		  get_object.c_str(),server_addr.c_str());

		// Other headers:
		for (TParameters<string>::const_iterator i=headers_to_send.begin();i!=headers_to_send.end();++i)
		{
			req+=i->first;
			req+=": ";
			req+=i->second;
			req+="\r\n";
		}

		// End:
		req+="\r\n";

		// Send:
		sock.sendString(req);

		// Read answer:
		vector_byte		buf;
		buf.reserve(1<<14);

		size_t	total_read = 0;
		bool	content_length_read = false;
		bool    all_headers_read = false;
		size_t  content_length = 0;
		size_t  content_offset = 0;
		int		http_code = 0;
		mrpt::utils::TParameters<string>  rx_headers;

		CTicTac  watchdog;
		watchdog.Tic();

		while (!content_length_read || total_read<(content_offset+content_length))
		{
			// Read until "Content-Length: XXX \r\n" is read or the whole message is read,
			//  or an error code is read.
			size_t	to_read_now;

			if (!content_length_read)
			{
				to_read_now = 1500;
			}
			else
			{
				to_read_now	= (content_length+content_offset) -total_read;
			}

			// make room for the data to come:
			buf.resize(total_read+to_read_now+1);

			// Read:
			size_t len = sock.readAsync(&buf[total_read],to_read_now, timeout_ms,100);
			if (!len)
			{
				//
				if (!sock.isConnected())
				{
					if (all_headers_read) // It seems we're done...
						break;
					else
					{
						out_errormsg = "Connection to server was lost";
						return net::erCouldntConnect;
					}
				}

				if ( watchdog.Tac()>1e-3*timeout_ms)
				{
					out_errormsg = "Timeout waiting answer from server";
					return net::erCouldntConnect;
				}
				mrpt::system::sleep(10);
				continue;
			}
			total_read+=len;
			watchdog.Tic();

			buf[total_read]='\0';

			// do we have a \r\n\r\n  ??
			if (!all_headers_read)
			{
				const char *ptr = ::strstr(reinterpret_cast<const char*>(&buf[0]),"\r\n\r\n");
				if (ptr)
				{
					all_headers_read = true;
					const size_t pos_dblret = ((char*)ptr)-(char*)(&buf[0]);

					// Process the headers:
					// ------------------------------
					if (!::strncmp("HTTP/",(const char*)&buf[0], 5))
					{
						http_code = ::atoi( (const char*)&buf[9] );
					}
					else
					{
						// May it be a "SOURCETABLE " answer for NTRIP protocol??
						if (!::strncmp("SOURCETABLE ",(const char*)&buf[0], 12))
						{
							http_code = ::atoi( (const char*)&buf[12] );
						}
						else
						{
							out_errormsg = "Server didn't send an HTTP/1.1 answer.";
							return net::erOtherHTTPError;
						}
					}

					// Check the HTTP code and the content-length:
					content_offset = pos_dblret + 4;

					// Do we have a "Content-Length:"??
					const char *ptr_len = ::strstr(reinterpret_cast<const char*>(&buf[0]),"Content-Length:");
					if (ptr_len)
					{
						content_length = ::atol( ptr_len+15 );
						content_length_read = true;
					}

					// Parse the rest of HTTP headers:
					{
						string aux_all_headers;
						deque<string> lstLines;
						aux_all_headers.resize(content_offset);
						::memcpy( &aux_all_headers[0],&buf[0],content_offset);

						mrpt::system::tokenize(aux_all_headers,"\r\n",lstLines);

						for (deque<string>::const_iterator i=lstLines.begin();i!=lstLines.end();++i)
						{
							const size_t p = i->find(":");
							if (p==string::npos) continue;

							const string key = i->substr(0,p);
							const string val = i->substr(p+2);
							rx_headers[key] = val;
						}
					}

				}
			}
		} // end while


		if (out_http_responsecode) *out_http_responsecode=http_code;
		if (out_headers) *out_headers = rx_headers;

		// Remove the headers from the content:
		buf.erase(buf.begin(),buf.begin()+content_offset);

		// Process: "Transfer-Encoding: chunked"
		if (rx_headers.has("Transfer-Encoding") && rx_headers["Transfer-Encoding"]=="chunked" )
		{
			// See: http://en.wikipedia.org/wiki/Chunked_transfer_encoding

			size_t index = 0;
			while (index<buf.size())
			{
				if (buf[index]=='\r' && buf[index+1]=='\n')
				{
					buf.erase(buf.begin()+index,buf.begin()+index+2);
					continue;
				}

				const char *pCRLF = ::strstr((const char*)&buf[index],"\r\n");
				if (!pCRLF) break;

				const size_t len_substr = ((char*)pCRLF)-(char*)(&buf[index]);

				string  sLen((const char*)&buf[index], len_substr);
				sLen=string("0x")+sLen;

				unsigned int lenChunk;
				int fields = ::sscanf(sLen.c_str(),"%x",&lenChunk);
				if (!fields) break;

				// Remove the len of this chunk header from the data:
				buf.erase(buf.begin()+index,buf.begin()+index+len_substr+2);

				index+=lenChunk;

				if (!lenChunk)
				{
					buf.resize(index);
					break;
				}
			}
		}


		// Set the content output:
		out_content.swap(buf);

		if (http_code==200)
		{
			return net::erOk;
		}
		else
		{
			out_errormsg = format("HTTP error %i",http_code);
			return net::erOtherHTTPError;
		}
	}
	catch (std::exception &e) {
		out_errormsg = e.what();
		return net::erCouldntConnect;
	}

	return net::erOk;
}