recv()/send() und \0
-
hmm bei mir nicht:
Ich verwende den Tcp-Server und Client von da:
http://www.cs.binghamton.edu/~nael/cs528/tutorial/und wenn ich in tcp-client.cc die nachricht so verändere:
char msg[80] = "Hello Wo\0rld!";
dann kommt zurück:
8 bytes: Hello Wo
LG
-
Du kannst hier nicht strlen() benutzen, um die Länge des Strings herauszufinden. Strings sind in C schließlich Null-terminiert, also hört strlen() dort auf zu zählen. Die tatsächliche Länge der empfangenen Daten bekommst du als Rückgabewert von recv().
-
Daran hatte ich natürlich auch gedacht.
Ich verwende strlen nicht sondern übergebe die Größe.LG
-
Nimmst du auch auf dem Server kein strlen? Zeig mal ein _minimalen_ Beispiel, dass dein Problem illustriert. Es wird definitiv irgend wie an deinem Code liegen (hast du zB beim Server noch das strlen drin?)
-
Nein eigentlich nicht:
Server:/* stream server: echo what is received from client */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main (int argc, char *argv[]) { int s, t; int recvd; unsigned int sinlen; struct sockaddr_in sin; char msg[80]; if (argc < 2) { printf ("%s port\n", argv[0] ); /* input error: need port no! */ return -1; } //first create a TCP socket if ( (s = socket(AF_INET, SOCK_STREAM, 0 ) ) < 0) { /* create socket*/ perror("socket"); /* socket error */ return -1; } sin.sin_family = AF_INET; /*set protocol family to Internet */ sin.sin_port = htons(atoi(argv[1])); /* set port no. */ sin.sin_addr.s_addr = INADDR_ANY; /* set IP addr to any interface */ //then bind it to my address and specified port num if (bind(s, (struct sockaddr *)&sin, sizeof(sin) ) < 0 ){ perror("bind"); return -1; /* bind error */ } /* server indicates it's ready, max. listen queue is 5 */ if (listen(s, 5)) { perror ("listen"); /* listen error*/ return -1; } sinlen = sizeof(sin); while (1) { /* accepting new connection request from client, socket id for the new connection is returned in t */ if ( (t = accept(s, (struct sockaddr *) &sin, &sinlen) ) < 0 ){ perror("accept "); /* accpet error */ return -1; } printf( "From %s:%d.\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port) ); if ( recvd = recv(t, msg, sizeof(msg),0 ) <0) { /* read message from client */ perror("recv"); /* recv error */ return -1; } printf("Read %s\n",msg); if ( send(t, msg, recvd,0 ) < 0 ) { /* echo message back */ perror("send"); return -1; /* send error */ } /* close connection, clean up sockets */ if (close(t) < 0) { perror("close"); return -1;} } // will never reach below if (close(s) < 0) { perror("close"); return -1;} return 0; }
Client:
/* stream client: send a message to server */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <netdb.h> int main (int argc, char *argv[] ) { int s, n; struct sockaddr_in sin; struct hostent *hptr; char msg[80] = "Hello Wo\0rld!"; if ( argc < 3 ) { printf ( "%s host port\n", argv[0] ); /* input error: need host & port */ return -1; } if ( (s = socket(AF_INET, SOCK_STREAM, 0 ) ) < 0) { /* create socket*/ perror("socket"); /* socket error */ return -1; } sin.sin_family = AF_INET; /*set protocol family to Internet */ sin.sin_port = htons(atoi(argv[2])); /* set port no. */ if ( (hptr = gethostbyname(argv[1]) ) == NULL){ fprintf(stderr, "gethostname error: %s", argv[1]); return -1; } memcpy( &sin.sin_addr, hptr->h_addr, hptr->h_length); if (connect (s, (struct sockaddr *)&sin, sizeof(sin) ) < 0 ){ perror("connect"); return -1; /* connect error */ } if ( send(s, msg, 14,0) < 0 ) { /* send message to server */ perror("write"); return -1; /* write error */ } if ( ( n = recv(s, msg, sizeof(msg),0 ) ) <0) { /* read message from server */ perror("read"); return -1; /* read error */ } printf (" %d bytes: %s\n", n, msg); /* print message to screen */ /* close connection, clean up socket */ if (close(s) < 0) { perror("close"); /* close error */ return -1;} return 0; }
-
if ( recvd = recv(t, msg, sizeof(msg),0 ) <0) {
stimmt natürlcih so nicht. kann es sein, dass es an der ausgabe liegt die nach der 0 abschneidet??
-
Scheint Tatsächlich so zu sein.
mit gdb erhalte ich: `(gdb) print msg$1 = "Hello Wo\000rld!\000\000\000\030v\376\267\001\000\000\000\000\000\000\000\001\000\000\000\250\363...."
`
Wenn mir jetzt noch einer sagen könnte wie ich das trozdem auf die Konsole bringe...
LG
-
fwrite(msg,1,n,stdout)
so evtl?
-
Socketer schrieb:
printf("Read %s\n",msg);
Im Beispiel liegt da der Hund begraben. Das printf mit Format %s gibt einen nullterminierten String aus. Also den Speicherbereich, auf den msg zeigt bis zum ersten 0-Byte.
Probier mal das:
for (i = 0; i < recvd; ++i) putchar(isprint(msg[i]) ? msg[i] : '.'); }
-
tntnet schrieb:
Socketer schrieb:
printf("Read %s\n",msg);
Im Beispiel liegt da der Hund begraben. Das printf mit Format %s gibt einen nullterminierten String aus. Also den Speicherbereich, auf den msg zeigt bis zum ersten 0-Byte.
Probier mal das:
for (i = 0; i < recvd; ++i) putchar(isprint(msg[i]) ? msg[i] : '.'); }
das bringt aber probleme falls das programm die ausgabe in z.b. eine datei umleitet
lg lolo