简体   繁体   English

如何停止从套接字C / C ++接收数据

[英]How to stop receiving data from socket C/C++

the key is that I send 4096 bytes but only 119 bytes aprox. 关键是我发送4096个字节,但仅发送119个字节的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. 100个字节以\\ r \\ n \\ r \\ n结尾,因此在客户端中,当我读取\\ r \\ n \\ r \\ n时,我想停止从该字符串中接收信息,然后重新开始。

I don't know if I have to flush, or close the socket, or whatever... 我不知道我是否必须冲洗或关闭插座,或其他任何东西。

They are sockets TCP. 它们是套接字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. 我只想读取一个新的“ ress”,而不要检索没有用的其余字节。

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. 如果您是想丢弃其余数据并读取一个新块,则无法使用TCP,因为TCP是面向流的,并且没有消息的概念,也不知道要忽略的其余消息。 if you mean something else please describe it more. 如果您有其他意思,请多描述。

but beside that why you use nbytes_sent = send(sock,(char *)details,sizeof(details),0); nbytes_sent = send(sock,(char *)details,sizeof(details),0); ,为什么要使用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之前的数据\\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?? \\r\\n' is important. you can use nbytes_sent = send(sock,(char *)details,strlen(details),0);`仅发送有效数据并减少通过网络发送的垃圾,而无需在服务器上重新开始? ?

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: 我不确定我是否会完全关注您的问题,但是似乎只要您检测到收到的消息结束就可以设置end=true

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. 如果您设计的协议类似于HTTP 1.0,则每个请求都将打开一个新套接字,然后在您阅读足够的内容后关闭该套接字。

Otherwise, you need to keep on reading until you skipped the entire 4096 bytes. 否则,您需要继续阅读,直到跳过整个4096字节。 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. 最简单的方法是继续读取,直到首先获得4096个字节(您需要循环调用recv ),然后解析缓冲区的内容。 Then again, you might be better off redesigning your protocol. 再说一遍,您可能最好重新设计协议。

My thought would be to just to peek at the first x chars. 我的想法是只偷看前x个字符。 The 4 chars could be the size of the buffer expected. 4个字符可能是预期缓冲区的大小。

So for example if your message is: abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\\r\\n\\r\\n 因此,例如,如果您的消息是:abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde \\ r \\ n \\ r \\ n

It's (to use your schematic) 100 bytes, plus the \\r\\n\\r\\n. (使用示意图)为100个字节,外加\\ r \\ n \\ r \\ n。 So it's 100 + 4, so 104. 所以是100 + 4,所以是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),作为一个警戒值,然后紧随其后的是字符串,因此它看起来类似于

char(104)abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde\\r\\n\\r\\n char(104)abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde \\ 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. 然后使用recv的peek_MSG功能获取第一个字符,设置字符串大小,仅读取该值,剩下的任何内容都将由您进行的套接字刷新调用丢弃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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