tools/hexnet: initial implementation of TCP receive only server
parent
21310fecc7
commit
b1733bc007
|
@ -14,9 +14,11 @@
|
||||||
//If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
|
//If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <sockpp/tcp_acceptor.h>
|
||||||
|
|
||||||
#include "../lib/error.h++"
|
#include "../lib/error.h++"
|
||||||
#include "../lib/cli.h++"
|
#include "../lib/cli.h++"
|
||||||
|
@ -34,8 +36,9 @@ int main(int argc, char* argv[]){
|
||||||
bool tcp = true;
|
bool tcp = true;
|
||||||
bool udp = true;
|
bool udp = true;
|
||||||
bool listen = false;
|
bool listen = false;
|
||||||
|
int64_t mtu = 1500;
|
||||||
std::string host;
|
std::string host;
|
||||||
uint16_t port;
|
in_port_t port;
|
||||||
|
|
||||||
std::vector<CLI::Flag> flags;
|
std::vector<CLI::Flag> flags;
|
||||||
flags.push_back(CLI::Flag('4', "ipv4", "use IPv4, defaults to both when -4 and -6 are omitted, otherwise uses what is specified"));
|
flags.push_back(CLI::Flag('4', "ipv4", "use IPv4, defaults to both when -4 and -6 are omitted, otherwise uses what is specified"));
|
||||||
|
@ -45,6 +48,7 @@ int main(int argc, char* argv[]){
|
||||||
|
|
||||||
std::vector<CLI::UnpositionalArgument> unpositionalArguments;
|
std::vector<CLI::UnpositionalArgument> unpositionalArguments;
|
||||||
unpositionalArguments.push_back(CLI::UnpositionalArgument('c', "connect", "HOST", "connect to HOST, listen for incoming connections if omitted"));
|
unpositionalArguments.push_back(CLI::UnpositionalArgument('c', "connect", "HOST", "connect to HOST, listen for incoming connections if omitted"));
|
||||||
|
unpositionalArguments.push_back(CLI::UnpositionalArgument('m', "mtu-optimize", "MTU", "Optimize for a specific maximum transfer unit by reading MTU bytes at a time."));
|
||||||
|
|
||||||
std::vector<CLI::PositionalArgument> positionalArguments;
|
std::vector<CLI::PositionalArgument> positionalArguments;
|
||||||
positionalArguments.push_back(CLI::PositionalArgument("PORT", "the port to use"));
|
positionalArguments.push_back(CLI::PositionalArgument("PORT", "the port to use"));
|
||||||
|
@ -66,15 +70,56 @@ int main(int argc, char* argv[]){
|
||||||
if (cliParser.getUnpositionalArgument('c').errorCode == ErrorCodes::NOT_PRESENT) {
|
if (cliParser.getUnpositionalArgument('c').errorCode == ErrorCodes::NOT_PRESENT) {
|
||||||
listen = true;
|
listen = true;
|
||||||
}
|
}
|
||||||
|
if (cliParser.getUnpositionalArgument('m').errorCode == ErrorCodes::SUCCESS) {
|
||||||
|
mtu = std::stol(cliParser.getUnpositionalArgument('m').value);
|
||||||
|
}
|
||||||
host = cliParser.getUnpositionalArgument('c').value;
|
host = cliParser.getUnpositionalArgument('c').value;
|
||||||
//FIXME: use a function that returns a fixed-width data type instead
|
//FIXME: use a function that returns a fixed-width data type instead,
|
||||||
port = (uint16_t) std::stoi(cliParser.getPositionalArgument(0).value);
|
// ensure that the given value is a valid port
|
||||||
|
port = (in_port_t) std::stoi(cliParser.getPositionalArgument(0).value);
|
||||||
|
|
||||||
std::cerr << "Port: " << (int) port << std::endl;
|
if (listen) {
|
||||||
std::cerr << (listen? "Listening" : "Host: ") << host << std::endl;
|
if (ipv6) {
|
||||||
std::cerr << "IPv4: " << (ipv4? "yes" : "no") << std::endl;
|
std::cerr << "IPv6 support is not implented yet." << std::endl;
|
||||||
std::cerr << "IPv6: " << (ipv6? "yes" : "no") << std::endl;
|
return EXIT_UNIMPLEMENTED;
|
||||||
std::cerr << "TCP: " << ( tcp? "yes" : "no") << std::endl;
|
}
|
||||||
std::cerr << "UDP: " << ( udp? "yes" : "no") << std::endl;
|
if (udp) {
|
||||||
return EXIT_UNIMPLEMENTED;
|
std::cerr << "UDP support is not implemented yet." << std::endl;
|
||||||
|
return EXIT_UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
std::cerr << "Listening on port " << port << "." << std::endl;
|
||||||
|
|
||||||
|
sockpp::socket_initializer socketInitializer;
|
||||||
|
sockpp::tcp_acceptor tcpAcceptor(port);
|
||||||
|
|
||||||
|
if (!tcpAcceptor) {
|
||||||
|
std::cerr << "Error while creating TCP acceptor: " << tcpAcceptor.last_error_str() << std::endl;
|
||||||
|
return EXIT_RUNTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockpp::inet_address peer;
|
||||||
|
sockpp::tcp_socket tcpSocket = tcpAcceptor.accept(&peer);
|
||||||
|
std::cerr << "Incoming connection from " << peer << std::endl;
|
||||||
|
|
||||||
|
if (!tcpSocket) {
|
||||||
|
std::cerr << "Error on incoming connection: " << tcpAcceptor.last_error_str() << std::endl;
|
||||||
|
return EXIT_RUNTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t numBytes;
|
||||||
|
uint8_t buffer[mtu];
|
||||||
|
while ((numBytes = tcpSocket.read(buffer, sizeof(buffer))) > 0) {
|
||||||
|
for (ssize_t i=0; i<numBytes; i++) {
|
||||||
|
std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) buffer[i];
|
||||||
|
}
|
||||||
|
std::cout.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << std::endl << "Connection closed." << std::endl;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
std::cerr << "Client mode is not implemented yet." << std::endl;
|
||||||
|
return EXIT_UNIMPLEMENTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue