This is my socket server with fork:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netdb.h>
void do_child(int sock);
int main(int argc, char *argv[]){
if(argc != 2){
perror("./server <numero porta>\n");
exit(1);
}
pid_t pid;
int DescrittoreServer, DescrittoreClient, LunghezzaClient;
int NumPorta = atoi(argv[1]);
struct sockaddr_in serv_addr, cli_addr; /* indirizzo del server e del client */
char Buffer[1024] = {};
DescrittoreServer = socket(AF_INET, SOCK_STREAM, 0);
if(DescrittoreServer < 0){
perror("Errore: creazione socket\n");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */
serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */
serv_addr.sin_port = htons(NumPorta); /* porta */
serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che è un server bisogna associargli l'indirizzo della macchina su cui sta girando */
if(bind(DescrittoreServer, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
perror("Errore di bind\n");
close(DescrittoreServer);
exit(1);
}
listen(DescrittoreServer, 5);
LunghezzaClient = sizeof(cli_addr);
while(1){
DescrittoreClient = accept(DescrittoreServer, (struct sockaddr *) &cli_addr, &LunghezzaClient);
if(DescrittoreClient < 0){
perror("Errore: non è possibile stabilire la connessione\n");
close(DescrittoreServer);
close(DescrittoreClient);
exit(1);
}
pid = fork();
if(pid < 0){
perror("Fork error");
close(DescrittoreServer);
close(DescrittoreClient);
exit(1);
}
if(pid == 0){
close(DescrittoreServer);
do_child(DescrittoreClient);
exit(0);
}
else{
close(DescrittoreClient);
}
}
}
void do_child(int sock){
int n;
char Buffer[1024] = {};
n=read(sock, Buffer, 255);
if(n < 0){
perror("Errore nella lettura dalla socket\n");
exit(1);
}
recv(sock, Buffer, sizeof(Buffer), 0);
printf("Dati ricevuti: %s\n", Buffer);
strcpy(Buffer, "Dati ricevuti correttamente!");
send(sock, Buffer, strlen(Buffer)+1, 0);
}
without fork the server and the client work perfectly but after i’ve introduced the fork i got a strange behaviour from them.
Let’s try to explain it:
Behaviour without fork: the client send the message “Ciao sono il client” and the server give the response “Dati ricevuti correttamente”.
Behaviour with fork: nothing happen until i press “CTRL-C” on the client (i’m on Ubuntu). After i’ve pressed CTRL-C the server print the message from the client.
I don’t understand why the messages sharing are not “on demand” but only when i stop the client or the server 🙁
Your
do_child()codereads from the socket first (and thenrecvagain after this), before writing, whereas your parent code contains no socket write code at all (at least the snippet you provided didn’t) so is it possible that yourdo_child()function is blocking while you read data that is not being sent???