简体   繁体   中英

How to stop receiving data from socket C/C++

the key is that I send 4096 bytes but only 119 bytes aprox. carry useful information.

The 100 bytes ends with \\r\\n\\r\\n so in the client, when I read \\r\\n\\r\\n I want to stop receiving information from that string, and start over.

I don't know if I have to flush, or close the socket, or whatever...

They are sockets TCP.

In the client I do:

 buf details[4096];
 strcpy(details,"1");
 strcat(details,"10/04/12");
 strcat(details,"Kevin Fire");
 strcat(detils,"abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\r\n\r\n");
 nbytes_sent = send(sock,(char *)details,sizeof(details),0);

On the other hand, the server ...

char buf[20];
memset(buf,'\0',20);

while(!end){
 nbytes_read=recv(sclient,(char *)ress,sizeof(ress),0);

 if(strcmp(ress,"1")==0){
   printf("Details: %s (%i)\n",buf,nbytes_read);
   while(strcmp(buf,"\r\n\r\n") != 0){
     nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
     cout.flush();
     printf("Details: %s (%i)\n",buf,nbytes_read);
   }                                     }
   if(strcmp(buf,"\r\n\r\n")==0) printf("The End\n");
   cout.flush();
 }
}

I just want to read a new "ress" and not being retrieving the rest of bytes that are not useful.

Thanks in advance.

If you mean you want to discard rest of data and read a new block you can't do it with TCP because it is stream oriented and do not have a concept of message and have no idea about the rest of message that you want to ignore. if you mean something else please describe it more.

but beside that why you use nbytes_sent = send(sock,(char *)details,sizeof(details),0); when only data until \\r\\n' is important. you can use \\r\\n' is important. you can use nbytes_sent = send(sock,(char *)details,strlen(details),0);` that only send valid data and reduce garbage that you send over network and you don't need to start over in the server??

I'm not sure if I'm following your question entirely, but it appears that you can just set end=true whenever you detect the end of the message you're receiving:

char buf[20];
memset(buf,'\0',20);
while(!end)
{
    nbytes_read=recv(sclient,(char *)ress,sizeof(ress),0);
    if(strcmp(ress,"1")==0)
    {
        printf("Details: %s (%i)\n",buf,nbytes_read);
        while(strcmp(buf,"\r\n\r\n") != 0)
        {
            nbytes_read=recv(sclient,(char *)buf,sizeof(buf),0);
            cout.flush();
            printf("Details: %s (%i)\n",buf,nbytes_read);
        }
    }
    if(strcmp(buf,"\r\n\r\n")==0)
    {
        end = true; // <--- This should do it for you, right?
        printf("The End\n");
    }
    cout.flush();
}

However, if the client is still connected and writing the next message to the socket, then you just need to start reading the next message. So what happens with the client once the message is written? Does it start writing the next message or does it close the socket connection?

In addition: you need to take what's in your buffer and create a message from it. When the current message is done, then consider creating a new message with the contents of the buffer from the next message.

If you design your protocol like HTTP 1.0, where each request opens a new socket, then you close the socket after you've read enough.

Otherwise, you need to keep on reading until you skipped the entire 4096 bytes. The easiest thing to do is to keep on reading till you get 4096 bytes in the first place (you'll need to call recv in a loop), and then parse the contents of the buffer. Then again, you might be better off redesigning your protocol.

My thought would be to just to peek at the first x chars. The 4 chars could be the size of the buffer expected.

So for example if your message is: abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\\r\\n\\r\\n

It's (to use your schematic) 100 bytes, plus the \\r\\n\\r\\n. So it's 100 + 4, so 104.

I would send char(104) at the beginning of your string, as a sentinal value then the string with it right after so it'd appear similar to

char(104)abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\\r\\n\\r\\n

Then use recv's peek_MSG ability to get the first char, make your string size, read only that value and whatever's left get's discarded by a socket flush call you make.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM