Я пишу себе небольшой серверный демон на C, а основные компоненты, такие как обработка, подключаются, отключаются и получают уже, но проблема с получением по-прежнему сохраняется.
Я использую «recv» для чтения 256 байтов одновременно в массив символов, и, поскольку он может содержать несколько строк данных в виде одного большого блока, мне нужно иметь возможность разделять каждую строку отдельно для обработки.
Это само по себе не было бы проблемой, но из-за возможности того, что строка могла быть обрезана, потому что она больше не помещалась в буфер, я также должен иметь возможность видеть, была ли линия обрезана. Не так уж и плохо, просто проверьте последний символ для \r
или \n
, но что за , если линия была обрезана? Мой код не позволяет легко «просто читать больше данных», потому что я использую select()
для обработки нескольких запросов.
По сути, это моя ситуация:
//This is the chunk of code ran after select(), when a socket
//has readable data
char buf[256] = { 0 };
int nbytes;
if ((nbytes = recv(i, buf, sizeof(buf) - 1, 0)) <= 0)
{
if (nbytes == 0)
{
struct remote_address addr;
get_peername(i, &addr);
do_log("[Socket #%d] %s:%d disconnected", i, addr.ip, addr.port);
}
else
do_log("recv(): %s", strerror(errno));
close(i);
FD_CLR(i, &clients);
}
else
{
buf[sizeof(buf) - 1] = 0;
struct remote_address addr;
get_peername(i, &addr);
do_log("[Socket #%d] %s:%d (%d bytes): %s", i, addr.ip, addr.port, nbytes, buf);
// split "buf" here, and process each line
// but how to be able to get the rest of a possibly cut off line
// in case it did not fit into the 256 byte buffer?
}
Я думал о том, чтобы иметь временную буферную переменную с более высокой областью действия (возможно, malloc()
'd), чтобы сохранить текущий буфер, если он был слишком длинным, чтобы соответствовать сразу, но я всегда чувствую себя плохо из-за введения излишне высокой области переменные, если есть лучшее решение: /
Я ценю любые указатели (, кроме XKCD :)) )!