tools/hexnet: Implement UDP support (and minor refactoring)
							parent
							
								
									7ae843039c
								
							
						
					
					
						commit
						a7e07d2c3c
					
				|  | @ -25,6 +25,8 @@ | ||||||
| #include <sockpp/tcp_connector.h> | #include <sockpp/tcp_connector.h> | ||||||
| #include <sockpp/tcp6_acceptor.h> | #include <sockpp/tcp6_acceptor.h> | ||||||
| #include <sockpp/tcp6_connector.h> | #include <sockpp/tcp6_connector.h> | ||||||
|  | #include <sockpp/udp_socket.h> | ||||||
|  | #include <sockpp/udp6_socket.h> | ||||||
| #include <thread> | #include <thread> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
|  | @ -47,6 +49,10 @@ sockpp::tcp6_socket tcp6Socket; | ||||||
| sockpp::tcp6_acceptor tcp6Acceptor; | sockpp::tcp6_acceptor tcp6Acceptor; | ||||||
| // TCP v6 client
 | // TCP v6 client
 | ||||||
| sockpp::tcp6_connector tcp6Connector; | sockpp::tcp6_connector tcp6Connector; | ||||||
|  | // UDP v4 server and client
 | ||||||
|  | sockpp::udp_socket udpSocket; | ||||||
|  | // UDP v6 server and client
 | ||||||
|  | sockpp::udp6_socket udp6Socket; | ||||||
| 
 | 
 | ||||||
| bool exitProgram = false; | bool exitProgram = false; | ||||||
| 
 | 
 | ||||||
|  | @ -58,6 +64,12 @@ bool outgoing = false; | ||||||
| std::string host; | std::string host; | ||||||
| in_port_t port; | in_port_t port; | ||||||
| 
 | 
 | ||||||
|  | // This is probably bigger than the MTU on any given network.
 | ||||||
|  | // This should allow us to read entire packets at once when they arrive
 | ||||||
|  | // slowly enough to be read individually.
 | ||||||
|  | const uint32_t bufferSize = 2048; | ||||||
|  | uint8_t networkBuffer[bufferSize]; | ||||||
|  | 
 | ||||||
| void signalHandler(int signal) { | void signalHandler(int signal) { | ||||||
|     // shut down gracefully
 |     // shut down gracefully
 | ||||||
|     exitProgram = true; |     exitProgram = true; | ||||||
|  | @ -75,10 +87,9 @@ void signalHandler(int signal) { | ||||||
| 
 | 
 | ||||||
| void readFromTCP() { | void readFromTCP() { | ||||||
|     ssize_t byteCount; |     ssize_t byteCount; | ||||||
|     uint8_t buffer[1536]; |     while (!exitProgram && (outgoing? (byteCount = tcpConnector.read(networkBuffer, bufferSize)) > 0 : (byteCount = tcpSocket.read(networkBuffer, bufferSize)) > 0)) { | ||||||
|     while (!exitProgram && (outgoing? (byteCount = tcpConnector.read(buffer, sizeof(buffer))) > 0 : (byteCount = tcpSocket.read(buffer, sizeof(buffer))) > 0)) { |  | ||||||
|         for (ssize_t i=0; i<byteCount; i++) { |         for (ssize_t i=0; i<byteCount; i++) { | ||||||
|             std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) buffer[i] << " "; |             std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) networkBuffer[i] << " "; | ||||||
|         } |         } | ||||||
|         std::cout.flush(); |         std::cout.flush(); | ||||||
|     } |     } | ||||||
|  | @ -86,15 +97,38 @@ void readFromTCP() { | ||||||
| 
 | 
 | ||||||
| void readFromTCP6() { | void readFromTCP6() { | ||||||
|     ssize_t byteCount; |     ssize_t byteCount; | ||||||
|     uint8_t buffer[1536]; |     while (!exitProgram && (outgoing? (byteCount = tcp6Connector.read(networkBuffer, bufferSize)) > 0 : (byteCount = tcp6Socket.read(networkBuffer, bufferSize)) > 0)) { | ||||||
|     while (!exitProgram && (outgoing? (byteCount = tcp6Connector.read(buffer, sizeof(buffer))) > 0 : (byteCount = tcp6Socket.read(buffer, sizeof(buffer))) > 0)) { |  | ||||||
|         for (ssize_t i=0; i<byteCount; i++) { |         for (ssize_t i=0; i<byteCount; i++) { | ||||||
|             std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) buffer[i] << " "; |             std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) networkBuffer[i] << " "; | ||||||
|         } |         } | ||||||
|         std::cout.flush(); |         std::cout.flush(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void readFromUDP() { | ||||||
|  |     ssize_t byteCount; | ||||||
|  |     sockpp::udp_socket::addr_t peer; | ||||||
|  |     while ((byteCount = udpSocket.recv_from(networkBuffer, bufferSize, &peer)) > 0) { | ||||||
|  |         std::cout << peer << ": "; | ||||||
|  |         for (ssize_t i=0; i<byteCount; i++) { | ||||||
|  |             std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) networkBuffer[i] << " "; | ||||||
|  |         } | ||||||
|  |         std::cout << std::dec << std::endl; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void readFromUDP6() { | ||||||
|  |     ssize_t byteCount; | ||||||
|  |     sockpp::udp6_socket::addr_t peer; | ||||||
|  |     while ((byteCount = udp6Socket.recv_from(networkBuffer, bufferSize, &peer)) > 0) { | ||||||
|  |         std::cout << peer << ": "; | ||||||
|  |         for (ssize_t i=0; i<byteCount; i++) { | ||||||
|  |             std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) networkBuffer[i] << " "; | ||||||
|  |         } | ||||||
|  |         std::cout << std::dec << std::endl; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int main(int argc, char* argv[]) { | int main(int argc, char* argv[]) { | ||||||
|     std::signal(SIGINT, signalHandler); |     std::signal(SIGINT, signalHandler); | ||||||
|     std::signal(SIGTERM, signalHandler); |     std::signal(SIGTERM, signalHandler); | ||||||
|  | @ -109,6 +143,7 @@ int main(int argc, char* argv[]) { | ||||||
| 
 | 
 | ||||||
|     std::vector<CLI::Option> options; |     std::vector<CLI::Option> options; | ||||||
|     options.push_back(CLI::Option('c', "connect", "HOST", "make an outgoing connection to HOST instead of listening for an incoming connection")); |     options.push_back(CLI::Option('c', "connect", "HOST", "make an outgoing connection to HOST instead of listening for an incoming connection")); | ||||||
|  |     options.push_back(CLI::Option('b', "bind", "ADDRESS", "(UDP only) bind to ADDRESS instead of localhost")); | ||||||
| 
 | 
 | ||||||
|     std::vector<CLI::Argument> arguments; |     std::vector<CLI::Argument> arguments; | ||||||
|     arguments.push_back(CLI::Argument("PORT", "the port to lsiten on (or connect to)")); |     arguments.push_back(CLI::Argument("PORT", "the port to lsiten on (or connect to)")); | ||||||
|  | @ -204,10 +239,42 @@ int main(int argc, char* argv[]) { | ||||||
|             std::cerr << "Talking to " << host << " on port " << (int) port << " (UDP)..." << std::endl; |             std::cerr << "Talking to " << host << " on port " << (int) port << " (UDP)..." << std::endl; | ||||||
|             if (ipv4) { |             if (ipv4) { | ||||||
|                 // UDP v4 out
 |                 // UDP v4 out
 | ||||||
|                 return EXIT_UNIMPLEMENTED; |                 if (!udpSocket) { | ||||||
|  |                     std::cerr << "Error creating UDP socket: " << udpSocket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  |                 // Btw: Did you know that UDP has no concept of a connection?
 | ||||||
|  |                 if (!udpSocket.connect(sockpp::inet_address(host, port))) { | ||||||
|  |                     std::cerr << "Error associating socket with " << host << " port " << port << std::endl; | ||||||
|  |                     std::cerr << udpSocket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::thread threadReadFromUDP = std::thread(readFromUDP); | ||||||
|  |                 //std::thread threadWriteToUDP = std::thread(writeToUDP);
 | ||||||
|  | 
 | ||||||
|  |                 threadReadFromUDP.join(); | ||||||
|  |                 //threadWriteToUDP.join();
 | ||||||
|  | 
 | ||||||
|  |                 std::cout << std::endl; | ||||||
|  |                 return EXIT_SUCCESS; | ||||||
|             } else { |             } else { | ||||||
|                 // UDP v6 out
 |                 // UDP v6 out
 | ||||||
|                 return EXIT_UNIMPLEMENTED; |                 if (!udp6Socket) { | ||||||
|  |                     std::cerr << "Error creating UDP socket: " << udp6Socket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  |                 // Btw: Did you know that UDP has no concept of a connection?
 | ||||||
|  |                 if (!udp6Socket.connect(sockpp::inet6_address(host, port))) { | ||||||
|  |                     std::cerr << "Error associating socket with " << host << " port " << port << std::endl; | ||||||
|  |                     std::cerr << udp6Socket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::thread threadReadFromUDP6 = std::thread(readFromUDP6); | ||||||
|  |                 //std::thread threadWriteToUDP6 = std::thread(writeToUDP6);
 | ||||||
|  | 
 | ||||||
|  |                 threadReadFromUDP6.join(); | ||||||
|  |                 //threadWriteToUDP6.join();
 | ||||||
|  | 
 | ||||||
|  |                 std::cout << std::endl; | ||||||
|  |                 return EXIT_SUCCESS; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|  | @ -263,13 +330,45 @@ int main(int argc, char* argv[]) { | ||||||
|                 return EXIT_SUCCESS; |                 return EXIT_SUCCESS; | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             std::cerr << "Listening on port " << (int) port << " (UDP)..." << std::endl; |             std::string address = "localhost"; | ||||||
|  |             if (cliParser.getOption("bind").errorCode != ErrorCodes::NOT_PRESENT) { | ||||||
|  |                 address = cliParser.getOption("bind").value; | ||||||
|  |             } | ||||||
|  |             std::cerr << "Listening on " << address << " port " << (int) port << " (UDP)..." << std::endl; | ||||||
|             if (ipv4) { |             if (ipv4) { | ||||||
|                 // UDP v4 in
 |                 // UDP v4 in
 | ||||||
|                 return EXIT_UNIMPLEMENTED; |                 if (!udpSocket) { | ||||||
|  |                     std::cerr << "Error creating UDP socket: " << udpSocket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  |                 if (!udpSocket.bind(sockpp::inet_address(address, port))) { | ||||||
|  |                     std::cerr << "Error binding UDP socket to " << address << " port " << port << ": " << udpSocket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::thread threadReadFromUDP = std::thread(readFromUDP); | ||||||
|  |                 //std::thread threadWriteToUDP = std::thread(writeToUDP);
 | ||||||
|  | 
 | ||||||
|  |                 threadReadFromUDP.join(); | ||||||
|  |                 //threadWriteToUDP.join();
 | ||||||
|  | 
 | ||||||
|  |                 std::cout << std::endl; | ||||||
|  |                 return EXIT_SUCCESS; | ||||||
|             } else { |             } else { | ||||||
|                 // UDP v6 in
 |                 // UDP v6 in
 | ||||||
|                 return EXIT_UNIMPLEMENTED; |                 if (!udp6Socket) { | ||||||
|  |                     std::cerr << "Error creating UDP socket: " << udp6Socket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  |                 if (!udp6Socket.bind(sockpp::inet6_address(address, port))) { | ||||||
|  |                     std::cerr << "Error binding UDP socket to " << address << " port " << port << ": " << udp6Socket.last_error_str() << std::endl; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::thread threadReadFromUDP6 = std::thread(readFromUDP6); | ||||||
|  |                 //std::thread threadWriteToUDP6 = std::thread(writeToUDP6);
 | ||||||
|  | 
 | ||||||
|  |                 threadReadFromUDP6.join(); | ||||||
|  |                 //threadWriteToUDP6.join();
 | ||||||
|  | 
 | ||||||
|  |                 std::cout << std::endl; | ||||||
|  |                 return EXIT_SUCCESS; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 BodgeMaster
						BodgeMaster