We have a server !

This commit is contained in:
Adrien Bourmault 2021-06-16 19:44:48 +02:00
parent 1842e1cebd
commit 3046f41506
No known key found for this signature in database
GPG Key ID: 6EB408FE0ACEC664
6 changed files with 255 additions and 47 deletions

View File

@ -22,10 +22,12 @@
CCOPTS=-pthread -Wall -g -Os CCOPTS=-pthread -Wall -g -Os
LDFLAGS= -lc -lpthread LDFLAGS= -lc -lpthread
BINDIR=bin BINDIR=bin
INCDIR=include
SRCDIR=src SRCDIR=src
DEBDIR=debian DEBDIR=debian
OBJ= $(BINDIR)/scheduler.o $(BINDIR)/server.o $(BINDIR)/localworker.o \ SERVEROBJ= $(BINDIR)/scheduler.o $(BINDIR)/server.o $(BINDIR)/localworker.o \
$(BINDIR)/centers.o $(BINDIR)/main.o $(BINDIR)/centers.o $(BINDIR)/main.o
CLIOBJ= $(BINDIR)/cli.o
.DEFAULT_GOAL:= all .DEFAULT_GOAL:= all
.PHONY: all clean deb tests install run .PHONY: all clean deb tests install run
@ -40,21 +42,30 @@ $(BINDIR)/tests/centers: $(SRCDIR)/tests/centers.c
# ---- General recipes ------------------------------------------------------- # # ---- General recipes ------------------------------------------------------- #
$(BINDIR)/%.o: $(SRCDIR)/%.c $(BINDIR)/%.o: $(SRCDIR)/%.c $(INCDIR)/%.h $(INCDIR)/base.h
@echo "Compiling $<" @echo "Compiling $<"
@$(CC) $(CCINCLUDES) $(CCOPTS) $(CCFLAGS) -c -o $@ $< @$(CC) $(CCINCLUDES) $(CCOPTS) $(CCFLAGS) -c -o $@ $<
# ---- Main recipe ----------------------------------------------------------- # # ---- Main recipe ----------------------------------------------------------- #
$(BINDIR)/gem-graph-server: $(OBJ) $(BINDIR)/main.o: $(SRCDIR)/main.c $(INCDIR)/base.h
@echo "Compiling $<"
@$(CC) $(CCINCLUDES) $(CCOPTS) $(CCFLAGS) -c -o $@ $<
$(BINDIR)/gem-graph-server: $(SERVEROBJ) $(INCDIR)/base.h
@echo "Building program to $@" @echo "Building program to $@"
@$(CC) -o $@ $(OBJ) $(LDFLAGS) @$(CC) -o $@ $(SERVEROBJ) $(LDFLAGS)
@echo "Success!"
$(BINDIR)/gem-graph-ctl: $(CLIOBJ) $(INCDIR)/base.h
@echo "Building program to $@"
@$(CC) -o $@ $(CLIOBJ) $(LDFLAGS)
@echo "Success!" @echo "Success!"
# ---- Misc recipes ---------------------------------------------------------- # # ---- Misc recipes ---------------------------------------------------------- #
clean: clean:
-rm -f $(SRCDIR)/*.o $(BINDIR)/* $(BINDIR)/tests/* *.deb -rm -f $(SRCDIR)/*.o $(BINDIR)/* $(BINDIR)/tests/* *.deb
all: $(BINDIR)/gem-graph-server all: $(BINDIR)/gem-graph-server $(BINDIR)/gem-graph-ctl
tests: $(TESTS) tests: $(TESTS)

View File

@ -19,14 +19,15 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // // along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=// //=-------------------------------------------------------------------------=//
#include <sys/param.h>
#include <stdbool.h> #include <stdbool.h>
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h>
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/param.h> #include <errno.h>
#include <stdio.h>
#define BASE_H #define BASE_H

24
include/cli.h Normal file
View File

@ -0,0 +1,24 @@
//=-------------------------------------------------------------------------=//
// CLI definition //
// //
// Copyright © 2021 The Gem-graph Project //
// //
// This file is part of gem-graph. //
// //
// This program is free software: you can redistribute it and/or modify //
// it under the terms of the GNU Affero General Public License as //
// published by the Free Software Foundation, either version 3 of the //
// License, or (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU Affero General Public License for more details. //
// //
// You should have received a copy of the GNU Affero General Public License //
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#ifndef BASE_H
#include "../include/base.h"
#endif

View File

@ -42,3 +42,4 @@ static inline void ServerDestroy(Server_t *server)
static inline void ServerWait(Server_t *server) static inline void ServerWait(Server_t *server)
{ {
pthread_join(*server->id, NULL); pthread_join(*server->id, NULL);
}

157
src/cli.c Normal file
View File

@ -0,0 +1,157 @@
//=-------------------------------------------------------------------------=//
// Command line interface management module //
// //
// Copyright © 2021 The Gem-graph Project //
// //
// This file is part of gem-graph. //
// //
// This program is free software: you can redistribute it and/or modify //
// it under the terms of the GNU Affero General Public License as //
// published by the Free Software Foundation, either version 3 of the //
// License, or (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU Affero General Public License for more details. //
// //
// You should have received a copy of the GNU Affero General Public License //
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
//=-------------------------------------------------------------------------=//
#include "../include/base.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERVER_IP_ADDR "127.0.0.1"
// -------------------------------------------------------------------------- //
// Socket init function //
// -------------------------------------------------------------------------- //
static inline int createSocket(void)
{
int socketDescriptor;
//printLog("Create the socket\n");
socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
return socketDescriptor;
}
static inline int connectSocket(int newSocket)
{
int effectiveSocket = -1;
int serverPort = 90190;
struct sockaddr_in remote = {0};
remote.sin_addr.s_addr = inet_addr(SERVER_IP_ADDR);
remote.sin_family = AF_INET;
remote.sin_port = htons(serverPort);
effectiveSocket =
connect(newSocket,
(struct sockaddr*)&remote,
sizeof(struct sockaddr_in)
);
return effectiveSocket;
}
static inline int sendSocket(int effectiveSocket, char *request,
short requestSize)
{
int returnSocket = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if (setsockopt(effectiveSocket,
SOL_SOCKET,SO_SNDTIMEO,
(char *)&tv,sizeof(tv)) < 0) {
printLog("Time Out\n");
return -1;
}
returnSocket = send(effectiveSocket, request, requestSize, 0);
return returnSocket;
}
static inline int receiveSocket(int effectiveSocket, char *serverAnswer,
short receiveSize)
{
int returnSocket = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if (setsockopt(effectiveSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,
sizeof(tv)) < 0) {
printLog("Time Out\n");
return -1;
}
returnSocket = recv(effectiveSocket, serverAnswer, receiveSize, 0);
//printLog("Anwer %s\n", serverAnswer);
return returnSocket;
}
int main(int argc, char **argv)
{
int socketDescriptor, nextSocketDescriptor, readSize;
struct sockaddr_in server;
char clientMessage[255] = {0};
char serverReply[255] = {0};
char *exitCommand = "exit";
while(1) {
printf("\ngem-graph console> ");
fgets(clientMessage, 255, stdin);
clientMessage[strcspn(clientMessage, "\n")] = '\0';
if (strcmp(exitCommand,clientMessage) == 0)
{
close(socketDescriptor);
shutdown(socketDescriptor, 0);
shutdown(socketDescriptor, 1);
shutdown(socketDescriptor, 2);
return 0;
}
//Create socket
socketDescriptor = createSocket();
if(socketDescriptor == -1) {
printLog("Could not create socket\n");
continue;
}
//Connect to remote server
if (connectSocket(socketDescriptor) < 0) {
printLog("Connection failed\n");
continue;
}
//Send data to the server
sendSocket(socketDescriptor, clientMessage, strlen(clientMessage));
//Received the data from the server
readSize = receiveSocket(socketDescriptor, serverReply, 200);
printf("%s\n", serverReply);
memset(serverReply, 0, 255);
close(socketDescriptor);
shutdown(socketDescriptor, 0);
shutdown(socketDescriptor, 1);
shutdown(socketDescriptor, 2);
}
return 0;
}

View File

@ -21,12 +21,8 @@
#include "../include/base.h" #include "../include/base.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h>
static void *serverMain(void *server); static void *serverMain(void *server);
@ -47,49 +43,58 @@ pthread_t *ServerInit(Server_t *scheduler)
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
static inline int createSocket(void) static inline int createSocket(void)
{ {
int hSocket; int newSocket;
printLog("Create the socket\n"); printLog("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0); newSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket; return newSocket;
} }
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
// Soecket binding function // // Soecket binding function //
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
static inline int bindSocket(int hSocket) static inline int bindSocket(int newSocket)
{ {
int iRetval=-1; int effectiveSocket = -1;
int ClientPort = 90190; int clientPort = 90190;
struct sockaddr_in remote= {0}; struct sockaddr_in remote = {0};
/* Internet address family */
// Internet address family
remote.sin_family = AF_INET; remote.sin_family = AF_INET;
/* Any incoming interface */
// Any incoming interface
remote.sin_addr.s_addr = htonl(INADDR_ANY); remote.sin_addr.s_addr = htonl(INADDR_ANY);
remote.sin_port = htons(ClientPort); /* Local port */ remote.sin_port = htons(clientPort); // Local port
iRetval = bind(hSocket,(struct sockaddr *)&remote,sizeof(remote)); effectiveSocket = bind(newSocket,(struct sockaddr*)&remote,sizeof(remote));
return iRetval;
return effectiveSocket;
} }
//
// Commands understood by the server
//
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
// Server main function // // Server main function //
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
static void *serverMain(void *server) static void *serverMain(void *server)
{ {
Server_t *args; Server_t *args;
int socketDescriptor, sock, clientLen, readSize; int socketDescriptor, effectiveSocket, clientLen;
struct sockaddr_in client; struct sockaddr_in client;
char clientMessage[255]= {0}; char clientRequest[255]= {0};
char message[255] = {0}; char serverAnswer[255] = {0};
const char *pMessage = "hello world!\n"; const char *pMessage = "hello";
// Get args // Get args
args = (Server_t*) server; args = (Server_t*) server;
printLog("Server #%lu online\n", *args->id);
//Create socket //Create socket
socketDescriptor = createSocket(); socketDescriptor = createSocket();
if (socketDescriptor) if (socketDescriptor < 0)
{ {
printLog("Could not create socket\n"); printLog("Could not create socket\n");
return NULL; return NULL;
@ -99,12 +104,12 @@ static void *serverMain(void *server)
//Bind //Bind
if( bindSocket(socketDescriptor) < 0) if( bindSocket(socketDescriptor) < 0)
{ {
//print the error message //print the error serverAnswer
printLog("bind failed.\n"); printLog("Socket bind failed\n");
return NULL; return NULL;
} }
printLog("bind done\n"); printLog("Socket bind succeeded\n");
//Listen //Listen
listen(socketDescriptor, 3); listen(socketDescriptor, 3);
@ -114,38 +119,47 @@ static void *serverMain(void *server)
{ {
printLog("Waiting for incoming connections...\n"); printLog("Waiting for incoming connections...\n");
clientLen = sizeof(struct sockaddr_in); clientLen = sizeof(struct sockaddr_in);
//accept connection from an incoming client //accept connection from an incoming client
sock = accept(socketDescriptor,(struct sockaddr *)&client,(socklen_t*)&clientLen); effectiveSocket = accept(socketDescriptor,(struct sockaddr *)&client,(socklen_t*)&clientLen);
if (sock < 0)
if (effectiveSocket < 0)
{ {
printLog("accept failed"); printLog("Acceptation failed\n");
return NULL; return NULL;
} }
printLog("Connection accepted\n"); printLog("Connection accepted\n");
memset(clientMessage, '\0', sizeof clientMessage);
memset(message, '\0', sizeof message); memset(clientRequest, '\0', sizeof(clientRequest));
memset(serverAnswer, '\0', sizeof(serverAnswer));
//Receive a reply from the client //Receive a reply from the client
if( recv(sock, clientMessage, 200, 0) < 0) if (recv(effectiveSocket, clientRequest, 200, 0) < 0)
{ {
printLog("recv failed"); printLog("Reception failed");
break; break;
} }
printLog("Client reply : %s\n",clientMessage); printLog("Client reply : %s\n",clientRequest);
if(strcmp(pMessage,clientMessage)==0) if (strcmp(pMessage,clientRequest) == 0)
{ {
strcpy(message,"Hi there !"); strcpy(serverAnswer,"Hello there.");
} }
else else
{ {
strcpy(message,"Invalid Message !"); strcpy(serverAnswer,"Invalid command");
} }
// Send some data // Send some data
if( send(sock, message, strlen(message), 0) < 0) if (send(effectiveSocket, serverAnswer, strlen(serverAnswer), 0) < 0)
{ {
printLog("Send failed"); printLog("Send failed\n");
return NULL; return NULL;
} }
close(sock);
close(effectiveSocket);
} }
return 0;
printLog("Server #%lu offline\n", *args->id);
return NULL;
} }