Recv ()는 바이트를 건너 뜁니다.

user7629762

기본 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);
    }
}
user7629762

recv의 반환 값을 확인하면이 경우에 도움이됩니다 (Michael Burrs 의견에 대한 응답으로). 마지막 recv 호출이 모든 바이트를 읽지 않고 남은 바이트 만 읽는다는 결론에 도달했습니다. 이 경우 1 또는 2입니다. 그런 다음 바이트는 시작 부분에 배치되고 이전 값은 덮어 쓰여지지 않습니다. 나는이 조합이 나를 혼란스럽게 생각한다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

PHP는 계속 조건 평가를 건너 뜁니다.

분류에서Dev

scanf를 건너 뜁니다 (?)

분류에서Dev

pytest-dependency는 종속 테스트를 건너 뜁니다.

분류에서Dev

this.props.history.push ()는 중간 페이지를 건너 뜁니다.

분류에서Dev

CipherInputStream은 길이를 16으로 나눌 수있는 경우 마지막 바이트를 건너 뜁니다.

분류에서Dev

Selenium RC는 요소를 클릭 한 후 onclick () 이벤트를 건너 뜁니다.

분류에서Dev

Selenium RC는 요소를 클릭 한 후 onclick () 이벤트를 건너 뜁니다.

분류에서Dev

SQLSRV는 쿼리를 반환 할 때 행을 건너 뜁니다.

분류에서Dev

Genfromtxt는 #으로 정보를 건너 뜁니다.

분류에서Dev

파일에서 바이트를 읽으려고하는데 탭 문자를 건너 뜁니다.

분류에서Dev

load_file이 null 바이트를 건너 뜁니다.

분류에서Dev

Java FileInputStream.read ()가 바이트를 건너 뜁니다.

분류에서Dev

dnsConfig는 GKE에서 건너 뜁니다.

분류에서Dev

Elasticsearch는 @ -symbol을 건너 뜁니다.

분류에서Dev

ansible : 연결할 수없는 호스트를 자동으로 건너 뜁니다.

분류에서Dev

타이프 스크립트 함수는 문장을 건너 뜁니다.

분류에서Dev

'E'가있는 scanf는 내 전체 루프를 한 번 건너 뜁니다.

분류에서Dev

'E'가있는 scanf는 내 전체 루프를 한 번 건너 뜁니다.

분류에서Dev

2 문자가있는 For-Loops는 많은 아웃 퍼를 건너 뜁니다.

분류에서Dev

SimpleDateFormat :: parse ()를 건너 뜁니다.

분류에서Dev

c # XMLReader는 ReadElementContentAs를 사용한 후 노드를 건너 뜁니다.

분류에서Dev

스칼라를 던지는 대신 잘못된 요소를 건너 뜁니다.

분류에서Dev

BufferedReader는 테스트 / 퀴즈에서 질문을 건너 뜁니다.

분류에서Dev

잠금 스크립트는 일부 명령을 건너 뜁니다.

분류에서Dev

일일 합계를 계산하는 SQL 쿼리가 일을 건너 뜁니다.

분류에서Dev

XamlWriter가 ResourceDictionary를 저장하는 동안 "x : Name"특성을 건너 뜁니다.

분류에서Dev

Highcharts는 일련의 제공되지 않은 단계를 건너 뜁니다.

분류에서Dev

PHP json_decode는 소스 JSON의 일부를 건너 뜁니다.

분류에서Dev

uniq는 처음 N 개의 문자 / 필드를 건너 뜁니다.

Related 관련 기사

  1. 1

    PHP는 계속 조건 평가를 건너 뜁니다.

  2. 2

    scanf를 건너 뜁니다 (?)

  3. 3

    pytest-dependency는 종속 테스트를 건너 뜁니다.

  4. 4

    this.props.history.push ()는 중간 페이지를 건너 뜁니다.

  5. 5

    CipherInputStream은 길이를 16으로 나눌 수있는 경우 마지막 바이트를 건너 뜁니다.

  6. 6

    Selenium RC는 요소를 클릭 한 후 onclick () 이벤트를 건너 뜁니다.

  7. 7

    Selenium RC는 요소를 클릭 한 후 onclick () 이벤트를 건너 뜁니다.

  8. 8

    SQLSRV는 쿼리를 반환 할 때 행을 건너 뜁니다.

  9. 9

    Genfromtxt는 #으로 정보를 건너 뜁니다.

  10. 10

    파일에서 바이트를 읽으려고하는데 탭 문자를 건너 뜁니다.

  11. 11

    load_file이 null 바이트를 건너 뜁니다.

  12. 12

    Java FileInputStream.read ()가 바이트를 건너 뜁니다.

  13. 13

    dnsConfig는 GKE에서 건너 뜁니다.

  14. 14

    Elasticsearch는 @ -symbol을 건너 뜁니다.

  15. 15

    ansible : 연결할 수없는 호스트를 자동으로 건너 뜁니다.

  16. 16

    타이프 스크립트 함수는 문장을 건너 뜁니다.

  17. 17

    'E'가있는 scanf는 내 전체 루프를 한 번 건너 뜁니다.

  18. 18

    'E'가있는 scanf는 내 전체 루프를 한 번 건너 뜁니다.

  19. 19

    2 문자가있는 For-Loops는 많은 아웃 퍼를 건너 뜁니다.

  20. 20

    SimpleDateFormat :: parse ()를 건너 뜁니다.

  21. 21

    c # XMLReader는 ReadElementContentAs를 사용한 후 노드를 건너 뜁니다.

  22. 22

    스칼라를 던지는 대신 잘못된 요소를 건너 뜁니다.

  23. 23

    BufferedReader는 테스트 / 퀴즈에서 질문을 건너 뜁니다.

  24. 24

    잠금 스크립트는 일부 명령을 건너 뜁니다.

  25. 25

    일일 합계를 계산하는 SQL 쿼리가 일을 건너 뜁니다.

  26. 26

    XamlWriter가 ResourceDictionary를 저장하는 동안 "x : Name"특성을 건너 뜁니다.

  27. 27

    Highcharts는 일련의 제공되지 않은 단계를 건너 뜁니다.

  28. 28

    PHP json_decode는 소스 JSON의 일부를 건너 뜁니다.

  29. 29

    uniq는 처음 N 개의 문자 / 필드를 건너 뜁니다.

뜨겁다태그

보관