tools/hexnet: Implement UDP support (and minor refactoring)
parent
7ae843039c
commit
a7e07d2c3c
|
@ -25,6 +25,8 @@
|
|||
#include <sockpp/tcp_connector.h>
|
||||
#include <sockpp/tcp6_acceptor.h>
|
||||
#include <sockpp/tcp6_connector.h>
|
||||
#include <sockpp/udp_socket.h>
|
||||
#include <sockpp/udp6_socket.h>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
|
@ -47,6 +49,10 @@ sockpp::tcp6_socket tcp6Socket;
|
|||
sockpp::tcp6_acceptor tcp6Acceptor;
|
||||
// TCP v6 client
|
||||
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;
|
||||
|
||||
|
@ -58,6 +64,12 @@ bool outgoing = false;
|
|||
std::string host;
|
||||
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) {
|
||||
// shut down gracefully
|
||||
exitProgram = true;
|
||||
|
@ -75,10 +87,9 @@ void signalHandler(int signal) {
|
|||
|
||||
void readFromTCP() {
|
||||
ssize_t byteCount;
|
||||
uint8_t buffer[1536];
|
||||
while (!exitProgram && (outgoing? (byteCount = tcpConnector.read(buffer, sizeof(buffer))) > 0 : (byteCount = tcpSocket.read(buffer, sizeof(buffer))) > 0)) {
|
||||
while (!exitProgram && (outgoing? (byteCount = tcpConnector.read(networkBuffer, bufferSize)) > 0 : (byteCount = tcpSocket.read(networkBuffer, bufferSize)) > 0)) {
|
||||
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();
|
||||
}
|
||||
|
@ -86,15 +97,38 @@ void readFromTCP() {
|
|||
|
||||
void readFromTCP6() {
|
||||
ssize_t byteCount;
|
||||
uint8_t buffer[1536];
|
||||
while (!exitProgram && (outgoing? (byteCount = tcp6Connector.read(buffer, sizeof(buffer))) > 0 : (byteCount = tcp6Socket.read(buffer, sizeof(buffer))) > 0)) {
|
||||
while (!exitProgram && (outgoing? (byteCount = tcp6Connector.read(networkBuffer, bufferSize)) > 0 : (byteCount = tcp6Socket.read(networkBuffer, bufferSize)) > 0)) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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[]) {
|
||||
std::signal(SIGINT, signalHandler);
|
||||
std::signal(SIGTERM, signalHandler);
|
||||
|
@ -109,6 +143,7 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
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('b', "bind", "ADDRESS", "(UDP only) bind to ADDRESS instead of localhost"));
|
||||
|
||||
std::vector<CLI::Argument> arguments;
|
||||
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;
|
||||
if (ipv4) {
|
||||
// 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 {
|
||||
// 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 {
|
||||
|
@ -263,13 +330,45 @@ int main(int argc, char* argv[]) {
|
|||
return EXIT_SUCCESS;
|
||||
}
|
||||
} 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) {
|
||||
// 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 {
|
||||
// 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