Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何准确地读一行?_C++_Sockets_File Descriptor - Fatal编程技术网

C++ 如何准确地读一行?

C++ 如何准确地读一行?,c++,sockets,file-descriptor,C++,Sockets,File Descriptor,我有一个Linux文件描述符(来自套接字),我想读一行。 如何在C++中进行? < P> Pseudocode: char newline = '\n'; file fd; initialize(fd); string line; char c; while( newline != (c = readchar(fd)) ) { line.append(c); } 诸如此类。如果您正在从TCP套接字读取数据,则无法假设何时将到达行的末尾。 因此,你需要这样的东西: std::string li

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

< P> Pseudocode:

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

诸如此类。

如果您正在从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;
std::字符串行;
char-buf[1024];
int n=0;
while(n=read(fd,buf,1024))
{
常量int pos=std::find(buf,buf+n,'\n')
if(pos!=std::string::npos)
{
如果(位置<1024-1&&buf[pos+1]='\n')
打破
}
行+=buf;
}
行+=buf;
假设您使用“\n\n”作为分隔符。(我没有测试那个代码片段;-))


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

< P>使用C++ Sokes库:

class LineSocket : public TcpSocket { public: LineSocket(ISocketHandler& h) : TcpSocket(h) { SetLineProtocol(); // enable OnLine callback } void OnLine(const std::string& line) { std::cout << "Received line: " << line << std::endl; // send reply here { Send( "Reply\n" ); } } }; LineSocket类:公共TcpSocket { 公众: 线路插座(ISocketHandler&h):TcpSocket(h){ SetLineProtocol();//启用联机回调 } 联机作废(常量标准::字符串和行){
std::cout这是一个经过测试的非常有效的代码:

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;
}
在读写过程中设置signal SIGPIPE ignorening(以及如上所示处理错误)也很有用:


这通常已经足够好了,但有时我会收到非常长的行,一次读取一个字符的速度太慢。这是关于TCP的,是的。问题是套接字是交互式的。我必须发送一行,然后才能收到几行。我可以识别双换行符“\n\n”的结尾..所以我无法提前读取1024个字符,因为可能没有那么多。man 2 read显示POSIX read有3个参数,所以我不知道您指的是什么read。正如我告诉您的,我没有测试它。我只编写“即时”。代码很容易理解和修改。顺便说一句,我更新了它,以考虑您的行分隔符:“\n\n”Łukasz:“预读”是什么意思?
read()
在任何数据可用时立即返回。只需使用大缓冲区调用
read()
,它不会等待整个缓冲区填满。不,非阻塞读取是即使没有可用数据也会返回的读取。但是,即使在阻塞模式下,read()将在数据到达时立即返回。从手册页中:“成功时,返回读取的字节数(零表示文件结束),文件位置按此数字前进。如果此数字小于请求的字节数,则不是错误;例如,可能会发生这种情况,因为现在实际可用的字节数较少。”
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;
}
signal (SIGPIPE, SIG_IGN);