Newsgroup: it.comp.os.linux.development
Titolo: Socket

Buonasera a tutti.
Da pochissimo ho cominciato a studiare i socket ed il loro utilizzo.
Ho fatto un programmino che si mette in ascolto su di una porta e attende
che il client si connetta e dia dei comendi unix per eseguirli ed inviare
l'output al client.
Il problema è che i due programmi fanno tutto, ma solamente una volta.
Vi posto il codice sperando che qualcuno possa aiutarmi.
Grazie a tutti e buona serata.
Ciao
Paolo
//Server
int main(int argc, char **argv)
{
pid_t pid;
int saddr_him_len;
int fd, fd_new, file, nread, opRes;                         // file
descriptors for the network sockets
struct sockaddr_in saddr_me, saddr_him; // addresses of the server socket
descr.
char buf[MAX_STRING], sendd[MAX_STRING], buf_tmp[MAX_STRING+20];
 
        if ((fd=socket(AF_INET,SOCK_STREAM,0)) < 0)
                error("Server: socket not connected ");
 
        saddr_me.sin_family = AF_INET;
        saddr_me.sin_addr.s_addr= htonl(INADDR_ANY); 
        saddr_me.sin_port = htons(PORT); 
 
        if (bind(fd, (struct sockaddr *) &saddr_me, sizeof(saddr_me)) < 0)
                error("Server: bind failure ");
        if (listen(fd,1) < 0 )
                error("Server: listen failure ");
 
        printf("\nServer started\n");
        saddr_him_len= sizeof(saddr_him);       
        while(1){
                if ( (fd_new=accept(fd, (struct sockaddr *) &saddr_him,
&saddr_him_len)) < 0)
                        {error("Server: accept failure ");}
 
                        printf("\nConnection from %s, port %d\n", 
                                inet_ntoa(saddr_him.sin_addr),
                                htons(saddr_him.sin_port));
 
                if ((pid = fork()) < 0){
                        error("fork_error");
                }
                if (pid==0){ 
                for(;;){        
                        //close(fd);
                        memset((char *) buf, 0, sizeof(buf));
                        recv(fd_new, buf, MAX_STRING,0);
                        if((strcmp(buf,"esci"))==0      ){
                                close(fd_new);
                                close(fd);
                                error("ciao");
                                }else{
                        strcat(buf_tmp, buf);   
                        strcat(buf_tmp, " > ./tmpf");
                        printf("\n%s\n", buf_tmp);
                        system(buf_tmp);
                        if((file=open("./tmpf", O_RDWR, 0))==-1){
                                        error("errore nell'open");
                        }else{
                                while(nread=read(file, sendd, MAX_STRING)>0){
                                        //write(fd_new,send, sizeof(send));     
                                        opRes=send(fd_new, sendd, MAX_STRING, 0);
                                        if(opRes == -1){
                                                error("send");
                                                close(fd_new);
                                        }
                                }
                                close(file);
                        }       
                        }
                }
                close(fd_new);
                }
        }
close(fd);
return 0;
}
// Client
int main(int argc, char **argv)
{
int fd, nread;                         // file descriptor for the network
socket
struct sockaddr_in saddr;
char buf[MAX_STRING], sendd[MAX_STRING];
        if ( argc < 2 ) UsageCli();
        if ((fd=socket(AF_INET,SOCK_STREAM,0)) < 0) 
                error("Client: socket not connected ");
 
        saddr.sin_family = AF_INET;
        saddr.sin_addr.s_addr = inet_addr(argv[1]);
        // inet_addr(): deprecated; use inet_aton() instead
        //   Unfortunately Winsock does not support inet_aton()
        saddr.sin_port = htons(PORT);
 
        // requesting connection to server socket (remote host) 
        if (connect(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
                error("Client: error in connect ");
        for(;;){
                        if((strcmp(buf,"esci"))==0){
                                close(fd);
                                error("ciao");
                                }else{  
                printf("\n->");
                scanf("%s",sendd);
                send(fd, sendd, MAX_STRING,0);
                while(nread=recv(fd, buf, MAX_STRING, 0)!=-1){
                        if(fputs(buf,stdout)==EOF){
                                error("fputs_error");
                        }
                }
        }
        }  
        close(fd);
}

 Paolo
Non ho ancora esaminato il codice (non so se potro farlo in seguito),
ma una prima cosa che mi sento di consigliarti e' di settare per
il socker lato server l' opzione SO_REUSEADDR con setsockopt().
Questo perche' se chiudi il server, il socker va in TIMEWAIT e rimane
occupato per circa un minuto e quindi non puoi rilanciare il server.
Ciao.
Roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it