Bozza iniziale del server
This commit is contained in:
parent
d944ded792
commit
e5ab042be3
3 changed files with 223 additions and 0 deletions
77
gamedata.c
Normal file
77
gamedata.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "gamedata.h"
|
||||||
|
|
||||||
|
struct _gamedata {
|
||||||
|
double chf;
|
||||||
|
int bitto;
|
||||||
|
int flour;
|
||||||
|
int pizzoccheri;
|
||||||
|
double chf_unit;
|
||||||
|
};
|
||||||
|
|
||||||
|
gamedata_t* gamedata_new() {
|
||||||
|
gamedata_t* self = (gamedata_t*) malloc(sizeof(gamedata_t));
|
||||||
|
if(errno != 0) {
|
||||||
|
perror("gamedata malloc() creation error: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
self->chf = 0;
|
||||||
|
self->bitto = 500;
|
||||||
|
self->flour = 200;
|
||||||
|
self->pizzoccheri = 0;
|
||||||
|
self->chf_unit = 0.5;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gamedata_delete(gamedata_t* self) {
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gamedata_print_status(gamedata_t *self, FILE* out) {
|
||||||
|
fprintf(out, "OK BITTO %d, FLOUR %d, ", self->bitto, self->flour);
|
||||||
|
fprintf(out, "INVENTORY %d, ", self->pizzoccheri);
|
||||||
|
fprintf(out, "UNIT PRICE %.02f CHF, PROFIT %.02f CHF\n", self->chf_unit, self->chf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Q_BITTO_FOR_PIZZOCCHERO 1
|
||||||
|
#define Q_FLOUR_FOR_PIZZOCCHERO 2
|
||||||
|
bool gamedata_make_pizzoccheri(gamedata_t *self, unsigned int q) {
|
||||||
|
int q_flour = q * Q_FLOUR_FOR_PIZZOCCHERO;
|
||||||
|
int q_bitto = q * Q_BITTO_FOR_PIZZOCCHERO;
|
||||||
|
|
||||||
|
if(self->flour < q_flour || self->bitto < q_bitto) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->flour -= q_flour;
|
||||||
|
self->bitto -= q_bitto;
|
||||||
|
self->pizzoccheri += q;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRICE_BITTO_UNIT 0.5
|
||||||
|
bool gamedata_buy_bitto(gamedata_t *self, unsigned int q) {
|
||||||
|
double price = q * PRICE_BITTO_UNIT;
|
||||||
|
|
||||||
|
if(price > self->chf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->chf -= price;
|
||||||
|
self->bitto += q;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRICE_FLOUR_UNIT 0.5
|
||||||
|
bool gamedata_buy_flour(gamedata_t *self, unsigned int q) {
|
||||||
|
double price = q * PRICE_FLOUR_UNIT;
|
||||||
|
|
||||||
|
if(price > self->chf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->chf -= price;
|
||||||
|
self->flour += q;
|
||||||
|
return true;
|
||||||
|
}
|
17
gamedata.h
Normal file
17
gamedata.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef gamedata
|
||||||
|
#define gamedata
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
typedef struct _gamedata gamedata_t;
|
||||||
|
|
||||||
|
extern gamedata_t* gamedata_new();
|
||||||
|
extern void gamedata_delete();
|
||||||
|
extern bool gamedata_buy_bitto(gamedata_t*, unsigned int);
|
||||||
|
extern bool gamedata_buy_flour(gamedata_t*, unsigned int);
|
||||||
|
extern void gamedata_print_status(gamedata_t*, FILE*);
|
||||||
|
extern bool gamedata_make_pizzoccheri(gamedata_t*, unsigned int);
|
||||||
|
|
||||||
|
#endif
|
129
server.c
Normal file
129
server.c
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "gamedata.h"
|
||||||
|
|
||||||
|
#define SERVER_ADDR htonl(INADDR_ANY)
|
||||||
|
#define MAX_CLIENTS 100
|
||||||
|
#define MAX_COMMAND_LINE_LENGTH 101
|
||||||
|
|
||||||
|
bool prefix(const char *pre, const char *str) {
|
||||||
|
return strncmp(pre, str, strlen(pre)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
|
if(argc < 2) {
|
||||||
|
fprintf(stderr, "Give port number as $1\n");
|
||||||
|
exit(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock_conn_d, sock_data_d;
|
||||||
|
struct sockaddr_in server;
|
||||||
|
|
||||||
|
if((sock_conn_d = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
||||||
|
perror("server socket not created");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&server, 0, sizeof(server)); // zero the memory
|
||||||
|
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_addr.s_addr = SERVER_ADDR;
|
||||||
|
server.sin_port = htons(atoi(argv[1]));
|
||||||
|
|
||||||
|
if(bind(sock_conn_d, (struct sockaddr*)&server, sizeof(server)) == -1) {
|
||||||
|
perror("server socket not bound");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if(listen(sock_conn_d, MAX_CLIENTS) != 0) {
|
||||||
|
perror("cannot listen on socket");
|
||||||
|
close(sock_conn_d);
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("listening...\n");
|
||||||
|
|
||||||
|
struct sockaddr_in client;
|
||||||
|
socklen_t client_len = sizeof(client);
|
||||||
|
sock_data_d = accept(sock_conn_d, (struct sockaddr*)&client, &client_len);
|
||||||
|
|
||||||
|
if(sock_data_d == -1) {
|
||||||
|
perror("cannot accept client");
|
||||||
|
close(sock_conn_d);
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
|
||||||
|
if(pid < 0) {
|
||||||
|
perror("cannot fork for new client");
|
||||||
|
exit(6);
|
||||||
|
}
|
||||||
|
else if(pid == 0) {
|
||||||
|
gamedata_t *curr_data = gamedata_new();
|
||||||
|
|
||||||
|
unsigned char command[MAX_COMMAND_LINE_LENGTH];
|
||||||
|
FILE* in = fdopen(sock_data_d, "r");
|
||||||
|
FILE* out = fdopen(dup(sock_data_d), "w");
|
||||||
|
|
||||||
|
fprintf(out, "OK Connection establshed.\n");
|
||||||
|
fflush(out);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
fgets(command, MAX_COMMAND_LINE_LENGTH, in);
|
||||||
|
|
||||||
|
union {
|
||||||
|
unsigned int u;
|
||||||
|
double d;
|
||||||
|
} arg1;
|
||||||
|
|
||||||
|
if(sscanf(command, "MAKE %u\n", &(arg1.u)) == 1) {
|
||||||
|
bool status = gamedata_make_pizzoccheri(curr_data, arg1.u);
|
||||||
|
fprintf(out, status ? "OK Made.\n" : "KO 1 Insufficient resources.\n");
|
||||||
|
}
|
||||||
|
else if(sscanf(command, "BUY BITTO %u", &(arg1.u)) == 1) {
|
||||||
|
bool status = gamedata_buy_bitto(curr_data, arg1.u);
|
||||||
|
fprintf(out, status ? "OK Purchased.\n" : "KO 2 Insufficient funds\n");
|
||||||
|
}
|
||||||
|
else if(sscanf(command, "BUY FLOUR %u", &(arg1.u)) == 1) {
|
||||||
|
bool status = gamedata_buy_flour(curr_data, arg1.u);
|
||||||
|
fprintf(out, status ? "OK Purchased.\n" : "KO 3 Insufficient funds\n");
|
||||||
|
}
|
||||||
|
else if(prefix("STATUS", command)) {
|
||||||
|
gamedata_print_status(curr_data, out);
|
||||||
|
}
|
||||||
|
else if(prefix("EXIT", command)) {
|
||||||
|
fprintf(out, "OK Closing...\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(out, "KO 255 Syntax error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("closing data socket...\n");
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
fclose(out);
|
||||||
|
|
||||||
|
gamedata_delete(curr_data);
|
||||||
|
|
||||||
|
printf("exiting...\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
// if father process just continue
|
||||||
|
}
|
||||||
|
close(sock_conn_d);
|
||||||
|
exit(0);
|
||||||
|
}
|
Loading…
Reference in a new issue