file descriptor를 marking 해서 select와 FD_ISSET을 속이는 방법
글쓴이: mandugukbap / 작성시간: 월, 2013/06/10 - 10:59오후
안녕하세요.
아래 여러차례 질문을 드렸습니다만, 마땅한 해결책을 못 찾아서 다시 한 번 다른 방식으로 질문을 드립니다.
간단하게 질문을 요약하자면 제목처럼 "file descriptor를 marking 해서 select와 FD_ISSET을 속이는 방법"입니다.
좀 더 설명을 드리자면. 아래와 같은 구조에서 Socket API를 후킹했습니다. 그래서 read()가 불려질 때마다 모든 데이터를 어플리케이션으로 보내는게 아니라. 데이터의 일부만 올려 보내고 나머지 데이터는 일정 시간 후에 올려 보내야 합니다.
즉,
1) 어플리케이션이 select와 FD_ISSET으로부터 데이터를 감지하고 read() 호출
2) 중간에서 후킹된 read()는 버퍼로부터 100KB를 읽었지만 50KB만 리턴해 주고 나머지 50KB는 임시 버퍼에 담아 둡니다.
3) T 단위시간 후에, 어플리케이션에 데이터를 보내야 하는데
4) 그런데 이미 TCP Buffer가 비워진 상태이므로 어플리케이션은 더 이상 Read()를 호출하려고 하지 않습니다.
(어플리케이션) | (Socket API) | (TCP Buffer)
이럴 때, 해당 커넥션의 socket fd를 마킹해서 어플리케이션의 select()와 FD_ISSET()이 다시 읽기 시도를 하게 하는 트릭이 없을까요?
너무 어려운 질문 드려서 정말 죄송합니다.
Forums:
설계를 잘못하신듯하네요 시스템콜을 그런식으로 고치면
설계를 잘못하신듯하네요
시스템콜을 그런식으로 고치면 안되는 겁니다
차라리..
일단 설계를 왜 저렇게 해야하는지 모르겠네요.. 그래도 꼭 해야한다면
말씀하신것 처럼 데이터의 일부만 줘야하고, 일정 시간 후에 다시 읽기 시도를 하는 구조라면
차라리 시스템콜을 수정하지 마시고, 설계를 바꾸세요
일단 thread 하나가 데이터를 계속 read()로 읽게 하고, 읽은 데이터를 queue에다 쌓도록 합니다.. 이때 큐에 담을 데이터는 님이 원하시는 대로 50KB씩 쪼개서 넣던가.. 하시면 될듯
그리고 실제 데이터를 읽어와서 처리하는 thread는 API의 read()를 호출하는게 아니라 이 queue에서 pop하여 데이터를 하나씩 꺼내도록 하는겁니다. API read()하는 스레드가 50KB 씩 쪼개서 queue에 넣었으면 당연히 순서대로 pop 될것이고.. T 시간 후에 pop 하면 당연히 순차적으로 나오겠죠. 원하시는 구조가 될겁니다
2) 중간에서 후킹된 read()는 버퍼로부터
2) 중간에서 후킹된 read()는 버퍼로부터 100KB를 읽었지만 50KB만 리턴해 주고 나머지 50KB는 임시 버퍼에 담아 둡니다.
이 설명을 보면
my_read()
{
orginal_read()
리턴값 조작
}
이런 순으로 되어 있을듯 한데...
요구사항이 잃혀진 길이에 의존해서 리턴할값을 결정(예, 잃혀진 길이의 절반) 할게 아니고 tcp같이 메시지 바운드리 없는 스트림소켓으로 한정한다면, 리턴값을 조작할게 아니라 원래의 read를 호출하기전에 버퍼크기를 줄여 주면 원래의 read가 그이상 잃지 않을테니까 큰 부작용이 없을것 같은데 말이죠...
답변 감사 드립니다. kid1402님께서 말씀하신
답변 감사 드립니다. kid1402님께서 말씀하신 내용과 비슷한 구조로 프로그래밍을 해 나가고 있습니다. 아무튼, application을 속이는 방법은 없는 것으로 생각하는게 좋겠네요. 다른 분들의 답변도 감사 드립니다.
댓글 달기