기본 TCP 연결에서 recv를 사용하고 있습니다. 이것은 내가 읽고있는 [] 바이트입니다. [0 4 9 0]
다음은 recv 호출이며 마지막에는 컨텍스트의 코드입니다.
recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL);
len = ntohs(len);
recv(fd_serv, &tool_id, sizeof (tool_id), MSG_NOSIGNAL);
recv(fd_serv, rdbuf, len, MSG_NOSIGNAL);
gdb에서 디버깅 할 때
len = 4
tool_id = 9
rdbuf = [ 0 4 9 0 ] / [ 0 4 \t 0 ]
어떻게 가능합니까? recv는 len에 대해 처음 2 바이트를 사용하고 tool_id에 대해 다음 바이트 (길이 / 크기와 같은)를 사용하고 rdbuf에 대해 모든 바이트를 사용하는 것처럼 보입니다. 일관성이 있기를 기대합니다. 나는 이것이 부분 바이트 읽기 기능이라고 생각했지만 분명히 틀렸다.
내가 제거하면
recv(fd_serv, &tool_id, sizeof (tool_id), MSG_NOSIGNAL);
코드에서 gdb의 rdbuf를 실행 한 후 처음 2 바이트 변경을 확인합니다.
recv(fd_serv, rdbuf, len, MSG_NOSIGNAL);
그것은된다
[ 9 0 9 0 ] / [ \t 0 \t 0 ]
다시 주석 처리를 해제하면 rdbuf가 다시 정상입니다. 처음에는 읽지 않은 남은 바이트가 복사되었다고 생각했습니다. rdbuf [3]을 5로 설정하고 0을 대체 할 수 있다고 생각했지만 그렇지 않았습니다. 지금은 여기서 무슨 일이 일어나고 있고 왜 여기에서 일관되지 않는지 알 수 없습니다.
저는 Arch Linux x86_64 gdb 7.12.1, gcc 6.3.1을 사용하고 있습니다.
gcc -g -DDEBUG *.c -o client.dbg -lcrypto
문맥
while(TRUE) {
if (fd_serv != -1 && FD_ISSET(fd_serv, &fdsetrd)) {
int n;
uint16_t len;
uint8_t tool_id;
char rdbuf[1024];
errno = 0;
n = recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL | MSG_PEEK);
if (n == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
continue;
else
n = 0;
}
if (n == 0) {
close_connection();
continue;
}
if (len == 0) {
recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL);
continue;
}
len = ntohs(len);
if (len > sizeof (rdbuf)) {
close(fd_serv);
fd_serv = -1;
}
errno = 0;
n = recv(fd_serv, rdbuf, len, MSG_NOSIGNAL | MSG_PEEK);
if (n == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
continue;
else
n = 0;
}
if (n == 0) {
close_connection();
continue;
}
recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL);
len = ntohs(len);
recv(fd_serv, &tool_id, sizeof (tool_id), MSG_NOSIGNAL);
recv(fd_serv, rdbuf, len, MSG_NOSIGNAL);
printf("%d\n", tool_id);
}
}
recv의 반환 값을 확인하면이 경우에 도움이됩니다 (Michael Burrs 의견에 대한 응답으로). 마지막 recv 호출이 모든 바이트를 읽지 않고 남은 바이트 만 읽는다는 결론에 도달했습니다. 이 경우 1 또는 2입니다. 그런 다음 바이트는 시작 부분에 배치되고 이전 값은 덮어 쓰여지지 않습니다. 나는이 조합이 나를 혼란스럽게 생각한다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다