#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;
}