저는 텍스트 기반 파일을 전송하는 데 사용되는 소켓 코드를 테스트하고 있으며 Unix Network Programming (Chinese Version) 책을 참조하여이 코드를 작성하고 있습니다 . 간단히 아래에 몇 가지 코드를 붙여 넣겠습니다.
내 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이 전송된다고합니다. 맞습니까?
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를 보여주었습니다. 이것은 내가 말한 것과 같이 프로세스가 조기에 종료되었습니다. 이것이 이전 코드가 작동하지 않는 이유입니다. 모든 설명에 감사 드리며, 진행 상황을 더 잘 이해할 수 있도록 도와줍니다.
프로세스 종료는 암시 적으로 close()
모든 파일 / 소켓 설명자입니다. 그리고 이것이 문제입니다. 전송 후 닫으면 수신자 측에서 데이터가 손실 될 수 있습니다 (TCP 스택의 구현에 따라 다름).
서버가 소켓을 닫기 전에 클라이언트가 모든 데이터의 수신을 확인하도록하는 애플리케이션 레벨 프로토콜을 구현해야합니다.
요약하자면 : 애플리케이션 레벨 프로토콜의 일부로 소켓 폐쇄를 사용 하는 것은 신뢰할 수 없습니다 . 이러지 마세요.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다