Possible Duplicate:
What is the correct way of reading from a TCP socket in C/C++?
I'm trying to develop a TCP client/server. My problem is, when I try to send the data from cliente I do it in one sent.
But my problem appears when I try to receive the data with a specific structure, I mean, the first 8 bytes set a date, the next 10 a name, and undefined number of bytes set a text (this text ends with /r/n/r/n)
The client sends as follows:
char date[8];
char name[10];
char msg[4096];
strcpy(msg,"12/10/12"); //8 bytes
strcat(msg,"Kevin Fire"); //10 bytes
strcat(msg,"abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\r\n\r\n");
nbytes_sent = send(sock,(char *)msg,sizeof(msg),0);
printf("Bytes_sent: %s -> %i\n",msg,nbytes_sent);
And the server try to parse the data from socket as follows:
char date[8];
char name[10];
char * text;
char buf[1024];
int i=0;
for(i=0; i < 8; i++)
date[i] = '\0';
for(i=0; i < 10; i++)
name[i] = '\0';
nbytes_read=recv(sclient,(char *)date,sizeof(date),0);
if(nbytes_read > 0){
printf("Date: %s (%i)\n",date,nbytes_read);
//cout.flush();
nbytes_read=recv(sclient,(char *)name,sizeof(name),0);
if(nbytes_read > 0){
printf("Name: %s (%i)\n",name,nbytes_read);
//cout.flush();
nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
strcpy(text,buf);
while(nbytes_read > 0){
nbytes_read=recv(sclient(char*)buf,sizeof(buf),0);
strcat(text,buf);
}
}
}
printf("Date: %s. Name: %s. Text: %s\n",date,name,text);
Adding to @hmjd's find:
declared at the var decls is your text pointer...
then later...
Maybe try setting that 'text' pointer to something beside a random stack value will help as well.
Continuing the barrage, though the following will not necessarily blow up, your
date
variable as:on both client and server side The client variable isn't used at all. The server variable, however is:
Problem is, the date you sent is, in fact, 8 chars wide already: "12/10/12". Therefore, even if you firm-up a null terminator on the end of your string, which you should always do regardless (good practice):
you'll be truncating off the last char of your date.
There are other things wrong with this; we've only pointed out a few. Think about sending length-prefixes with each of these data values in the array, with checks or range to ensure you get what you expected.
Finally, spending some time on the business-end of a debugger would probably do you very well, especially on the server side.
Here's a simple "receive all" function:
One (repeated) mistake is:
recv()
does not null terminate. This meansdate
will not have a null terminator ifsizeof(date)
bytes is read. This is a problem when a non-null terminated string is passed as an argument toprintf()
with"%s"
format specifier. If the string is non-null terminated you may see garbage characters appearing after the actual string data. You need to read one less than the target buffer and null terminate or use the format specifier"%*.s"
that does not require null termination:Note you can initialise a
char[]
to all nulls instead of using afor
:or you can use
memset()
.