Blob Blame Raw

#include <cstring>

#include <unistd.h>

#include "tcpprotocol.h"
#include "main.h"


namespace {
	class MyConnection: public Connection {
	private:
		enum { BUFSIZE = 16 };
		const bool serverSide;
		const bool serverHello;
		char buffer[2][BUFSIZE + 1];
		
	public:
		std::string name;
		
		explicit MyConnection(const char *name, bool serverSide, bool serverHello = false):
			serverSide(serverSide), serverHello(serverHello), buffer(), name(name) { }
		
	protected:
		void sendData() {
			for(int i = 0; i < BUFSIZE; ++i) buffer[1][i] = '0' + rand()%10;
			buffer[1][BUFSIZE - 2] = '\n';
			buffer[1][BUFSIZE - 1] = '\n';
			printf("%s: send: %s\n", name.c_str(), buffer[1]);
			writeReq(buffer[1], BUFSIZE);
		}
		
		ErrorCode onOpen() override {
			printf("%s: MyConnection::onOpen()\n", name.c_str());
			if (serverSide == serverHello) sendData();
			readReq(buffer[0], BUFSIZE);
			return ERR_NONE;
		}
		
		void onCloseRequested() override {
			printf("%s: MyConnection::onCloseRequested()\n", name.c_str());
			if (isAllDone()) close();
		}
		
		void onClose(ErrorCode errorCode) override {
			printf("%s: MyConnection::onClose(%u)\n", name.c_str(), errorCode);
		}
		
		void onReadReady(const ReadReq&) override {
			printf("%s: MyConnection::onReadReady()\n", name.c_str());
			printf("%s: received: %s\n", name.c_str(), buffer[0]);
			
			if (isCloseRequested()) {
				if (serverSide) sendData(); else
					if (isAllDone()) close();
			} else {
				sendData();
				readReq(buffer[0], BUFSIZE);
			}
		}
		
		void onWriteReady(const WriteReq&) override {
			printf("%s: MyConnection::onWriteReady()\n", name.c_str());
			if (isCloseRequested() && isAllDone() && serverSide) close();
		}
	};
	
	
	class MyServer: public Server {
	private:
		unsigned int lastId;
		
	public:
		MyServer(): lastId() { }
		
	protected:
		ErrorCode onStart() override {
			printf("MyServer::onStart()\n");
			return ERR_NONE;
		}
		
		void onStopRequested() override {
			printf("MyServer::onStopRequested()\n");
		}
		
		void onStop(ErrorCode errorCode) override {
			printf("MyServer::onStop(%u)\n", errorCode);
		}
		
		Connection::Handle onConnect(const Address &remoteAddress) override {
			printf("MyServer::onConnect( ");
			for(int i = 0; i < (int)remoteAddress.size; ++i) printf("%d.", remoteAddress.data[i]);
			printf(" )\n");
			
			char buf[1024] = {};
			sprintf(buf, "remote%d", ++lastId);
			printf("new connection: %s\n", buf);
			
			return Connection::Handle(new MyConnection(buf, true));
		}
		
		void onDisconnect(const Connection::Handle &connection) override {
			printf("MyServer::onDisconnect( %s )\n", ((MyConnection*)connection.pointer())->name.c_str());
		}
	};
}


int main(int argc, char** argv) {
	if (argc != 3)
		{ printf("two args expected\n"); return 1; }

	bool client = (0 == strcmp(argv[1], "tcpclient"));
	bool server = (0 == strcmp(argv[1], "tcpserver"));
	if (!client && !server)
		{ printf("wrong args\n"); return 1; }
		
	printf("start tcp protocol\n");
	TcpProtocol::Handle protocol(new TcpProtocol());
	protocol->start();
	
	Address address;
	address.set(Address::COMMON_STRING, argv[2]);
	ErrorCode errorCode = protocol->resolve(address);
	if (errorCode) {
		printf("cannot resolve address: %s, errorCode: %u\n", argv[2], errorCode);
	} else
	if (client) {
		printf("tcpclient, %s\n", argv[2]);
		
		Connection::Handle connection(new MyConnection("client", false));
		errorCode = protocol->connect(connection, address);
		if (errorCode) {
			printf("cannot open connection, errorCode: %u\n", errorCode);
		} else {
			printf("connected\n");
			usleep(5000000ll);
			//fgetc(stdin);
			printf("disconnection\n");
			connection->closeWait(10);
			printf("disconnected\n");
		}
	} else {
		printf("tcpserver, %s\n", argv[2]);
		
		Server::Handle server(new MyServer());
		errorCode = protocol->listen(server, address);
		if (errorCode) {
			printf("cannot start server, errorCode: %u\n", errorCode);
		} else {
			printf("server started\n");
			fgetc(stdin);
			printf("stop server\n");
			server->stopWait(10);
			printf("server stopped\n");
		}
	}
	
	printf("stop tcp protocol\n");
	protocol->stopWait(10*1000000ll);
	printf("finished, last error: %u\n", errorCode);
	
	return errorCode;
}