#include "ServerProtocol.h"
/* ServerProtocol.cpp
Si veda il file ServerProtocol.h per l'utilizzo delle funzioni
presenti nel modulo */
/* Apre il server su una porta e ritorna un riferimento al socket */
SOCKET OpenServer(int iPort){
WORD sockVersion;
WSADATA wsaData;
int rVal;
/* Il controllo Winsocket in windows richiede l'inizializazione */
sockVersion = MAKEWORD(2,0);
WSAStartup(sockVersion, &wsaData);
/* Crea un socket internet, tcp, che usi il protocollo tcp/ip */
//SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKET s = WSASocket (AF_INET, SOCK_STREAM, 0, 0, 0, 0);
if(s == INVALID_SOCKET){
WSACleanup();
return SERVER_SOCKET_ERROR;
}
/* Riempiamo la struttura */
SOCKADDR_IN sin;
sin.sin_family = PF_INET;
sin.sin_port = htons(iPort);
sin.sin_addr.s_addr = INADDR_ANY;
/* Ok, proviamo a bindare il server */
rVal = bind(s, (LPSOCKADDR)&sin, sizeof(sin));
if(rVal == SOCKET_ERROR){
WSACleanup();
return SERVER_SOCKET_ERROR;
}
/* Mettiti in ascolto per al massimo 1 client */
rVal = listen(s, 1);
if(rVal == SOCKET_ERROR){
WSACleanup();
return SERVER_SOCKET_ERROR;
}
return s;
}
/* Ritorna un oggetto SOCKET alla prima connessione di un client */
SOCKET WaitForClientConnection(SOCKET s){
SOCKET client;
client = accept(s, NULL, NULL);
if(client == INVALID_SOCKET){
WSACleanup();
return SERVER_SOCKET_ERROR;
}
/* TODO: Controllo password */
return client;
}
/* Funzione per ricevere un messaggio dalla socket */
int RecvFrom(SOCKET s, char *pBuffer){
char *tmpBuffer = new char[BUFFER_LENGTH];
int res;
/* Azzera il buffer */
*pBuffer = '\0';
/* Riceve i dati fino a che non viene inviato il carattere '\n' */
do{
res=recv(s,tmpBuffer,sizeof(tmpBuffer),0);
/* Se riceve un pacchetto non valido esce */
if (tmpBuffer[0] == '\0') return SERVER_SOCKET_ERROR;
if (res>=0) *(tmpBuffer+res)='\0';
lstrcat(pBuffer,tmpBuffer);
}while(*(tmpBuffer+res-1) != '\n');
return SERVER_SOCKET_OK;
}
/* Funzione per inviare un messaggio alla socket */
int SendTo(SOCKET s, char *pText){
return send(s, pText,lstrlen(pText),0);
}
/* Funzione per identificare il tipo di comando ricevuto */
char *GetCommand(char *pRecvBuf){
/* Il tipo di comando viene inviato alla testa di ogni pacchetto
quindi estraiamolo */
return GetToken(pRecvBuf,0);
}
/* Funzione per prendere una parte del comando ricevuto dal server */
char *GetToken(char *pRecvBuf, int iTokenNumber){
char *Buffer = new char[BUFFER_LENGTH];
memset(Buffer,'\0',BUFFER_LENGTH);
char *pBuffer = Buffer;
int iTokenCount = 0;
int iTokensCount = TokensCount(pRecvBuf)-1;
/* Scorre il buffer fino ad incontrare il token desiderato... */
while((iTokenCount < iTokenNumber) && (*pRecvBuf)) if (*pRecvBuf++ == SEPARATOR) iTokenCount++;
/* Inserisce nel buffer temporaneo il contenuto del token */
while((*pRecvBuf != SEPARATOR) && (*pRecvBuf)) *pBuffer++ = *pRecvBuf++;
/* Tronca gli ultimi due caratteri se si tratta dell'ultimo token */
if (iTokensCount == iTokenNumber) *(pBuffer-2) = '\0';
return Buffer;
}
// Conta i Token di una stringa
int TokensCount(char *pString) {
char *p = pString;
int iTemp = 1;
while(*p) if (*p++ == SEPARATOR) iTemp++;
return iTemp;
}
/* Funzione per notificare l'avvenuta esecuzione del comando */
void SendCommandNotify(SOCKET s, char *pCommand, bool Success){
char *pBuffer = new char[BUFFER_LENGTH];
/* Aggiunge il valore di OK al comando e invia
i dati alla socket */
wsprintf(pBuffer,"%s%c%s\n\r\0",Success ? OKCOMMAND : NOCOMMAND,SEPARATOR,pCommand);
SendTo(s,pBuffer);
}
/* Funzione per inizializzare una socket client */
SOCKET InitClientSocket(char *pHost, int iPort){
struct sockaddr_in saClient;
struct hostent *pHostinfo;
SOCKET sock;
WORD version;
WSADATA WSAData;
version=MAKEWORD(1,1);
WSAStartup(version, &WSAData);
//Avvia il socket
if ((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR){
return 0;
}
//Risolve il DNS
pHostinfo=gethostbyname(pHost);
if (pHostinfo==NULL){
return 0;
}
//Imposta la connessione con il server...
saClient.sin_family=AF_INET;
saClient.sin_addr=*((struct in_addr *)pHostinfo->h_addr);
saClient.sin_port=htons(iPort);
//Si connette al server...
if (connect(sock,(struct sockaddr *)&saClient, sizeof(saClient))){
return 0;
}
return sock;
}