도와주세요!!
안녕하세요.
소켓 프로그래밍을 하던 중 이상 증상이 발생하여 질문 드립니다.
타겟 보드에 리눅스를 올리고, 간단한 UDP 통신 프로그램을 구현하였습니다.
sendto()를 이용하여 1472바이트를 전송하며, 데이터는 0부터 FF로 순차적으로 채워져 있습니다.
그런데 데이터를 윈도우 wireshark에서 캡쳐하면 아래 그림과 같이 데이터 중간 부분부터 전부 0으로 채워져 있으며,
그 결과 UDP 헤더의 Checksum 에러가 발생하여 해당 데이터를 윈도우에서 실행중인 프로그램이 수신하지 못합니다.
UDP 통신 프로그램은 socket()함수로 소켓을 생성하고, sendto() 함수를 호출하는 형태로 아주 단순합니다.
리눅스 PC에서 프로그램을 실행하면 정상적으로 데이터가 수신되는 것으로 보아, 소스는 이상이 없다고 판단됩니다.
그리고 위 그림에서 Checksum 값 0x9adb는 sendto() 함수로 전달한 데이터에 대한 Checksum이 맞는 것 같습니다.
리눅스 PC에서 전송된 데이터에서는 저 값이 나오거든요.
그래서, 소켓 라이브러리나 좀 더 로우 레벨에서의 문제가 아닌가 생각이 되는데, 제가 리눅스는 처음 작업하는 거라서, 어떻게 접근해야할지 감이 안잡힙니다.
고수분들의 많은 조언을 부탁드립니다.
제 작업 환경은 다음과 같습니다.
- 타겟 보드 : Atmel AT91SAM9263
- 커널 버전 : 3.2.6
- 크로스 컴파일러 : gcc 4.6.3, eabi
- 파일시스템은 BuildRoot를 컴파일하여 사용합니다.
감사합니다.
PING 동작도 유사하게 문제가 있습니다. 즉, -l 옵션으로 데이터 사이즈를 변화시켰을 때 작은 패킷은 정상적으로 응답을 하지만, 큰 패킷은 응답이 없습니다. (UDP 소켓도 작은 패킷은 정상 동작함.)
SSH는 이 문제와 관련이 있는지는 모르겠으나, 접속 후 5~10초가 지났을 때 간헐적으로 멈추는 현상이 있으며, 일정 시간이 지나서 자동으로 접속이 끊깁니다.
반면, FTP는 get / put 모두 정상 동작합니다. 전송 과정에서 재전송이 일어나는지는 모르겠으나, 속도 자체는 1.5~3MB/s 정도 나옵니다. 이 속도가 정상인지는 모르겠네요.
보드를 새로 만드신 것인가요?
새로 만든 보드라면 동일한 드라이버를 레퍼런스 보드에서 돌려보시고 비교해 보는 것도 방법입니다.
네트웍의 속도를 강제로 저속으로 테스트를 해보는 것도 방법입니다.
100 하프, 10메가풀, 10메가 하프 등... 자동설정말고 수동으로 속도를 낮추어 테스트 해보세요
이렇게 해서 문제가 없을 경우 하드웨어적인 문제일 가능성이 큽니다.
레퍼런스 보드라면 업데이트된 드라이버를 확인해 보시거나
최초 제공된 레퍼런스 보드의 소프트웨어를 그대로 올리셔서 동작 유무를 판단하는 것도
판단에 도움을 줍니다.
레퍼런스로 제공된 보드와 코드, 그리고 업데이트된 드라이버에서도 문제가 발생한다면
직접 드라이버를 디버깅해 사용하는 최후의 수단을 사용하셔야겠죠.
원인은 잘못된(?) 패치였습니다.
제가 사용하는 AT91SAM9263은 이더넷 통신시 Tx Underrun이 발생하는 문제가 있으며, 칩 내부의 SRAM을 사용하면 발생 빈도를 줄일 수 있다고 언급되어 있습니다. 이와 관련하여 예전 2.6.x 커널에서는 Tx 버퍼를 내부의 SRAM으로 사용하는 패치가 있었습니다.
현재 제가 사용하는 3.2.6 커널에는 이 패치가 적용되지 않은것 같아서, 해당 패치를 적용하였는데, 이로 인해 위와 같은 문제가 발생하게 되었습니다. 이 패치를 사용하지 않을 경우는 패킷 사이즈에 관계없이 모든 기능이 정상적으로 동작합니다.
3.x 커널용 패치가 별도로 존재하는지는 모르겠으나, 우선은 해당 패치를 제거하여 잘 사용하고 있습니다.
응용프로그램에서의 문제라고 보기는 힘든것 같긴 한데요.
작성하신 응용을 제외하고 ping, ssh, telnet 등은 동작하나요?
그런 네트워크 어플리케이션이 동작하는지부터 확인을 해보는 것도
좋을것 같습니다.