PDA

View Full Version : [C]problema con send e recv i nremoto


viridovix1
27-08-2005, 23:16
Sistema op suse 9.2 compilatore gcc linguaggio C (stesse versioni su entrambi i PC).
Server e client sono connessi tramite socket con protocollo TCP
Un server invia una matrice(statica) al client che la visualizza su schermo.

1 caso) Client e server girano sulla stessa macchina(cmq viene simulta la connessione xchè si utlizzano i socket).
La visualizzazione da parte del client su video avviene senza problemi.

2 caso) Client e Server girano su macchine differenti.(stesso codice del primo caso) .
IL client nn visualizza la matrice (a volte in parte ,a volte no) e si blocca.

Di seguito riporto il codice del server che inizializza/crea la matrice.
Non fate caso al puntatore che mi serve x mantenre condiviso un flag(posto vuoto/libero) che cmq nn viene utilizzato con la send e recv, quindi nn coinvolge il client.

struct posto
{
unsigned char idPosto[6]; // i caratteri che indicano fila e posto sono
memo qui
int *flag; // flag poso libero/prenotato
};




struct posto cinema [3][3];

void inizializza_cinema(struct posto cine[3][3],int *p)
{

unsigned char i,j,k;
int *pp,*ppp;
pp=p;
ppp=p;
for(i='A';i<='C';i++)
{

for(j='1';j<='3';j++)
{cine[i-'A'][j-'1'].flag=ppp;
ppp=ppp+1;
}
}

k='1';
for(i='A';i<='C';i++)
{

for(j='1';j<='3';j++)
{ *pp=0;
cine[i-'A'][j-'1'].flag=0;
cine[i-'A'][j-'1'].idPosto[0]=' ';
cine[i-'A'][j-'1'].idPosto[1]=i;
cine[i-'A'][j-'1'].idPosto[2]=j;
cine[i-'A'][j-'1'].idPosto[3]=' ';
cine[i-'A'][j-'1'].idPosto[4]='\t';
cine[i-'A'][j-'1'].idPosto[5]='\0';
pp=pp+1;
}
cine[i-'A'][2].idPosto[4]='\n';
}
};


di seguito il codice del server che spedisce la matrice vettore x vettore al client.


void posti_vuoti(struct posto cine[3][3],int *p)
{ int *pp;
pp=p;
unsigned char i,j;
i='A';
j='1';
send(ds_sock_acc,"\n\nI posti contrassegnati con le parentesi quadre sono
già
assegnati!!\n\n",MAX_DIM,0);

for (i='A'; i<='C'; i++)
{

for (j='1'; j<='3'; j++)
{
if (*pp==0)
if (cine[i-'A'][j-'1'].flag==0)
{ cine[i-'A'][j-'1'].idPosto[0]=' ';
cine[i-'A'][j-'1'].idPosto[3]=' ';
send(ds_sock_acc,&cine[i-'A'][j-'1'].idPosto,MAX_DIM,0);

}
else //posto occupato lo stampo tra le parentesi []
{ cine[i-'A'][j-'1'].idPosto[0]='[';
cine[i-'A'][j-'1'].idPosto[3]=']';

send(ds_sock_acc,&cine[i-'A'][j-
'1'].idPosto,MAX_DIM,0);
}
pp=pp+1;
}
}


send (ds_sock_acc,"\nFatto",10,0);
};


ora codice funzione visualizza matrice del client:


void visualizza()
{ char buf[MAX_DIM];
do
{
recv(ds_sock,&buf,MAX_DIM,0);
if (strcmp(buf,"Fatto")!=0)
{
printf("%s",buf);
}
}
while (strcmp(buf,"\nFatto")!=0);
sleep(3);

};


Quindi il client x primo stampa il messaggio :i posti prenotato si trovano tra parentesi []
il primo vettore della matrice A1 A2 A3 e poi si blocca.
Nel caso di processi su macchina locale come detto il client stampa
A1 A2 A3
B1 B2 B3
C1 C2 C3
Quindi il server invia \nFatto che è la condizione di uscita.
Ripeto in locale(simulata xro' la connessione) funziona, da remoto no :(
Non riesco a capire come mai le send e recv nn funzionino a dovere con la connessione in remoto .
Qualcuna spero mi sappia aiutare. C'è un modo x controllare il giusto flusso di dati x garantire la giusta visualizzazione ????????

71104
27-08-2005, 23:34
forse già l'hai notato, ma nel codice del client fai una comparazione con "\nFatto" e una con "Fatto"... non so se è questo che intendevi o è un errore di distrazione...
comunque se non riesci a venirne a capo prova ad usare uno sniffer ;)

viridovix1
28-08-2005, 12:16
NO è u nerrore di distrazione qui , il codice sulla macchina è corretto.
Che intendi con l'usare uno sniffer???
A me serve forzare ogni send e recv a inviare ricevere correttamente la quantità giusta di dati

71104
28-08-2005, 15:45
Che intendi con l'usare uno sniffer??? che hai capito? :D
uno sniffer è un programma che tramite un driver riesce ad intercettare e monitorare tutti i pacchetti che viaggiano sulle tue NIC; usalo per debuggare, per controllare che i pacchetti spediti siano effettivamente quelli che ti aspetti.
uno sniffer gratis c'era ma purtroppo non ne ricordo il nome... è abbastanza famoso cmq...

BlueDragon
28-08-2005, 16:09
che hai capito? :D
uno sniffer è un programma che tramite un driver riesce ad intercettare e monitorare tutti i pacchetti che viaggiano sulle tue NIC; usalo per debuggare, per controllare che i pacchetti spediti siano effettivamente quelli che ti aspetti.
uno sniffer gratis c'era ma purtroppo non ne ricordo il nome... è abbastanza famoso cmq...
Ethereal?
http://www.ethereal.com/

ilsensine
29-08-2005, 07:35
recv(ds_sock,&buf,MAX_DIM,0);
Valori di ritorno, questi sconosciuti...

(hint: MTU, frammentazione...dice nulla? ;) )

GioVesas
29-08-2005, 08:38
Hai provato a fare

int len= recv(ds_sock,&buf,MAX_DIM,0);

printf ("%s\n",len);
ed a vedere quanti byte ricevi ?

viridovix1
29-08-2005, 12:40
Ho appreso che una volta che la send ha spedito i dati, la recv puo nn riceverli tutti in una botta, ma possono sono essere necessarie + recv.
Ho provato con
int dati;

while (dati=(recv(ds_sock,&buf,MAX_DIM,0))>0);
tuttavia cmq mi si blocca lo stesso dopo aver visualizzato la matrice xchè crdo nn riceva correttamente la condizione di uscita da lciclo :(
IN rete ho trovato anche una cosa cosi
while (dati=(recv(ds_sock,&buf,MAX_DIM,0))>0);
{ buf[dati]='\0'; // che dovrebbe specificare la fine della stringa ricevuta

ma cosi mi si blocca senza nemme no visualizzare la matrice.
Ho trovato e provato anche dele funzioni readn e writen ma nn vanno lo stesso

GioVesas
29-08-2005, 12:58
Che la recv non riceva tutti i dati è possibile normalmente per messaggi molto lunghi.
Se ti funziona il for(), può essere che
send (ds_sock_acc,"\nFatto",10,0);
dovrebbe inviare 6 caratteri, ma tu ne fai inviare 10, i cui ultimi 4 sono casuali nello stack.

ilsensine
29-08-2005, 13:19
while (dati=(recv(ds_sock,&buf,MAX_DIM,0))>0);
Così sovrascrivi sempre il buffer; quando sono finiti i dati, se il socket non viene chiuso dal server la recv blocca.