6

我有一个 Linux 文件描述符(来自套接字),我想读一行。如何在 C++ 中做到这一点?

4

4 回答 4

3

我您正在从 TCP 套接字读取数据,您无法假设何时会到达行尾。因此你需要这样的东西:

std::string line;
char buf[1024];
int n = 0;
while(n = read(fd, buf, 1024))
{
   const int pos = std::find(buf, buf + n, '\n')
   if(pos != std::string::npos)
   {
       if (pos < 1024-1 && buf[pos + 1] == '\n')
          break;
   }
   line += buf;
}

line += buf;

假设您使用 "\n\n" 作为分隔符。(我没有测试那个代码片段;-))

在 UDP 套接字上,这是另一回事。发射器可能会发送一个包含整行的 paquet。接收器保证接收作为一个单元的包。如果它接收到它,因为 UDP 当然不如 TCP 可靠。

于 2009-10-17T22:25:56.383 回答
2

这是一个经过测试的非常有效的代码:

bool ReadLine (int fd, string* line) {
  // We read-ahead, so we store in static buffer 
  // what we already read, but not yet returned by ReadLine.
  static string buffer; 

  // Do the real reading from fd until buffer has '\n'.
  string::iterator pos;
  while ((pos = find (buffer.begin(), buffer.end(), '\n')) == buffer.end ()) {
    char buf [1025];
    int n = read (fd, buf, 1024);
    if (n == -1) {    // handle errors
      *line = buffer;
      buffer = "";
      return false;
    }
    buf [n] = 0;
    buffer += buf;
  }

  // Split the buffer around '\n' found and return first part.
  *line = string (buffer.begin(), pos);
  buffer = string (pos + 1, buffer.end());
  return true;
}

在读写时设置忽略信号 SIGPIPE 也很有用(并处理如上所示的错误):

signal (SIGPIPE, SIG_IGN);
于 2009-10-18T11:15:16.203 回答
2

伪代码:

char newline = '\n';
file fd;
initialize(fd);
string line;
char c;
while( newline != (c = readchar(fd)) ) {
 line.append(c);
}

类似的东西。

于 2009-10-17T22:23:39.600 回答
0

使用 C++ 套接字库:

类 LineSocket : 公共 TcpSocket
{
上市:
  LineSocket(ISocketHandler& h) : TcpSocket(h) {
    SetLineProtocol(); // 启用在线回调
  }
  void OnLine(const std::string& line) {
    std::cout << "收到的行:" << line << std::endl;
    // 在这里发送回复
    {
      发送(“回复\n”);
    }
  }
};

并使用上面的类:

主函数()
{
  尝试
  {
    套接字处理器 h;
    LineSocket 袜子(h);
    sock.Open("remote.host.com", 端口);
    h.添加(&sock);
    而 (h.GetCount())
    {
      h.选择();
    }
  }
  catch (const Exception&e)
  {
    std::cerr << e.ToString() << std::endl;
  }
}

该库负责所有错误处理。

使用 google 查找库或使用此直接链接:http ://www.alhem.net/Sockets/

于 2009-10-18T07:10:32.560 回答