《TCP/IP 네트워크 프로그래밍》 제5장 - TCP 기반 서버/클라이언트(2)(학습 노트)
10812 단어 필기
제5장 TCP 기반 서버/클라이언트(2)
이 장에서는 TCP에 필요한 이론 지식을 자세히 설명하고 4장 클라이언트 문제 해결 방안도 제시한다.
5.1 메아리 클라이언트의 완벽한 실현
5.1.1 메아리 서버는 문제가 없고 클라이언트만 문제가 있습니까?
문제는 서버에 있지 않고 클라이언트에 있지만 코드만 보면 이해가 안 될 수도 있습니다. 입출력에 같은 함수를 사용했기 때문입니다.먼저 메아리 서버 측의 입출력 관련 코드를 살펴보고 다음은 제4장echo_server.c
의 부분 코드입니다.while((str_len = read(clnt_sock, message, BUF_SIZE)) != 0)
write(clnt_sock, message, str_len);
이어서 4장echo_client.c
코드입니다.write(sock, message, strlen(message));
str_len = read(sock, message, BUF_SIZE - 1);
둘 다read나 write 함수를 순환적으로 호출합니다.실제로 이전의 메아리 클라이언트는 100% 자신이 전송한 데이터를 수신할 것이다. 단지 데이터를 받아들일 때의 단위에 문제가 있을 뿐이다.클라이언트 코드 검토 범위를 확장합니다. 다음 코드는 echo_client.c
입니다.while (1) {
fputs("Input message(Q to quit): ", stdout);
fgets(message, BUF_SIZE, stdin);
....
write(sock, message, strlen(message));
str_len = read(sock, message, BUF_SIZE - 1);
message[str_len] = 0;
printf("Message from server: %s", message);
}
메아리 클라이언트가 전송하는 것은 문자열이며, write 함수를 호출하여 한꺼번에 발송합니다.이후 read 함수를 한 번 호출해 자신이 전송한 문자열을 받아들이기를 기대하는 것이 문제다.(본인은 여기에서 지적해야 할 메아리가 완전하지 않다고 생각한다)
5.1.2 메아리 클라이언트 문제 해결 방법
수신 데이터의 크기를 미리 정할 수 있기 때문에 클라이언트는 크기가 충족될 때까지read 함수를 순환해서 호출할 수 있습니다.
책에서 코드를 참고하여 나의 견해를 좀 말하다
read 함수 세 번째 매개 변수 설정 문제
논리적으로 받은 데이터의 크기는 보내는 크기를 초과하지 않을 것이며 부등식으로 판단하는 것은 문제없지만 사순환할 수 있다.책에서 크기 판단으로 해결하지만 이런 독초가 나오면 초과된 부분의 데이터가 무엇인지 봐야 한다고 생각합니다. 왜냐하면 자신의 코드 논리가 초과되지 않기 때문입니다.
코드는 생략하고 사고방식은 결코 복잡하지 않다.
5.1.3 만약에 메아리 클라이언트가 문제가 아니라면: 응용층 프로토콜 정의
메아리 클라이언트는 수신 데이터의 길이를 미리 알 수 있지만, 이것은 더 많은 상황에서는 불가능하다.만약 수신 데이터의 길이를 예지할 수 없다면 어떻게 데이터를 수발해야 합니까?이때 필요한 것은 응용층 프로토콜의 정의이다.
수발 과정에서 데이터의 경계를 표시하거나 수발 데이터의 크기를 미리 알려주는 규칙(협의)을 정해야 한다.서비스 포트/클라이언트 실현 과정에서 점차적으로 정의된 이러한 규칙 집합은 바로 응용층 프로토콜이다.
계산기 기능을 실현하기 위해 프로그램을 스스로 실현해 보세요.
클라이언트는 계산 내용을 보내야 하고 서비스 측은 계산 결과를 되돌려주며 클라이언트는 계산 결과를 나타낸다.
내 구현 참조 문서op_client.c
와 op_server.c
책과 방법이 다르다.
제 방법은요.mywrite
함수는 매번 두 자리를 먼저 써서 다음에 보내는 데이터의 길이를 표시하고 데이터를 발송한다.myread
함수는 매번 두 자리를 먼저 읽고 다음에 데이터를 수신해야 한다는 길이를 나타낸다.
순수한 c 언어로 표현식의 값을 구하는 것은 너무 번거로워서 가감법을 마음대로 실현하였다.
실행 결과#
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ gcc op_server.c -o opserver.exe
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ ./opserver.exe 9190
Connect client 1
: 5+2+6-1
: 12
#
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ gcc op_client.c -o opclient.exe
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ ./opclient.exe 127.0.0.1 9190
Connected...
:
5+2+6-1
result: 12
5.1.4 계산기 서버/클라이언트 예
대략
5.2 TCP 원리
5.2.1 TCP 소켓의 입출력 버퍼
TCP 소켓의 데이터 송수신은 경계가 없습니다.서버 측에서 write 함수를 한 번 호출하여 40바이트의 데이터를 전송하더라도 클라이언트는 4번의read 함수를 호출하여 매번 10바이트를 읽을 수 있습니다.그러나 서버에서 40바이트를 한꺼번에 전송했는데 클라이언트가 느린 분할 수신을 할 수 있다는 의문도 있다.클라이언트가 10바이트를 받아들인 후 나머지 30바이트는 어디에서 기다립니까?
실제로 write 함수 호출 후 데이터를 즉시 전송하는 것이 아니며,read 함수 호출 후에도 데이터를 즉시 수신하는 것이 아니다.write 함수 호출 순간 데이터는 출력 버퍼로 이동합니다.read 함수 호출 순간 입력 버퍼에서 데이터를 읽습니다.
이러한 입출력 버퍼 특성은 다음과 같이 정리할 수 있습니다.
while((str_len = read(clnt_sock, message, BUF_SIZE)) != 0)
write(clnt_sock, message, str_len);
write(sock, message, strlen(message));
str_len = read(sock, message, BUF_SIZE - 1);
while (1) {
fputs("Input message(Q to quit): ", stdout);
fgets(message, BUF_SIZE, stdin);
....
write(sock, message, strlen(message));
str_len = read(sock, message, BUF_SIZE - 1);
message[str_len] = 0;
printf("Message from server: %s", message);
}
#
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ gcc op_server.c -o opserver.exe
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ ./opserver.exe 9190
Connect client 1
: 5+2+6-1
: 12
#
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ gcc op_client.c -o opclient.exe
wzy@wzypc:~/TCP-IP-NetworkNote/chapter-05$ ./opclient.exe 127.0.0.1 9190
Connected...
:
5+2+6-1
result: 12
클라이언트 입력 버퍼는 50바이트이고 서버 측은 100바이트를 전송했다.
TCP가 데이터 흐름을 제어하므로 이러한 문제가 발생하지 않습니다.TCP에는 슬라이딩 창(Sliding Window) 프로토콜이 있으며 다음과 같이 대화식으로 표시됩니다.
A:안녕하세요,최대 50 바이트 B:네,A:저는 20바이트의 공간을 비웠습니다.최대 70 바이트 B:네
데이터 송수신도 마찬가지이기 때문에 TCP에서 버퍼링 오버플로 데이터가 손실되지 않습니다.
write 함수는 데이터가 출력 버퍼로 이동할 때 TCP가 출력 버퍼에 대한 전송을 보장하기 때문에 write 함수는 데이터 전송이 끝날 때 되돌아옵니다.
5.2.2 TCP 내부 작동 원리 1: 상대방과 소켓 연결
TCP 소켓은 생성에서 제거까지 다음 3단계로 나뉘어 진행됩니다.
세 번의 악수 과정은 자체적으로 을 조회한다.
5.2.2 TCP 내부 작동 원리 2: 상대 호스트와의 데이터 교환
대략
자세한 내용은 TCP/IP 상세 정보 볼륨 1 참조
5.2.3 TCP의 내부 작동 방식 3: 소켓과 연결 끊기
네 번 손을 흔들다
자세한 내용은 TCP/IP 상세 정보 볼륨 1 참조
5.3 Windows 기반 구현
대략
5.4 연습 문제
다음은 저의 이해입니다.
ACK는 다음에 받아야 할 일련 번호의 시작을 나타냅니다. SEQ는 현재 전송된 데이터의 시작 번호입니다.어떤 ACK를 받았는데, 이 ACK 이전의 데이터가 모두 정확하게 발송되었다는 것을 설명한다.ACK 시간 초과를 기다리면 데이터가 손실되면 다시 전송해야 합니다.
TCP 소켓이 write 함수를 호출하면 데이터가 출력 버퍼로 이동합니다.TCP 프로토콜 스택에서 상대방 입력 버퍼로 전송이 완료되었습니다.
read 함수를 호출하여 입력 버퍼에서 데이터를 읽습니다.
슬라이딩 창 프로토콜 때문에 보낼 수 있는 것은 50바이트 밖에 없고, 나머지 20바이트는 상대방의 알림 창 공간이 해당 바이트 번호로 덮어쓸 때까지 버퍼에 저장됩니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
static 간단한 설명static 방법은 일반적으로 정적 방법이라고 부른다. 정적 방법은 어떠한 대상에 의존하지 않고 접근할 수 있기 때문에 정적 방법에 있어this는 없다. 왜냐하면 그 어떠한 대상에도 의존하지 않기 때문이다. 대상이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.