We have a server !
This commit is contained in:
parent
1842e1cebd
commit
3046f41506
21
Makefile
21
Makefile
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
90
src/server.c
90
src/server.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue