Я тестирую свой код сокета, который используется для передачи текстового файла, и пишу этот код, ссылаясь на книгу Сетевое программирование Unix (китайская версия).Вкратце я вставлю следующий код:
Моя функция serve_client:
void serve_client(int connfd, const char *filename, size_t filesize)
{
char header[1024];
int fd = open(filename, O_RDONLY, 0);
char *file_mapped;
if (fd == -1)
{
char *not_found = "HTTP/1.1 404 NOT FOUND\r\n";
send(connfd, not_found, strlen(not_found), 0);
}
else
{
sprintf(header, "HTTP/1.1 200 OK\r\n");
sprintf(header, "%sContent-Length: %u\r\n", header, filesize);
sprintf(header, "%sContent-Type: text/plain; charset=utf-8\r\n\r\n", header);
// send http response header
send(connfd, header, strlen(header), 0);
printf("Response headers:\n");
printf("%s", header);
file_mapped = (char *)mmap(0, filesize, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
// send http response body
send(connfd, file_mapped, filesize, 0);
int unmapped = munmap(file_mapped, filesize);
if (unmapped == -1)
{
perror("memory unmapped failed!");
_exit(1);
}
}
}
Есть несколько вопросов, которые я хотел бы задать вам, ребята:
После того, как эта serve_client()
функция успешно вернется, я имею в виду, что по крайней мере данные, которые мне нужны, должны быть полностью скопированы в буфер ядра, чтобы быть отправленными в ближайшем будущем.Я прав насчет этого?
shutdown()
функция вызывается, как показано ниже:
serve_client(connfd, path, st.st_size);
shutdown(connfd, SHUT_WR);
// thread or process ends
Я проверяю советы, упомянутые в этой книге, это говорит о том, что эта функция с этой опцией SHUT_WR
приведет к тому, что данные, оставшиеся в буфере ядра, будут сначала отправлены, а затем окончательный FIN.Это правильно?
Я фиксирую данные, отправленные и полученные с помощью WireShark, как показано на фотографии ниже:
https://i.imgur.com/Xu8gAgh.jpg Я видел, что RST прибыл, до того, как все данные были обнаружены.который не удалось клиенту, например,
wget
или просто доступ в Интернет.Любой совет был бы великолепен.
Теперь я решил эту проблему, выполнив это, позволив клиенту закрыть соединение, и сервер дождется прибытия FIN.Оно работает.Но все же не то, что я хочу.: (
while (1)
{
ssize_t bytes_read = recv(connfd, buf, 1024, 0);
if (bytes_read > 0)
{
continue;
}
else if (bytes_read == 0)
{
close(connfd);
break;
}
else
{
// < 0
// handle error
close(connfd);
break;
}
}
РЕДАКТИРОВАТЬ Извините за недопонимание, вызванное этим вопросом, дамп показал RST, отправленный с сервера, что похоже на то, что мне сказали, что процесс преждевременно завершилсяЭто причина того, что предыдущий код не сработает. Спасибо за все ваши объяснения, которые действительно помогают мне лучше понять прогресс под капотом.