select 함수를 쓰셔야 겠네요. select는 연결이 되었거나 실패했을 때 리턴합니다.
그리고 어느쪽도 아닐 때(접속 응답을 대기중일 때)도 타임아웃을 지정해서 그냥 리턴하게 할 수도 있습니다.
한가지 더 말씀 드리면 TCP/IP의 특성상 랜선을 뽑는다고 해서
바로 접속이 실패하는 것은 아닙니다. 다시 랜선을 연결하면
아무일 없었던 듯이 성공하기도 하니까요.
그만큼 연결 상태의 변화에 유연하게 대처하는 것이 TCP/IP입니다.
그 덕뿐에 랜선이 뽑힌 것을 어플리케이션이 알 수도 없는 것이지요.
접속의 실패는 상대 호스트가 명시적으로 거부했을 때는 바로 알 수 있지만,
응답이 없거나 랜선이 뽑신 것같은 비정상적인 상황에서는 타임 아웃된
경우를 연결 실패로 간주합니다.
사실 alarm을 쓰지 않아도 시스템 내부적으로 타임아웃이 있습니다.
OS에 따라 다르지만 대략 30초 정도 이지요.
그 시간이 길다고 생각되거나, 옵션으로 정하고 싶을 때는 alarm이나 select를
사용하시면 됩니다. (물론 이 경우에도 OS의 내부 타임아웃 매커니즘을
끌 수는 없습니다.)
1. CONNECT : CONNECT시 SELECT를 사용해서 타임아웃 시간을 둡니다. 그 타임아웃 시간안에 접속이 않되면 타임아웃이 나는것입니다. 그후 에러 처리를 하시고요. 이때 블락이 되어 버릴 경우가 있으므로 CONNECT시에는 ASYNC 통신이 아니더라도 잠시만 ASYNC모드로 두셨다가 해제하시는것도 좋은 방법입니다. 이경우 무한 블락의 경우가 생기는 경우가 왕왕 생기거든요.
2. SEND : 역시 SELECT를 사용합니다. 즉, SELECT가 잘못된 fd를 검출하는 경우가 있지만 전송 시간의 제한을 두는 경우도 있습니다. 두가지 모두 유효하게 사용하실수 있습니다.
리턴 전문의 경우는 보통 시리얼 통신이나 UDP의 경우 ACK 전문을 하나 더 만들어서 정상적으로 전송을 받았거나 그렇지 않았거나 하는 경우 사용합니다. 혹은 어떠한 전문을 전송받았는데 정상적이다 혹은 그렇지 않았을 경우에는 어떠한 에러를 가지고 에러를 내서 반송합니다. 하는 리턴 전문이 존재합니다. 그런데 이와 같이 전송 자체가 제대로 되지 않는 경우에는 구지 리턴 전문으로 해결하실 필요는 없을겁니다. TCP 자체가 해결해주죠.
send시 보내고자 하는 바이트가 모두 전송되었다고 바이트 수만큼 send함수가 리턴이 된다면 제대로 간것이라고 믿으셔도 됩니다. 혹은 이런 경우도 있습니다. 어떠한 방화벽의 경우 특정한 시간동안 세션의 움직임이 없으면 그냥 끊어 버립니다. 이것은 http를 주 서버로 사용하는 사이트들이 그렇게 해놓는 경우가 많습니다. 이럴 경우 중간에 CHIT-CHAT 형식으로 의미없는 전문을 주고 받도록 하는 것도 하나의 방법입니다. 이야기가 세네요.
참조
select에서 FD_CLOSE가 안먹힌다면 ^^;
아마 ping/pong 방법을 쓰셔야 할듯 합니다.~~
그럼
http://my.netian.com/~javaone/evmproxy.t
http://my.netian.com/~javaone/evmproxy.txt 를 참고하세요
------------------Signature
바늘속에서 사막찾기 0.o
select 함수를 쓰셔야 겠네요. select는 연결이 되었거나 실패했
select 함수를 쓰셔야 겠네요. select는 연결이 되었거나 실패했을 때 리턴합니다.
그리고 어느쪽도 아닐 때(접속 응답을 대기중일 때)도 타임아웃을 지정해서 그냥 리턴하게 할 수도 있습니다.
한가지 더 말씀 드리면 TCP/IP의 특성상 랜선을 뽑는다고 해서
바로 접속이 실패하는 것은 아닙니다. 다시 랜선을 연결하면
아무일 없었던 듯이 성공하기도 하니까요.
그만큼 연결 상태의 변화에 유연하게 대처하는 것이 TCP/IP입니다.
그 덕뿐에 랜선이 뽑힌 것을 어플리케이션이 알 수도 없는 것이지요.
접속의 실패는 상대 호스트가 명시적으로 거부했을 때는 바로 알 수 있지만,
응답이 없거나 랜선이 뽑신 것같은 비정상적인 상황에서는 타임 아웃된
경우를 연결 실패로 간주합니다.
사실 alarm을 쓰지 않아도 시스템 내부적으로 타임아웃이 있습니다.
OS에 따라 다르지만 대략 30초 정도 이지요.
그 시간이 길다고 생각되거나, 옵션으로 정하고 싶을 때는 alarm이나 select를
사용하시면 됩니다. (물론 이 경우에도 OS의 내부 타임아웃 매커니즘을
끌 수는 없습니다.)
TTL을 말씀 하신게 아닌가 싶습니다만약 패킷을 보냈는데 RTT
TTL을 말씀 하신게 아닌가 싶습니다
만약 패킷을 보냈는데 RTT 몇번 해보고
timeout 되면 끊어진걸로 간주합니다
그리고 패킷을 보낼때 랜선을 바로 뽑았더라도 소켓버퍼가 비었다면
프로그램상으로는 패킷을 보낸것을 성공으로 간주합니다
한마디로 send 함수를 성공시켰다고 상대방이 받은게 아니라
단지 커널의 TCP/IP 소켓의 버퍼에 보내고자 한 자료가 성공적으로
복사되었다는 의미밖에 되지 않습니다
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
그렇다면..
그렇다면 상대방이 받았다는 것을 확인하는 방법은 없나요?
파일 전송 프로그램을 만들때 보낸 용량을 표시하려면 실제 상대가
받은 양 만큼 표시해야 하는 것 아닌가요?
보통 그냥 커널의 버퍼에 복사한 양을 보낸거라 표시하는 건가요?
상대가 받은것을 확인하려면...상대에게 보낸 패킷의 응답 패킷을
상대가 받은것을 확인하려면...
상대에게 보낸 패킷의 응답 패킷을 받도록 프로토콜을 설정하시면
될거 같네요
트랜잭션 처리 방식으로 동작하도록요
일반적인 상황이라면
send에서 리턴한 값만큼 상대방에 전달 되었다고 보면 됩니다
파일 전송일 경우 패킷을 잘 받았다고 응답하도록 구현 할 필요는
전혀 없어보이네요
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
send/connect 모두 SELECT를 사용해보세요.
send/connect 모두 SELECT를 사용해보세요.
1. CONNECT : CONNECT시 SELECT를 사용해서 타임아웃 시간을 둡니다. 그 타임아웃 시간안에 접속이 않되면 타임아웃이 나는것입니다. 그후 에러 처리를 하시고요. 이때 블락이 되어 버릴 경우가 있으므로 CONNECT시에는 ASYNC 통신이 아니더라도 잠시만 ASYNC모드로 두셨다가 해제하시는것도 좋은 방법입니다. 이경우 무한 블락의 경우가 생기는 경우가 왕왕 생기거든요.
2. SEND : 역시 SELECT를 사용합니다. 즉, SELECT가 잘못된 fd를 검출하는 경우가 있지만 전송 시간의 제한을 두는 경우도 있습니다. 두가지 모두 유효하게 사용하실수 있습니다.
리턴 전문의 경우는 보통 시리얼 통신이나 UDP의 경우 ACK 전문을 하나 더 만들어서 정상적으로 전송을 받았거나 그렇지 않았거나 하는 경우 사용합니다. 혹은 어떠한 전문을 전송받았는데 정상적이다 혹은 그렇지 않았을 경우에는 어떠한 에러를 가지고 에러를 내서 반송합니다. 하는 리턴 전문이 존재합니다. 그런데 이와 같이 전송 자체가 제대로 되지 않는 경우에는 구지 리턴 전문으로 해결하실 필요는 없을겁니다. TCP 자체가 해결해주죠.
send시 보내고자 하는 바이트가 모두 전송되었다고 바이트 수만큼 send함수가 리턴이 된다면 제대로 간것이라고 믿으셔도 됩니다. 혹은 이런 경우도 있습니다. 어떠한 방화벽의 경우 특정한 시간동안 세션의 움직임이 없으면 그냥 끊어 버립니다. 이것은 http를 주 서버로 사용하는 사이트들이 그렇게 해놓는 경우가 많습니다. 이럴 경우 중간에 CHIT-CHAT 형식으로 의미없는 전문을 주고 받도록 하는 것도 하나의 방법입니다. 이야기가 세네요.
하여간 SELECT, 통신 프로그램에서 감초처럼 등장합니다. 자주 사용해보세요.
write() 호출시 SIGPIPE가 발생하는지,read() 호출시
write() 호출시 SIGPIPE가 발생하는지,
read() 호출시 0 (zero)이 리턴되는지를 보십시요.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
댓글 달기