Newsgroup: it.comp.lang.perl
Titolo: client c server perl

Salve a tutti
risolto il problema con il server, adesso c'e' un problema di
passaggio di messaggi nella connessione tra un client C e
il mio server perl.
Il problema e' che il mio server prende il messaggio del client ma e'
sporco.
Cerco di essere piu' chiaro: il client C invia n messaggi al server
che me li mette in un'unica stringa
e per ogni messaggio piu' corto del precedente, ovviamernte mi ritrovo
una serie di caratteri che non
riguardano il messaggio stesso.
Questo e' il mio server
$SocketServer = IO::Socket::INET->new("Proto" => "tcp",
                                                           "LocalPort"
=> "1234",
                                                           "Listen" =>
1) or die "ERROR: $!\n";
while(1)
{
   $client = $SocketServer->accept();
   print "Connesso\n";
   $message = <$client>;
   print "Messaggio ricevuto:\n $message\n";
}
Potete aiutarmi?
Grazie
e3

 e3
Sicuro che il bug non sia nel client C? Hai accesso hai sorgenti C?
Non che in un NG di perl sia pertinente discuterne, ma e' un bug
tipico che si produce in C quello che descrivi.
Se non hai accesso ai sorgenti, verifica con uno sniffer.
Ciao
Roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


Ho accesso al sorgente ed ho anche controllato.
Utilizzando un Server sempre fatto in C, il risultato e' pulito.
Il client C mi manda i messaggi in questa modalità
Ci sono n righe da inviare e le invia una per una, solo che mi sono
dimenticato
di aggiungere un problema che non capisco.
Se alla fine della riga inviata dal client C inserisco un carattere \n
per pulire il buffer
il server perl si blocca
Potrebbe essere queso il problema?
Grazie
e3

 e3
allora... mettiamo a fuoco il problema. Dato che non ho la boccia di
cristallo propongo a intuito alcune verifiche:
Cosa trasmette il client C e come e' congegnato il server C per ricevere
stringhe? Sono stringhe C che terminano con '


OK hai ragione.
Il client C trasmette delle stringhe
 while (cur != NULL) {
sprintf(buff,"str1=%s str2=%s str3=%s str4=%s",str1,str2,str3,str4);
				if (write(intero,buff,512) <512 )   perror("write"),exit(1);
 }
Il server C (classico)
if ( (c_sfd = accept(s_sfd,(struct sockaddr * )  &s_addr , &s_len)) <
0) perror("accept error"),exit(1);
	        while ((n_read=read(c_sfd,buff,MAX)) != 0) {
					printf("\n--%s--\n",buff);
				}
exit(0);
il server Perl
 while(1)
{
   $client = $SocketServer->accept();
   print "Connesso\n";
   $message = <$client>;
   print "Messaggio ricevuto:\n $message\n";
}
Grazie
e3

 if (write(intero,buff,512) <512 )   perror("write"),exit(1);
Quindi il client trasmette blocchi di 512 byte. Molti byte avranno perciň
valori casuali, tranne nel caso improbabile in cui la sprintf produca una
stringa di esattamente 512 byte.
Se il server Perl usa l'operatore '<>', la lettura prosegue fino al primo
terminatore di riga (tipicamente "\n", a meno che non sia stato ridefinito
$/). Pertanto, non stupisce che il server stampi dei valori casuali.
Soluzione: definisci il protocollo in modo rigoroso e implementalo basandoti
sulle specifiche.
Per inciso, il codice che hai mostrato suggerisce che chi l'ha scritto sia
convinto che un blocco trasmesso da un capo con una write venga
necessariamente letto dall'altro capo con una singola read. Non funziona
cosě.
Max

 e3
Ciao
Roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 


Risolto in due modi:
1) Il client C modificato con una serie di strcat che mi creano la
stringa
   e la inviano;
oppure
2)Il server Perl modificato in
  while(sysread($client,$buff,512)){
		print STDOUT $buff;
		}
Secondo voi qul'e la soluzione migliore
e piu' generica possibile
Grazie
e3

 e3
Io credo che il client puo limitarsi a fare la write di strlen(buffer) + 1
per includere anche il carattere 0 di terminazione stringa e lato server
Perl usare comunque la readline di cui <> e' la forma abbreviata, ponendo
pero' il record separator $/ = 'x0';
Lato client C usare strcat e' inutile: basta trasmettere solo la
parte di buffer che interessa.
Cosi da ottenere di trasmettere solo i caratteri utili e non sempre tutto
il blocco, e poter far fare al Perl stesso il lavoro di leggere il record.
Il server Perl cosi' come hai fatto funziona, magari sempre, ma
TEORICAMENTE il layer TCP potrebbe renderti i dati disponibili in piu'
di una sysread (non succende mai per dati di 512 bytes).


 questo articolo e` stato inviato via web dal servizio gratuitohttp://
www.newsland.it/newssegnala
 gli abusi ad 
ab...@newsland.it
Grazie Roberto
era banale ma non ci avevo pensato
il problema era proprio il blocco da 512.
Mi e' bastato inserire una strlen del buffer utilizzato ed e' andato
tutto a meraviglia anche su un altro server attivo su un VAX.
Grazie anche a Max
Saluti a tutti
e3