我有一个Linux文件描述符(来自socket),我想读一行。 如何在C ++中实现?
答案 0 :(得分: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。接收器保证接收paquet作为一个单元..如果收到它,因为UDP当然不如TCP可靠。
答案 1 :(得分:2)
伪代码:
char newline = '\n';
file fd;
initialize(fd);
string line;
char c;
while( newline != (c = readchar(fd)) ) {
line.append(c);
}
类似的东西。
答案 2 :(得分: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);
答案 3 :(得分:0)
使用C ++套接字库:
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" ); } } };
并使用上述课程:
int main() { try { SocketHandler h; LineSocket sock(h); sock.Open( "remote.host.com", port ); h.Add(&sock); while (h.GetCount()) { h.Select(); } } catch (const Exception& e) { std::cerr << e.ToString() << std::endl; } }
库负责所有错误处理。
使用谷歌查找图书馆或使用此直接链接:http://www.alhem.net/Sockets/