Buonasera a tutti, sto facendo un po' di esperimenti con la programmazione di rete e in questo momento sto creando un Server, che letta una stringa dalla socket (inviata ovviamente da un client che riceve in input da tastiera tale stringa ), restituisce al client la lunghezza di tale stringa. Per la prima stringa il server funziona correttamente e mi viene stampato il risultato giusto, però ora vorrei porre una piccola modifica: vorrei che il server non interrompa la connessione, ma lo faccia solo quando la socket del client si chiude. Insomma il client può inviare "ciao " e stampa 4 poi riscrive albero e stampare 6 , ma ciò non accade perché dopo la stringa ciao il Server o meglio il figlio del mio processo server termina la connessione e non rimane in attesa di altro. Avete delle idee?
#include<sys/types.h> /* predefined types */
#include<unistd.h> /* include unix standard library */
#include<arpa/inet.h> /* IP addresses conversion utililites */
#include<sys/socket.h> /* socket library */
#include<stdio.h> /* include standard I/O library */
#include <stdlib.h>
#include <string.h>
#define MAXLINE 256
int main (int argc , char *argv[])
{
int list_fd,conn_fd;
int i,nread;
struct sockaddr_in serv_add,client;
char buffer[1024],bufferStr[1024];
socklen_t len;
pid_t pid;
int logging =1;
if ((list_fd=socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("Socket error"); exit(1);}
serv_add.sin_family=AF_INET;
serv_add.sin_addr.s_addr=htonl(INADDR_ANY);
serv_add.sin_port= htons(1024);
if (bind(list_fd,(struct sockaddr *)&serv_add, sizeof(serv_add)) < 0 ){ perror("Bind error "); exit(1);}
if (listen(list_fd,1024) < 0 ){ perror("Listen error "); exit(1);}
while(1)
{
len = sizeof ( client );
if( (conn_fd=accept(list_fd,(struct sockaddr *)&client,&len)) <0 ){ perror("Accept error"); exit(1);}
/* fork to handle connection */
if((pid= fork())<0)
{
perror (" fork error ");
exit ( -1);
}
if(pid==0)
{ /* child */
close ( list_fd );
//[u][b] Credo che io debba modificare il corpo del while ma non riesco a capire come [/b][/u]
//leggo la stringa presente nella socket e la metto in bufferStr
while((nread=read(conn_fd,bufferStr,1024)) != 0){
if (nread < 0) {
perror("Errore in lettura");
return 1;
}
bufferStr[nread]=0;
//Scrivo in bufferStr la lunghezza della stringa presente in bufferStr (sovrascivo il contenuto)
snprintf(bufferStr,sizeof(bufferStr),"%d\n",(int)strlen(bufferStr)-1);
// scrivo nella socket ciò che è presente un bufferStr
write(conn_fd,bufferStr,sizeof(bufferStr));
if(logging)
{
// Stampo i dati di chi mi ha contattato
inet_ntop(AF_INET,&client.sin_addr,buffer,sizeof(buffer));
printf("Request from host %s, port %d\n",buffer,ntohs(client.sin_port));
}
}
close(conn_fd);
exit (0);
}
else
{ /* parent */
close ( conn_fd );
}
}
/* normal exit , never reached */
exit (0);
}
Questo è il client se può servire a qualcuno
#include <sys/types.h> /* predefined types */
#include <unistd.h> /* include unix standard library */
#include <arpa/inet.h> /* IP addresses conversion utiliites */
#include <sys/socket.h> /* socket library */
#include <stdio.h> /* include standard I/O library */
#include <errno.h> /* include error codes */
#include <string.h> /* include erroro strings definitions */
#include <stdlib.h>
#define MAXLINE 256
void ClientEcho(FILE * filein, int socket);
int main(int argc, char *argv[])
{
int sock, i;
int reset = 0;
struct sockaddr_in serv_add;
if ( (sock=socket(AF_INET,SOCK_STREAM,0)) < 0 ) {perror("Socket error "); exit (1);}
serv_add.sin_family=AF_INET;
serv_add.sin_port=htons(1024);
if (inet_pton(AF_INET, argv[1], &serv_add.sin_addr) <0) {perror("PTON error "); exit (1);}
if (connect(sock,(struct sockaddr *)&serv_add,sizeof(serv_add)) <0 ) { perror("Connect error "); exit(1);}
// passo il file da cui prendere l'input cioè dalla tastiera e il fd in cui deve scrivere
ClientEcho(stdin, sock);
/* normal exit */
return 0;
}
void ClientEcho(FILE * filein, int socket)
{
char sendbuff[MAXLINE+1], recvbuff[MAXLINE+1];
int nread, nwrite;
while (1) {
// prendo dallo stadinp e metto in send buff (equivale ad una scanf quindi il processe attende che inserisco qualcosa)
if (fgets(sendbuff, MAXLINE, filein) == NULL) { /* if no input */
close(socket);
return; /* we stopped client */
} else { /* else we have to write to socket */
//scrivo il contenuto di sendbuff nella socket cosi da inviarlo al server
write(socket,sendbuff,MAXLINE);
}
//il server mi restituisce la lunghezza della stringa contenuta in send buff e la inserisco n recvbuff
nread=read(socket,recvbuff,MAXLINE);
if (nread < 0)
{
fprintf(stderr,"read error\n");
exit(1);
}
else if (nread==0)
{
fprintf(stderr,"nread=0\n");
exit(1);
}
// se la lettura è andata a buon fine stampo con la fputs la stringa in recvbuff
recvbuff[nread] = 0;
printf("Numero di caratteri:\n");
if (fputs(recvbuff, stdout) == EOF) {
perror("Errore in scrittura su terminale");
return;
}
}
}