자유롭게 질의 및 응답을 할 수 있는 게시판입니다. 개발자 여러분의 답변이 큰 도움이 됩니다.
- 제품설치/등록 오류 문의: 설치/등록 Q&A 이용 (제품 구매 고객 한정)
C++ Builder 업데이트 후 IdIcmpClient (ping) 오류
2020.03.06 15:13
본 게시판은 개발자들이 자유롭게 질문과 답변을 공유하는 게시판입니다.
* 따라서 최대한 정중하게 질문을 올려 주세요.
* 질문을 상세히 작성해 주실 수록 좋은 답변이 올라 옵니다.
* 다른 분들도 참고할 수 있도록 결과 댓글 필수(또는 감사 댓글)
(결과 댓글을 달지 않는 경우 다음 질문에 대한 답변이 달리지 않는 불이익이 있을 수 있습니다.)
-----------------------------------------------------------------------------------------------
안녕하세요?
기존 10.3.1에서 사용하던 프로젝트가 10.3.2로 업데이트 후 동작이 안됩니다.
그래서 혹시나 하는 마음으로 10.3.3으로 업데이트 하였으나 여전히 동작이 안되고 있습니다.
일단 다른거는 아직 테스트를 해보지 않았고 IdIcmpClient 부분이 동작이 안됩니다.
프로젝트나 소스 코드는 동일 합니다. 10.3.1로 제작한 exe 파일을 실행하면 잘 동작 됩니다.
10.3.3으로 컴파일 후 실행하면 아래 구문에서 dead를 출력 합니다.
if(AReplyStatus->BytesReceived > 0)
{
}
else
{
Memo1->Lines->Add("dead");
}
IdIcmpClient 설정 부분은 아래(첨부파일)과 같습니다.
댓글 2
-
icj
2020.03.09 11:07
-
happy
2020.03.11 21:44
BytesReceived 로 결과를 판단하는 것은 잘못 된 겁니다.
ICMP 패킷은 Echo 코맨드만 있는 것도 아니고
네트웍 상황이 물리적으로 도달 할 수 없는 경우 라우터가 에러 패킷을 리턴할 수도 있으므로
BytesReceived 로 결과를 판단하는 것은 잘못 된 것임
요청 및 응답 패킷이 8 바이트로 관측되는 것은 ICMP 패킷의 FIXED 파트 헤더의 크기가 8 바이트
크기라서 그런 거고...
Ping() 을 호출할 때... 인수로 아무것도 주지 않으면 0 사이즈의 버퍼가 넘어 가고
인디 내부 코드에서 IP 헤더와 ICMP 헤더 크기를 뺀 나머지 크기를 리턴 된 패킷 사이즈로 보므로
결과적으로 BytesReceived 의 크기가 0이 될 수도 있지요.
따라서 ReplyStatusType 이 rsEcho인가로 판단하는 게 바른 방법이며
될수 있으면 Indy 사용하지 말고, raw socket 모드를 이용해서 IP헤더와 ICMP 패킷 구조를 직접 처리하는
코드를 만들어서 이용하든가, 그게 여의치 않으면 운영체제에서 제공해 주고 있는 ICMP API를
이용하는 게 더 나은 방법 임.
C++ Builder 업데이트 후 IdIcmpClient (ping) 오류
2020.03.06 15:13
본 게시판은 개발자들이 자유롭게 질문과 답변을 공유하는 게시판입니다.
* 따라서 최대한 정중하게 질문을 올려 주세요.
* 질문을 상세히 작성해 주실 수록 좋은 답변이 올라 옵니다.
* 다른 분들도 참고할 수 있도록 결과 댓글 필수(또는 감사 댓글)
(결과 댓글을 달지 않는 경우 다음 질문에 대한 답변이 달리지 않는 불이익이 있을 수 있습니다.)
-----------------------------------------------------------------------------------------------
안녕하세요?
기존 10.3.1에서 사용하던 프로젝트가 10.3.2로 업데이트 후 동작이 안됩니다.
그래서 혹시나 하는 마음으로 10.3.3으로 업데이트 하였으나 여전히 동작이 안되고 있습니다.
일단 다른거는 아직 테스트를 해보지 않았고 IdIcmpClient 부분이 동작이 안됩니다.
프로젝트나 소스 코드는 동일 합니다. 10.3.1로 제작한 exe 파일을 실행하면 잘 동작 됩니다.
10.3.3으로 컴파일 후 실행하면 아래 구문에서 dead를 출력 합니다.
if(AReplyStatus->BytesReceived > 0)
{
}
else
{
Memo1->Lines->Add("dead");
}
IdIcmpClient 설정 부분은 아래(첨부파일)과 같습니다.
댓글 2
-
icj
2020.03.09 11:07
-
happy
2020.03.11 21:44
BytesReceived 로 결과를 판단하는 것은 잘못 된 겁니다.
ICMP 패킷은 Echo 코맨드만 있는 것도 아니고
네트웍 상황이 물리적으로 도달 할 수 없는 경우 라우터가 에러 패킷을 리턴할 수도 있으므로
BytesReceived 로 결과를 판단하는 것은 잘못 된 것임
요청 및 응답 패킷이 8 바이트로 관측되는 것은 ICMP 패킷의 FIXED 파트 헤더의 크기가 8 바이트
크기라서 그런 거고...
Ping() 을 호출할 때... 인수로 아무것도 주지 않으면 0 사이즈의 버퍼가 넘어 가고
인디 내부 코드에서 IP 헤더와 ICMP 헤더 크기를 뺀 나머지 크기를 리턴 된 패킷 사이즈로 보므로
결과적으로 BytesReceived 의 크기가 0이 될 수도 있지요.
따라서 ReplyStatusType 이 rsEcho인가로 판단하는 게 바른 방법이며
될수 있으면 Indy 사용하지 말고, raw socket 모드를 이용해서 IP헤더와 ICMP 패킷 구조를 직접 처리하는
코드를 만들어서 이용하든가, 그게 여의치 않으면 운영체제에서 제공해 주고 있는 ICMP API를
이용하는 게 더 나은 방법 임.
wireshark로 확인한 결과 ping은 정상적으로 나가고 응답도 정상적으로 옵니다.
단, 요청 및 응답 패킷 길이가 8byte네요. 24byte를 요구 했는데.
그리고 AReplyStatus->BytesReceived를 보면 '0'으로 나옵니다.
(AReplyStatus->ReplyStatusType == rsEcho) 는 그나마 검출이 되는 것으로 확인하였습니다.
code insight가 안돼 이 부분도 확인이 상당히 어려웠습니다. 언제쯤 정상화 될지...