C'è l'ho fatta... In sostanza gli invii si andavano a sovrapporre alle ricezioni, mettemdo una usleep tra un invio e l'altro funziona tutto.
Finite le prove ho iniziato a scrivere il programma finale ha ho dei problemi con le fork (utilizzo nel server 3 processi, uno per creare le partite ogni due connessioni e due dentro la partita per comunicare con i client, e nei client un processo che "disegna" l'area di gioco e uno che comunica col server). Non riesco a capire per quale motivo il programma si blocca...
server:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/times.h>
#define SERVER_PORT 1025
#define MAX_CONN 10
#define MAXX 80
#define MAXY 24
struct pos { //rappresentazione delle coordinate del personaggio
char c;
int x;
int y;
};
int collision (struct pos a, struct pos b){ // verifica se le due posizioni coincidono
if((a.x == b.x) && (a.y == b.y))
return 1;
else
return 0;
}
void startgame (int guardia, int ladro){
struct pos pguardia, pladro;
int pid_ladro, pid_guardia;
pguardia.x=0;
pguardia.y=0;
pguardia.c='#';
pladro.x=MAXX;
pladro.y=MAXY;
pladro.c='$';
send(guardia, "Sei la guardia\n", 15, 0);
send(ladro, "Sei il ladro\n", 13, 0);
usleep(100000);
send(guardia, "#",1,0);
send(ladro, "$",1,0);
usleep(100000);
while ( collision (pguardia, pladro) == 0){
switch (pid_ladro = fork()){
case -1:
perror("Errore nell'esecuzione della fork (ladro)");
exit(4);
case 0:
recv(ladro, &pladro, sizeof(pladro),0);
send(guardia, &pladro, sizeof(pladro),0);
default:
switch (pid_guardia = fork()){
case -1:
perror("Errore nell'esecuzione della fork (guardia)");
exit(4);
case 0:
recv(guardia, &pguardia, sizeof(pguardia),0);
send(ladro, &pguardia, sizeof(pguardia),0);
}
}
kill(pid_ladro, 1);
kill(pid_guardia,1);
}
send(guardia, "Hai vinto!\n", 11, 0);
send(ladro, "Hai perso!\n", 11, 0);
}
int main (int argc, char **argv) {
int sock, fdguardia, fdladro, pid_gioco;
int waiting=0;
char prev='l';
struct sockaddr_in server;
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("chiamata alla system call socket fallita");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(SERVER_PORT);
if (bind(sock, (struct sockaddr *)&server, sizeof server) == -1) {
perror("chiamata alla system call bind fallita");
exit(2);
}
listen(sock, MAX_CONN);
/* gestione delle connessioni dei clienti */
printf("Server avviato correttamente\n");
while (1) {
if (prev == 'l'){
if ((fdguardia = accept(sock, NULL, 0)) < 0) {
perror("accepting connection");
exit(3);
}
prev = 'g';
}
else{
if ((fdladro = accept(sock, NULL, 0)) < 0) {
perror("accepting connection");
exit(3);
}
prev = 'l';
}
waiting++;
printf("ricevuta una connessione\n");
if (waiting >1){
waiting = waiting - 2;
switch (pid_gioco = fork()){
case -1:
perror("Errore nell'esecuzione della fork (startgame)");
exit(4);
case 0:
printf("avvio startgame\n");
startgame(fdguardia, fdladro);
}
} else
send(fdguardia, "Ricerca giocatori in corso...\n", 31, 0);
}
printf("Shutdown server\n");
close (sock);
}
client:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/times.h>
#include <curses.h>
#define SERVER_PORT 1025
#define MAXX 80
#define MAXY 24
#define SU 65
#define GIU 66
#define SINISTRA 68
#define DESTRA 67
struct pos { //rappresentazione delle coordinate del personaggio
char c;
int x;
int y;
};
void aggiorna (struct pos* position, int server){
switch(getch()) {
case SU:
if(position->y>0)
position->y-=1;
break;
case GIU:
if(position->y<MAXY-1)
position->y+=1;
break;
case SINISTRA:
if(position->x>0)
position->x-=1;
break;
case DESTRA:
if(position->x<MAXX-1)
position->x+=1;
break;
}
send(server, &position, sizeof(position), 0);
}
void visualizza (struct pos nuovo, struct pos* vecchio){
mvaddch(vecchio->y, vecchio->x, ' ');
mvaddch(nuovo.y, nuovo.x, nuovo.c);
curs_set(0);
refresh();
vecchio->x=nuovo.x;
vecchio->y=nuovo.y;
}
void startgame (int server){
struct pos miapos, suapos, supmia, supsua;
int pid_gioco, j;
char buf [11];
for (j=0; j<31; j++)
buf[j]='\0';
printf("attesa paramentri\n");
switch (recv(server, &buf, sizeof(buf), 0)){
case -1:
perror("errore di ricezione in startgame");
exit(4);
case '#':
miapos.x=0;
miapos.y=0;
miapos.c='#';
suapos.x=MAXX;
suapos.y=MAXY;
suapos.c='$';
default:
miapos.x=MAXX;
miapos.y=MAXY;
miapos.c='$';
suapos.x=0;
suapos.y=0;
suapos.c='#';
}
printf("ricevuti paramentri\n");
supmia=miapos;
supsua=suapos;
initscr();
noecho();
curs_set(0);
while(1){
switch (pid_gioco = fork()){
case -1:
perror("Errore nell'esecuzione della fork (gioco)");
exit(5);
case 0:
aggiorna(&miapos, server);
visualizza(miapos, &supmia);
default:
if(recv(server, &suapos, sizeof(suapos),0) < 0 ){
perror("Errore ricezione posizione avversario");
exit(4);
}else{
visualizza (suapos, &supsua);
}
}
kill(pid_gioco,1);
}
}
int main () {
int sock, server_len, j;
struct sockaddr_in server;
char buf [31];
//creazione socket
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("chiamata alla system call socket fallita");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(SERVER_PORT);
//connessione al server
server_len = sizeof(server);
if (connect(sock, (struct sockaddr *)&server, server_len) < 0) {
perror("accepting connection");
exit(2);
}
do {
for (j=0; j<31; j++)
buf[j]='\0';
if (recv(sock, &buf, sizeof(buf), 0) < 0) {
perror("rcv error in main");
exit(3);
} else printf("%s\n", buf);
}while(buf[0] != 'S');
printf("avvio startgame\n");
startgame(sock);
}
Ti ringrazio per l'aiuto che mi stai dando comunque!