metalsvm/kernel/server.c
Carl-Benedikt Krüger 96d938286e server & client test
2011-07-12 13:31:23 +02:00

199 lines
5 KiB
C

#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;i<srv->dwMaximumConnections;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);
if (!srv->sConnections || !srv->ConnectionsAddr || !srv->bThreads)
{
kprintf("low on mem");
return -1;
}
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;i<srv->dwMaximumConnections;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);
}