Вот пример кода, который вы дали в своем вопросе (с удаленным кодом отладки):
//setup socket
//loop and select structure to handle multiple connections
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
[... exception handling here ...]
} else {
char check[] = "newuser";
char fromUser[sizeof check];
strncpy(fromUser,buf, sizeof check);
if ( strcmp(fromUser, check) == 0) {
printf("aha! new user");
}
Этот код неверен; вы потенциально копируете больше байтов из buf [], чем было получено. Это приведет к тому, что вы будете сравнивать с мусором (который может случайно совпадать с вашей строкой "newuser"). И, как говорили другие люди, у вас есть вторая ошибка из-за того, что NUL не завершает одну из ваших строк.
В этом случае я бы использовал memcmp (). Это похоже на strcmp (), но оно принимает параметр длины, а не ожидает строки, заканчивающиеся NUL.
//setup socket
//loop and select structure to handle multiple connections
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
[... exception handling here ...]
} else {
static const char check[] = "newuser";
const size_t check_len = sizeof(check) - 1; // exclude the NUL terminator
if (nbytes >= check_len && memcmp(buf, check, check_len) == 0) {
printf("aha! new user");
}
P.S. Не имеет прямого отношения, но recv () может завершиться ошибкой, вернув -1
с errno==EINTR
. Это не ошибка, вам просто нужно повторить попытку. Обычно это случается так редко, что люди уходят без проверки, пока они не интегрируются с другим кодом, который использует сигналы, и внезапно их код случайно выходит из строя.
В приложении на основе select()
вы также должны установить неблокируемые сокеты, а затем проверить наличие errno==EAGAIN
и вернуться к select()
в этом случае. Это может произойти, если стек TCP / IP получает поврежденный пакет - он думает, что у него есть пакет, поэтому select()
сообщит вам, что он доступен для чтения, только при попытке прочитать его стек TCP / IP выполняет вычисление контрольной суммы и выполняет он должен выбросить данные. Затем он будет либо блокировать (плохо), либо, если он установлен как неблокирующий, он вернет -1
с errno==EAGAIN
.