你如何循环读取c ++套接字?

时间:2012-05-10 08:35:45

标签: c++ string sockets loops

如何循环读取c ++套接字。

stringstream ss;
while (1) {
    char buf [2];
    ssize_t e = read(fd, buf, 2);

    ss << buf[0];
    ss << buf[1];



    cout << e << endl;
    cout << buf[0] << endl;
    cout << buf[1] << endl;

    if (e <= 0) {
        break;
    }
}
string msg = "";
ss >> msg;

当我telnet并输入hello然后输入测试时,我得到了

2
h
e
2
l
l
2
o

1

它只是在那里等待,没有循环。发生了什么,我怎么读套接字?

如何使用

表示EOF
  1. 远程登录

  2. 写入(fd,buf,bufSize)的上下文中的buf;

3 个答案:

答案 0 :(得分:1)

你是什么意思没有循环?错误更多,按回车键,你会看到更多输出..

如果你完成了,你必须按Ctrl + D来表示输入结束(EOF)。

答案 1 :(得分:1)

  

如何使用

表示EOF      

1)telnet

     

2)写入(fd,buf,bufSize);

的上下文中的buf

首先,你想发出的不是EOF。它是“消息结束”或“您刚刚收到的数据是一个完整的协议数据单元,您现在应该处理它”。答案是,然而你想要,只要双方都同意。

例如,您可以专门保留~字符以标记邮件的结尾。为了表明消息的​​结束,一方发送~。另一方知道,当它收到~时,之前的所有内容都是一条消息,其后的所有内容都是新消息。

您还可以在发送实际消息之前发送消息的长度。您可以在文本后跟零字节或换行。或者您可以将每条消息都排成一行。

你可以这样做,但在你的特定应用程序中最有意义,但实际上你必须这样做。

有两种情况,TCP会为您执行此操作:

1)当一方完全发送并知道另一方不再发送任何数据时,它可以在套接字上使用close。另一方将阅读已发送的其余数据,然后read将返回0

2)当一方不再发送任何数据但另一方可能发送更多数据时,它可以shutdown其连接方。它永远不会发送更多数据。另一方将知道此关闭,如果专门编码,可以继续发送数据,直到它关闭它的一半。然后另一方的read将返回零。 (请注意,如果你对一个非设计的程序执行此操作,它可能会感到困惑,并且没有意识到它仍然可以向您发送数据。)

否则,一切都取决于你。

答案 2 :(得分:1)

TCP数据包是流,而不是文件。由你来决定如何读取流。

一般情况下,如果你在一端写20个字节,你会在一次读取的另一端获得20个字节,除非使用一些常见的tcp / ip选项。

下面有一些假设。一些假设是:

假设所有脚手架代码都存在。

假设我犯了错误并自己调试。

假设处理所有字节顺序问题。

假设您足够聪明,不要将浮点类型发送为二进制文件。

  • 有些程序员选择使用长度前缀数据包并读取长度字节(2),然后读取该长度所代表的字节数,就像这样。

     unsigned char buffer[MAX_CHAR] = "";
     unsigned char length = 0;
     int bytesRead = 0;
    
     read( fd, sizeof( length ), &length );
     // Handle failure from read
     while( bytesRead < length )
     {
         int readRv = read( fd, &buffer[bytesRead], length - bytesRead );
         if( readRv <= 0 )  // 0 usually means socket was closed. -1 is an erro
         {
             // Handle socket error/closed socket
         }
         else if( readRv < length )
         {
             bytesRead += readRv;
         }
         else if( readRv == length )
         {
             bytesRead = readRv;
             break;
         }
     }
    
  • 一些程序员阅读可用内容并查找数据包结束标记

     unsigned char buffer[MAX_CHAR] = "";
     unsigned char length = 0;
     int bytesRead = 0;
     int readRv = read( fd, buffer, sizeof( buffer ) );
     int eopFound = 0;
    
    
     if( (eopFound = findEndOfPacketMarker( buffer )) > 0 )
     {
         // Less than 0 = error.
     }
     else if( eopFound == 0 )
     {
         // No end of packet, must read more bytes here
     }
     else
     {
         // Found an end of packet marker
     }
    
     // Here you deal with bytes that are "over read"
     // Either the
     // 1) packet was bigger than buffer,
     // 2) there were bytes left over after the EOP marker
     // 3) Martians crapped in your code and screwed it all up. :)
    
  • 有些程序员使用固定大小的数据包和数据包类型id

    int packetType;
    
     unsigned char buffer[MAX_CHAR] = "";
     unsigned char length = 0;
     int bytesRead = 0;
    
     read( fd, sizeof( packetType ), &packetType );
     read( fd, getLengthFromPacketType( packetType ), buffer );
    

这应该涵盖大多数事情...... 如果您有更多问题,请在评论中询问@ JimR thingy,以便它显示为我阅读的消息。