X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Tools%2FNetTest%2Ftcpserver.c;h=d38b442f894f52040a05fc8c09fdeef2d4c8afaf;hb=d2f1a4c62225533351551870cbe44d94a4ec4fab;hp=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391;hpb=f08ffb4a09855859328b73127ad5a62505564612;p=tpg%2Facess2.git diff --git a/Tools/NetTest/tcpserver.c b/Tools/NetTest/tcpserver.c index e69de29b..d38b442f 100644 --- a/Tools/NetTest/tcpserver.c +++ b/Tools/NetTest/tcpserver.c @@ -0,0 +1,92 @@ +/* + * Acess2 Networking Test Suite (NetTest) + * - By John Hodge (thePowersGang) + * + * tcpserver.c + * - TCP Client tester + */ +#include +#include +#include +#include "tcpserver.h" + +#define MAX_CLIENTS 4 + +struct sNetTest_TCPServer +{ + int ServerFD; + int nClients; + struct sClient { + int FD; + } Clients[MAX_CLIENTS]; +}; + +// === CODE === +tNetTest_TCPServer *NetTest_TCPServer_Create(int Port) +{ + tNetTest_TCPServer *ret; + ret = calloc(sizeof(*ret), 1); + ret->ServerFD = VFS_Open("/Devices/ip/1/tcps", VFS_OPENFLAG_READ); + ASSERT(ret->ServerFD >= 0); + VFS_IOCtl(ret->ServerFD, 4, &Port); + return ret; +} + +void NetTest_TCPServer_Close(tNetTest_TCPServer *Srv) +{ + VFS_Close(Srv->ServerFD); + for( int i = 0; i < Srv->nClients; i ++ ) + { + struct sClient *client = &Srv->Clients[i]; + VFS_Close(client->FD); + } + free(Srv); +} + +int NetTest_TCPServer_FillSelect(tNetTest_TCPServer *Srv, fd_set *fds) +{ + ASSERT(Srv->ServerFD >= 0); + int max = -1; + + if( Srv->nClients == MAX_CLIENTS ) { + max = Srv->ServerFD; + FD_SET(Srv->ServerFD, fds); + } + for( int i = 0; i < Srv->nClients; i ++ ) + { + int fd = Srv->Clients[i].FD; + if( fd > max ) max = fd; + FD_SET(fd, fds); + } + return max; +} + +void NetTest_TCPServer_HandleSelect(tNetTest_TCPServer *Srv, const fd_set *rfds, const fd_set *wfds, const fd_set *efds) +{ + if( FD_ISSET(Srv->ServerFD, rfds) ) + { + // New connection! + ASSERT(Srv->nClients != MAX_CLIENTS); + struct sClient *client = &Srv->Clients[Srv->nClients++]; + client->FD = VFS_OpenChild(Srv->ServerFD, "", VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE); + } + + for( int i = 0; i < Srv->nClients; i ++ ) + { + struct sClient *client = &Srv->Clients[i]; + if( FD_ISSET(client->FD, rfds) ) + { + // RX'd data on client + } + + if( FD_ISSET(client->FD, efds) ) + { + // Drop client + VFS_Close(client->FD); + memmove(client, client+1, (Srv->nClients-i-1) * sizeof(*client)); + Srv->nClients --; + i --; // counteract i++ + } + } +} +