Если это имеет значение значение, для которого стандарта ++ постепенное увеличение прекращает функционировать, 9,007,199,254,740,992.
Если вы читаете из 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-сокетом это совсем другая история. Эмитент может отправить пакет, содержащий целую строку. Получатель гарантированно получит пакет как единое целое. Если он его получит, UDP, конечно, не так надежен, как TCP.
Псевдокод:
char newline = '\n';
file fd;
initialize(fd);
string line;
char c;
while( newline != (c = readchar(fd)) ) {
line.append(c);
}
Что-то вроде этого.
Вот протестированный, довольно эффективный код:
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);
Использование библиотеки сокетов 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; } }
Библиотека берет на себя всю обработку ошибок.
Найдите библиотеку с помощью Google или воспользуйтесь этой прямой ссылкой: http://www.alhem.net/Sockets/