From 86639c3e9fabd919b41c98e7f790f1d5afbb343b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl-Benedikt=20Kr=C3=BCger?= Date: Tue, 12 Jul 2011 12:56:48 +0200 Subject: [PATCH] server & client test --- kernel/Makefile | 2 +- kernel/client.c | 118 +++++++++++++++++++++++++++++ kernel/client.h | 56 ++++++++++++++ kernel/server.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/server.h | 67 +++++++++++++++++ kernel/tests.c | 113 ++++++++++++++++++++++++++++ 6 files changed, 548 insertions(+), 1 deletion(-) create mode 100644 kernel/client.c create mode 100644 kernel/client.h create mode 100644 kernel/server.c create mode 100644 kernel/server.h diff --git a/kernel/Makefile b/kernel/Makefile index fdddee71..82977931 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c +C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c server.c client.c MODULE := kernel include $(TOPDIR)/Makefile.inc diff --git a/kernel/client.c b/kernel/client.c new file mode 100644 index 00000000..248fbd8e --- /dev/null +++ b/kernel/client.c @@ -0,0 +1,118 @@ +#include "client.h" + +#include "../drivers/net/util.h" + +#define SOCKET_ERROR -1 + +int cli_sendBuffer(Client* cli,void* pBuffer, unsigned int bufferlen) +{ + int iResult; + ClientEventArgs e; + //abfragen ob client existiert!! wichtig + if (cli->sSocket != SOCKET_ERROR) + { + iResult= send(cli->sSocket,(char*)pBuffer,bufferlen,0); + if (cli->_OnWrite != 0) + { + e.dwLen = iResult; + e.pBuffer = pBuffer; + cli->_OnWrite(&e); + } + return iResult; + } + else + return -1; + } + +int cli_ConnectTo(Client* cli,char * pAdresse,unsigned short Port,int webAdresse) +{ + ClientEventArgs e; + cli->sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Einen Socket erstellen + cli->wPort=Port; + cli->adAddr.sin_port = htons(cli->wPort); + + + if (webAdresse) //Fall es sich um eine Internet Adresse Handelt + return -1; + else //Fall es sich um eine LAN Adresse im 127.0.0.1 Stil handelt + cli->adAddr.sin_addr.s_addr = inet_addr(pAdresse); + + if (connect(cli->sSocket,(const struct sockaddr*)&cli->adAddr, sizeof(cli->adAddr))==0) + { + + create_kernel_task(&cli->bThread,cli_WaitForPacket,cli); + + if (cli->_OnConnect != 0) + { + e.dwLen = 0; + e.pBuffer = 0; + cli->_OnConnect(&e); + } + return 0; + } + else + return -1; +}; + +int cli_DisconnectFrom(Client* cli) +{ + shutdown(cli->sSocket,2); + closesocket(cli->sSocket); + cli->sSocket = SOCKET_ERROR; + return 0; +} + +void cli_WaitForPacket(Client* cli) +{ + int iResult=1; + char pTmpBuffer[DEF_BUFFERSIZE+1]; + ClientEventArgs e; + + while (iResult > 0) + { + iResult = recv(cli->sSocket ,pTmpBuffer, DEF_BUFFERSIZE, 0); + if (iResult > 0) + { + pTmpBuffer[iResult]='\0'; + if (cli->_OnRead != 0) + { + e.dwLen = iResult; + e.pBuffer = pTmpBuffer; + cli->_OnRead( &e); + } + } + else //Verbindung geschlossen + { + cli->sSocket=SOCKET_ERROR; + if (cli->_OnDisconnect != 0) + { + e.dwLen = 0; + e.pBuffer = 0; + cli->_OnDisconnect( &e); + } + } + + } +}; + + +int cli_init(Client* cli) +{ + + cli->_OnConnect = 0; + cli->_OnWrite = 0; + cli->_OnRead = 0; + cli->_OnDisconnect = 0; + + cli->adAddr.sin_addr.s_addr = INADDR_ANY; // IP'S die der Client annehmen soll + cli->adAddr.sin_family = AF_INET; // AdressFamilie (TCP/IP) +// adAddr.sin_port = htons(iPort); // Port auf dem der Client erreichbar seien soll + + return NULL; +} + +int cli_destroy(Client* cli) +{ + closesocket(cli->sSocket);; + return NULL; +} diff --git a/kernel/client.h b/kernel/client.h new file mode 100644 index 00000000..aee71c7f --- /dev/null +++ b/kernel/client.h @@ -0,0 +1,56 @@ +#ifndef __CLIENT__ +#define __CLIENT__ + +#define DEF_BUFFERSIZE 8192 // Buffergröße für ein Packet + +#ifndef LWIP_SOCKET +#include +#endif + +#ifndef SOCKET +#define SOCKET int +#endif + + +#include + + +typedef struct _ClientEventArgs +{ + unsigned int dwLen; + void* pBuffer; +} ClientEventArgs; + + +typedef void (*ClientEventHandler)(ClientEventArgs*); + + +typedef struct _Client +{ +//Connection Handling +SOCKET sSocket; + +struct sockaddr_in adAddr; + +//Output Interfacte +unsigned short wPort; + +tid_t bThread; + +// Eventhandling +ClientEventHandler _OnConnect; +ClientEventHandler _OnDisconnect; +ClientEventHandler _OnRead; +ClientEventHandler _OnWrite; +} Client; + +int cli_sendBuffer(Client* cli,void* pBuffer, unsigned int bufferlen); +int cli_ConnectTo(Client* cli,char * pAdresse,unsigned short Port,int webAdresse); +int cli_DisconnectFrom(Client* cli); +void cli_WaitForPacket(Client* cli); + +cli_init(Client* cli); +cli_destroy(Client* cli); + + +#endif diff --git a/kernel/server.c b/kernel/server.c new file mode 100644 index 00000000..e25e12db --- /dev/null +++ b/kernel/server.c @@ -0,0 +1,193 @@ +#include "server.h" + +typedef int UINT_PTR; +#define SOCKET_ERROR -1 + + +int srv_sendBuffer(Server* srv, unsigned int cli,void* pBuffer, unsigned int dwLen) +{ + int result; + ServerEventArgs e; + //abfragen ob client existiert!! wichtig + if (srv->sConnections[cli] != SOCKET_ERROR) + { + result= send(srv->sConnections[cli],(char*)pBuffer,dwLen,0); + if (srv->_OnWrite!=0) + { + e.ClientID = cli; + e.dwLen = dwLen; + e.pBuffer = pBuffer; + srv->_OnWrite(&e); + } + + return result; + } + else + return -1; +} + +void srv_DisconnectClient(Server* srv, unsigned int cli) +{ + ServerEventArgs e; + closesocket(srv->sConnections[cli]); + srv->sConnections[cli]=SOCKET_ERROR; + srv->dwConnections--; + if (srv->_OnDisconnect!=0) + { + e.ClientID = cli; + e.dwLen = 0; + e.pBuffer = 0; + srv->_OnDisconnect(&e); + } + + memset(&srv->ConnectionsAddr[cli],0,sizeof(struct sockaddr_in)); +} +void* srv_WaitForConnection(Server* srv) +{ + SOCKET tmpClient; + struct sockaddr_in tmpAddr; + int tmpAddrLen; + ServerEventArgs e; + ServerThreadArgs* t; + unsigned int i; + + + do + { + if (srv->dwConnections < srv->dwMaximumConnections) + { + tmpAddrLen = sizeof(struct sockaddr); + if ((tmpClient=accept(srv->sSocket,(struct sockaddr*)&tmpAddr,&tmpAddrLen)) != SOCKET_ERROR) + { + for(i=0;idwMaximumConnections;i++) + { + if (srv->sConnections[i] == SOCKET_ERROR) + { + srv->sConnections[i] = tmpClient; + srv->ConnectionsAddr[i] = tmpAddr; + srv->dwConnections++; + + if(srv->_OnConnect!=0) + { + e.ClientID = i; + e.dwLen = 0; + e.pBuffer =0; + srv->_OnConnect(&e); + } + + t = (ServerThreadArgs*) kmalloc(sizeof(ServerThreadArgs)); + t->ID = i; + t->srv = srv; + create_kernel_task(&srv->bThreads[i],srv_WaitForPacket,t); + + break; + } + } + } + } + else + { + } + }while(1); + + return NULL; + +} +void* srv_WaitForPacket(ServerThreadArgs* t) +{ + int iResult=1; + char pTmpBuffer[DEF_BUFFERSIZE+1]; + ServerEventArgs e; + Server* srv = t->srv; + int cli = t->ID; + + while (iResult > 0) + { + iResult = recv(srv->sConnections[cli] ,pTmpBuffer, DEF_BUFFERSIZE, 0); + if (iResult > 0) + { + pTmpBuffer[iResult]='\0'; + if(srv->_OnRead!=0) + { + e.ClientID = cli; + e.dwLen = iResult; + e.pBuffer = pTmpBuffer; + srv->_OnRead(&e); + } + } + else //Verbindung geschlossen + { + closesocket(srv->sConnections[cli]); + srv->sConnections[cli]=SOCKET_ERROR; + if(srv->_OnDisconnect!=0) + { + e.ClientID = cli; + e.dwLen = 0; + e.pBuffer = 0; + srv->_OnDisconnect(&e); + } + memset(&srv->ConnectionsAddr[cli],0,sizeof(struct sockaddr_in)); + srv->dwConnections--; + iResult=-1; + } + } + return NULL; +} + +int server_init(Server* srv, unsigned short Port, unsigned int dwMaxConnections) +{ + struct sockaddr_in tmpAddr; + int tmpAddrLen; + ServerThreadArgs t; + tmpAddrLen = sizeof(struct sockaddr); + + // Unregister Events + srv->_OnConnect=0; + srv->_OnRead=0; + srv->_OnDisconnect=0; + srv->_OnWrite=0; + + // Allocate needed Memory + srv->sConnections=(SOCKET*)kmalloc(sizeof(SOCKET)*srv->dwConnections); + srv->ConnectionsAddr =(struct sockaddr_in*) kmalloc(sizeof(struct sockaddr_in)*dwMaxConnections); + srv->bThreads = (tid_t*)kmalloc(sizeof(tid_t)*dwMaxConnections); + + srv->dwMaximumConnections=dwMaxConnections; + + memset(srv->sConnections,0xFF,sizeof(SOCKET)*dwMaxConnections); + memset(srv->ConnectionsAddr,0x00,sizeof(struct sockaddr_in)*dwMaxConnections); + + srv->dwConnections=0; + srv->wPort = Port; + + srv->adAddr.sin_addr.s_addr = INADDR_ANY; // IP'S die der Server annehmen soll + srv->adAddr.sin_family = AF_INET; // AdressFamilie (TCP/IP) + srv->adAddr.sin_port = htons(srv->wPort); // Port auf dem der server erreichbar seien soll + + srv->sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Einen Socket erstellen + + bind( srv->sSocket,(const struct sockaddr *) &srv->adAddr, sizeof(srv->adAddr)); // Der Server an die Adresse binden; + listen(srv->sSocket,srv->dwMaximumConnections); // Den Server in listenig State versetzen + + create_kernel_task(&srv->bThread_listen,srv_WaitForConnection,srv); +// sConnections[0] = accept(sSocket,(struct sockaddr*)&tmpAddr,&tmpAddrLen); +// t.ID = 0; +// bthread_create(&bThreads[0],NULL,(start_routine) srv_WaitForPacket,&t); +} + +int server_destroy(Server* srv) +{ + unsigned int i; + for (i=0;idwMaximumConnections;i++) + { + if (srv->sConnections[i] != SOCKET_ERROR)closesocket(srv->sConnections[i]); + //bthread_terminate(&srv->bThreads[i],0x00); + } + closesocket(srv->sSocket); + //bthread_terminate(&srv->bThread_listen,0x00); + +// free(srv->sConnections); +// free(srv->ConnectionsAddr); +// free(srv->bThreads); + +} diff --git a/kernel/server.h b/kernel/server.h new file mode 100644 index 00000000..db3934f8 --- /dev/null +++ b/kernel/server.h @@ -0,0 +1,67 @@ +#ifndef __SERVER__ +#define __SERVER__ + + +#ifdef WIN32 +#include +#else +#include +#endif + +#ifndef LWIP_SOCKET +#include +#endif + + +typedef struct _ServerEventArgs +{ + unsigned int ClientID; + unsigned int dwLen; + void* pBuffer; +} ServerEventArgs; + +#define DEF_BUFFERSIZE 8192 + +typedef void (*ServerEventHandler)(ServerEventArgs*); + +#ifndef SOCKET +#define SOCKET int +#endif + + +typedef struct _Server +{ + SOCKET sSocket; + unsigned int* sConnections; + struct sockaddr_in adAddr; + unsigned short wPort; + unsigned int dwConnections; + unsigned int dwMaximumConnections; + + struct sockaddr_in* ConnectionsAddr; + + tid_t bThread_listen; + tid_t* bThreads; + + ServerEventHandler _OnConnect; + ServerEventHandler _OnDisconnect; + ServerEventHandler _OnRead; + ServerEventHandler _OnWrite; +} Server; + +typedef struct _ServerThreadArgs +{ + Server* srv; + unsigned int ID; +} ServerThreadArgs; + + +int srv_sendBuffer(Server* srv,unsigned int cli,void* pBuffer, unsigned int dwLen); +void srv_DisconnectClient(Server* srv,unsigned int cli); +void* srv_WaitForConnection(Server* srv); +void* srv_WaitForPacket(ServerThreadArgs* t); + +int server_init(Server* srv,unsigned short Port, unsigned int dwMaxConnections); +int server_destroy(Server* srv); + +#endif diff --git a/kernel/tests.c b/kernel/tests.c index 5339450a..96f0022a 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -36,6 +36,9 @@ #include #endif +#include "client.h" +#include "server.h" + static sem_t consuming, producing; static mailbox_int32_t mbox; static int val = 0; @@ -145,8 +148,70 @@ __inline int get_core_no(void) } +static int srv_cnt = 0; +void srv_on_read(ServerEventArgs* e) +{ + kprintf("%i:",srv_cnt); + hex_dump(e->dwLen,e->pBuffer); + srv_cnt++; +/* printf("%i:",cnt); + puts(e->pBuffer); + puts("\n"); + cnt++; + */ +} + +void srv_on_disc(ServerEventArgs*e ) +{ + kprintf("connection lost!!!\n"); +} + + void* server_task(void* e) { + + int i = 0; + int tmp1,tmp2; + char msg[7][60] ={"Hello you0 i have muc fun thogh!","Hello you1 here is a little smily for you!","Hello you2 whaaaaaaaaaaaaaaaaaaaaaaaaats uuuuuuuuuuuuuuuuuuuuuuuuuuuuup!","Hello you3! see this? this is fun ufun funfunfunfunf","Hello you4!" + ,"Hello you5! ogogogogoogoggoogogogogogog","Hello you6!AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa"}; + char buff[256]; + + Server srv; + + server_init(&srv,5555,2); + srv._OnRead = srv_on_read; + srv._OnDisconnect = srv_on_disc; + sleep(2); + srv_sendBuffer(&srv,0,"Hello you!",sizeof("Hello you!")); + sleep(1); + +#if 0 + while(1) + { + if (srv_sendBuffer(0,msg[i],sizeof(msg[i]))< 0) + { + kprintf("\nsending failed\n"); + return NULL; + } + i = (++i) % 7; + sleep(1); + } +#endif + tmp1 = get_clock_tick(); + for (i = 0; i < 1024*4*4*4; i++) + { + if (srv_sendBuffer(&srv,0,buff,sizeof(buff))< 0) + kprintf("dicker error!\n"); + kprintf("\r-%d-",i); + // Sleep(10); + } + tmp2 = get_clock_tick(); + + kprintf("send with %f kb/s", ((float)i*sizeof(buff))/(tmp2-tmp1)); + + return NULL; + +#if 0 int sockfd, newsockfd, portno, clilen; char buffer[512]; struct sockaddr_in serv_addr, cli_addr; @@ -234,11 +299,58 @@ void* server_task(void* e) kprintf("Send 1024*64 Bytes in : %d clock ticks",tmp2-tmp1); +#endif return 0; } +static int cli_cnt = 0; +void cli_on_read(ClientEventArgs* e) +{ + kprintf("\r-%d-",cli_cnt); + cli_cnt++; +// printf("%i:",cnt); +// hex_dump(e->dwLen,e->pBuffer); +// cnt++; +/* puts(e->pBuffer); + puts("\n"); + cnt++; +*/ +} + +void cli_on_disc(ClientEventArgs*e ) +{ + kprintf("connection lost!!!\n"); +} + + void* client_task(void* e) { + + Client cli; + char netbuffer[256]; + cli_init(&cli); + cli._OnRead = cli_on_read; + cli._OnDisconnect = cli_on_disc; + sleep(1); + while ( + cli_ConnectTo(&cli,"192.168.0.1",5555,0)); + sleep(1); + cli_sendBuffer(&cli,"Hallo Welt",sizeof("Hallo Welt")); + + while(1) + sleep(2); + + +#if 1 + while(1) + { + cli_sendBuffer(&cli,netbuffer,sizeof(netbuffer)); + sleep(1); + } +#endif + return NULL; + +#if 0 char dir[2048]; int sd; struct sockaddr_in sin; @@ -295,6 +407,7 @@ void* client_task(void* e) // close(sd); +#endif return NULL; }