edge-triggered 모드에서 epoll을 사용하고 비 블로킹 소켓 작업을 수행하는 TCP/IP 서버 애플리케이션을 구현 중입니다. 클라이언트는 epoll없이 간단한 차단 작업을 사용하고 있습니다.C 소켓 원자 비 차단 읽기
"원자 읽기"를 서버 측에서 구현하는 방법을 알지 못합니다. "원자 읽기"에 대한 의미를 설명하려면 간단한 차단 작업이있는이 예제를 참조하십시오.
- 클라이언트와 서버 모두 64K 버퍼를 사용하고 있습니다. (응용 프로그램 수준에서는 커널 수준의 소켓 버퍼를 변경하지 않습니다.)
- 클라이언트는 단일 쓰기 작업으로 12K 데이터를 씁니다.
- 서버에서 읽습니다. 이 경우 버퍼가 동일 할 때 항상 전체 12K를 읽습니다. 그래서 그것의 절반 만 읽을 수는 없습니다. 이것이 제가 "원자"라고 부르는 것입니다.
하지만 epoll 파일의 경우는 + 비 차단이 일어날 수있는 작업 :
- 클라이언트와 서버 모두 64 개 K 버퍼를 사용하고 있습니다. (응용 프로그램 수준에서는 커널 수준의 소켓 버퍼를 변경하지 않습니다.)
- 클라이언트는 단일 쓰기 작업으로 12K 데이터를 씁니다.
- 6K는
- 는 epoll 데이터가 응용 프로그램이 비 블로킹 작업을 사용하여 버퍼에 6K를 읽어 소켓
- 에 도착 응용 프로그램을 알려주는 서버에 도착한다.
- 읽기를 반복하면 EAGAIN/EWOULDBLOCK을 반환합니다.
이 경우 읽기는 "원자 적"이 아닙니다. 데이터가 단일 쓰기 작업으로 작성된 경우 읽기가 전체를 한 조각으로 반환한다는 보장은 없습니다.
데이터가 부분적 일 때를 알 수 있습니까? 한 가지 해결책은 데이터 크기를 항상 처음에 추가하는 것입니다. 그렇지 않으면 항상 연결을 닫고 다시 열 수 있지만 이러한 작업을 수행하지 않으려는 것입니다. 커널이 전체 블로킹 작업에 원 자성을 보장하기 때문에 "패키지"(BTW라고하는 단위는 어떻게됩니까?)가 도착했습니다.
감사합니다.
당신은 일반적으로 * 루프 *의 모든 I/O를 작성하고 자신의 버퍼를 유지해야합니다. –
소켓에서'read' 호출이'0'을 리턴하지 않았다면 이벤트 루프에서 캡처 할 수있는 더 많은 데이터가있을 것으로 기대할 수 있습니다. – jacob
바이너리 전송에서는 전송 시작 및 전송 종료와 같은 구분 기호를 추가하는 것이 일반적입니다. 텍스트 전송에서 구문 검사는 당신의 친구입니다. json 문자열을 전송하는 경우 json 문자열을 구문 분석하여 완료되었는지 여부를 확인할 수 있습니다. – alvits