TCP fd를 메모리 버퍼에 맵핑하는 방법
글쓴이: mandugukbap / 작성시간: 금, 2013/06/14 - 6:16오후
리눅스 C 소켓 프로그래밍 환경에서 sock()으로 받은 TCP fd를 메모리 블록 하나에 맵핑하고 싶습니다. 아래처럼 될거라고 생각했는데 되지가 않는군요.
int s = socket(......) void *buffer = (void*) malloc(len); memset(buffer, 0, len); mmap(buffer, size, PROT_READ | PROT_WRITE, MAP_FIXED, s, 0);
Forums:
if (mmap(buffer, size,
의 결과로는 Invalid argument 가 뜨고,
의 결과로는 No such device 가 뜹니다.
매뉴얼을 먼저 보세요 mmap은 그런용도로 만든게
매뉴얼을 먼저 보세요
mmap은 그런용도로 만든게 아닙니다
그리고 파일기술자에 대해 잘못 이해하고 계신듯합니다
먼저 운영체제나 시스템 프로그래밍에 대한 공부를 하시는게 좋을듯 합니다
공부 좀 더 하라는 조언 감사 드립니다. 제 능력으로
공부 좀 더 하라는 조언 감사 드립니다. 제 능력으로 매뉴얼을 읽은 바로는 메모리와 fd를 맵핑하는 용도가 맞는거 같은데, 익명 사용자님께서 아니라고 생각하시면 mmap은 어떤 용도로 사용하는 것인지요?
그리고 질문은, mmap의 사용 용도를 묻는게 아니라 memory block과 socket()으로 할당 받은 fd를 맵핑하는 방법이 있는지 묻는 거였습니다.
...
거의 뻔한 얘기입니다만...
http://stackoverflow.com/questions/4873956/why-is-it-not-possible-to-use-mmap-with-socket-fd-as-an-argument
답변 정말 감사 합니다, 여러분. mmap()을
답변 정말 감사 합니다, 여러분.
mmap()을 그런 용도로 사용하면 안된다는 것은 이제 너무나도 명확하게 알겠으니 더 이상 지적 안 해 주셔도 될 것 같구요.
그런데 제가 원하는 것은 아주 정석의 해법을 찾곘다는 것은 아니구요. 어떻게든 socket()으로 오픈된 기술자를 메모리에 리맵핑(re-mapping)할 수 있는 트릭을 아시는 고수 분이 있으신가 싶어서 글을 올린 것입니다. 아주 지저분해도 상관없으니 조그만 힌트라도 좀 주시면 대단히 감사하겠습니다.
MAPPING_SOCKET_TO_MEMORY(s, myBuffer)를 만들 수 있는 어떤 dirty hack 없을까요?
메모리에 매핑해서 어떤 일을 하고 싶으신 건가요?
메모리에 매핑해서 어떤 일을 하고 싶으신 건가요?
TCP 버퍼의 내용을 임시로 저장해 두는 버퍼를
TCP 버퍼의 내용을 임시로 저장해 두는 버퍼를 만들고 application이 그 버퍼를 읽도록 하기 위함입니다.
즉, application이 커널의 TCP 버퍼로부터 바로 데이터를 받아 가게 하는게 아니고 따로 만들어진 버퍼에서 데이터를 읽어 가도록 하기 위함입니다.
소켓에서 읽어오는 프로세스와 처리하는 프로세스를
소켓에서 읽어오는 프로세스와 처리하는 프로세스를 분리하고, ipc는 message queue를 넣으면 깔끔하게 됩니다.
application A가 소켓에서 데이터를 읽어 분절을 만들어 queue에 넣습니다.
application B는 queue로부터 데이터를 읽어서 처리를 합니다.
------------------------
그리고 걱정되어서 하는 이야기인데, 님이 쓰신 다른 글도 읽어보니 전체적으로
운영체제나 시스템 설계에 대한 이해가 우선시 되어야 할 것 같습니다.
지금 글을 보면 dirty한 구현이든 뭐든 괜찮다는 생각을 가지고 계신데,
그게 언제까지 가능할까요?
그리고 어떤 문제를 일으킬 지 생각해보지는 않으셨나요?
컴퓨터 공학에서 운영체제든, 애플리케이션이든 설계는 계층 구조를 따르게 됩니다.
user level에서 가능한 작업을 죄다 system level로 넣지 않는 것이 바로 그 예입니다.
예를 들어 어떤 데이터베이스 엔진이 성능을 위해서 system call을 수정한다고 가정해 봅시다.
기존 system call의 semantic을 해치지 않으면 다행이겠지만, 유감스럽게도 semantic을 무시한다면?
그렇게 되면 해당 systam call을 사용하는 수 많은 다른 애플리케이션은 어떻게 될까요?
마찬가지로 님이 질문하신 socket에 버퍼를 리맵핑하는 것도
커널이나 시스템 라이브러리를 뜯어 고치면 가능하게 할 수 있습니다.
그런데 왜 그렇게 프로그래밍 해야 하나요?
왜 그렇게 설계해야 하는지요?
충분히 애플리케이션 레벨에서 wrapper 함수를 만들거나
비동기 처리 구조를 만들어서 하면 될 수 있는데
왜 커널까지 손을 대야 하고,
왜 시스템 라이브러리를 수정해야만 하나요?
이전에 질문하셨던 read를 수정하여 select를 속이는 일도 같은 맥락입니다.
read는 유닉스 표준 함수입니다.
표준 함수의 semantic을 해치지 않으면서 개량하는 것은 환영할 일이지만,
표준에 쓰여있는 semantic을 임의로 바꿔버리면 어떤 일이 벌어질까요?
read를 사용하는 다른 프로세스들은 어떻게 작동할 지 상상해 보셨나요?
FD 는 커널 입장에서보면 커널 전역변수입니다.
FD 는 커널 입장에서보면 커널 전역변수입니다. 따라서 이걸 사용자 영역으로 복사하면 커널영역에 있는 주소로 못찾아가죠. 터널 소스를 수정해서 fd 를 복사하는수가 있는지는 잘 모르겠고 일단 이부분은 소켓버퍼 즉 skb 를 복사하는 커널함수 뭐더라...skb_clone 일겁니다 이걸 사용해서 소켓버퍼를 복사하는게 쉬울듯
이 역시 커널영역 내에서 그러니까 커널 소스수정해서 해야 합니다. 사용자 프로그램은 무조건 커널 외부 3GB 메모리블럭에 있으므로 사용자 프로그램으론 방법없습니다.
PACKET_MMAP 참고해보셔요
network sniff할때 사용할수 있다는거 같은데 참고해보십시오 (사용해본적은 없어요)
http://www.mjmwired.net/kernel/Documentation/networking/packet_mmap.txt
댓글 달기