Tcpdump 에서 Flags[S] 만 뜨는 현상

안녕하세요 공부하는 학생입니다!

어떠한 장비A는 외부에서 데이터를 받을시 그 데이터를 정해진 서버와 ip로 통신하게

되어있습니다. 근데 데이터가 안들어오고 소켓로그에도 안찍히길레

tcpdump를 해보니 Flags 가 [S] 인 패킷만 무한대로 찍힙니다.

자료를 보니 sync 하는 플래그인데 어떤 문제가 있는건지 조언좀 부탁드립니다. ㅠㅠ

192.168.0.1.AAA > 192.168.0.2.AAA: Flags [S], cksum 0x68b4 (correct), seq 789457140, win 2048, options [mss 1460], length 0

이것만 cksum 값이 조금 바뀐값으루 계속찍힙니다…

[code:xtgoxt2b]
09:20:58.124532 IP 192.168.25.40.49133 > 192.168.25.1.http: Flags [S], seq 1016758406, win 29200, options [mss 1460,sackOK,TS val 876277 ecr 0,nop,wscale 7], length 0

09:20:58.126380 IP 192.168.25.1.http > 192.168.25.40.49133: Flags [S.], seq 1233985748, ack 1016758407, win 5792, options [mss 1460,sackOK,TS val 30709144 ecr 876277,nop,wscale 1], length 0

09:20:58.126442 IP 192.168.25.40.49133 > 192.168.25.1.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 876278 ecr 30709144], length 0

09:20:58.126559 IP 192.168.25.40.49133 > 192.168.25.1.http: Flags [P.], seq 1:376, ack 1, win 229, options [nop,nop,TS val 876278 ecr 30709144], length 375

09:20:58.128459 IP 192.168.25.1.http > 192.168.25.40.49133: Flags [.], ack 376, win 3432, options [nop,nop,TS val 30709144 ecr 876278], length 0
[/code:xtgoxt2b]

위 내용은 제가 제 PC에서 무선 공유기 router에 있는 web server에 web browser로 연결하면서 tcpdump가 준 출력 중에서 처음 5줄만을 보인것입니다. 그 5줄이 잘 구분되도록 하기 위하여, 매 줄마다 비어있는 줄을 하나씩 일부러 집어넣었습니다. client와 server가 TCP로 데이터를 주고 받으려면, 일단 통성명을 해야합니다. client와 server 사이에 연결을 하는 것이죠. 위 code에서는 위로부터 3개 줄이 이에 해당합니다. 연결이 되고 나면 데이터를 주고 받습니다. 위 code에서는 아래 2줄이 데이터 교환의 시작을 보여줍니다.

연결과정을 보면…
(1) 일단 client가 server에 연결 요청(syn)을 합니다. 위 첫 줄에 보이는 [b:xtgoxt2b]Flags [S][/b:xtgoxt2b]이 이에 해당합니다.
(2) server가 이 연결 요청을 받으면 연결 요청을 수락한다는 신호(ack)를 client에 보냅니다. 위 두번째 줄에 보이는 [b:xtgoxt2b]Flags [S.], seq 1233985748, ack[/b:xtgoxt2b]이 이에 해당합니다. [b:xtgoxt2b]ack[/b:xtgoxt2b]이라는 단어를 눈여겨 보세요.
(3) ack를 받은 client는 server의 수락 신호를 받았다는 신호를 server에 보냅니다. 위 세번쨰 줄에 있는 [b:xtgoxt2b]Flags [.], ack 1[/b:xtgoxt2b]이 이에 해당합니다.

학생의 경우, 장비 A가 TCP client이고, TCP 서버와 데이터를 교환하는 것이겠죠. 그런데 위 첫줄의 접속 요청만 있고, 두번째, 세번째 줄에 해당하는 handshake 과정이 보이지 않는다는 말이 되겠죠. 원인은 다양할 수 있겠죠. 서버 IP가 틀렸던지, port number가 틀렸던지, firewall에 의하여 막혀 있다던지, 혹은 하드웨어적 결함 등등… 원인은 찾아내셔야죠. 일단, 서버가 범용 컴퓨터이고, 다른 service (에 ftp, web, mail 등등)도 하는 것이라면, 그런 서비스 접속을 해서 서버의 하드웨어적 결함 가능성부터 점검하고, server와 client의 소프트웨어 (설정을 포함하여…)를 점검해야 할 듯합니다. 단, connection request는 나오는 것으로 보아 client의 하드웨어 결함 가능성은 낮아보이긴 합니다. 근데, 혹시 모르죠.

안녕하세요! 관심가져주시고 조언해주셔서 정말 감사합니다.

질문을 너무 두리뭉실하게해서 지울까말까 하다가 댓글 달아주시고 조언해주셔서 뭐라

어떻게 감사를 드려야할지 모르겠습니다.

현재 A장비는 어떠한 입력을 받으면 그 받은 입력을 정해진 서버IP와 포트로 그 데이터와 자신의 고유넘버를 보내줍니다.

문제점은 이 장비 A를 두번째 켰을때 이러한 동작이 작동안하는 것이 문제점입니다

그래서 시도해본것이 tcpdump였고 첨부한 그림파일의 왼쪽위 putty 화면을 보시면 서버가 부팅되고 A장비가 처음에 장착됬을때는

정상적으로 3way 핸드쉐이킹 방식으로 ‘S’, ‘S.’, ‘.’ 이 찍히는 것을 확인했는데 이것을 확인하고

A장비를 껏다 키면 모니터링되는 패킷이 첫번째 질문에 올린

192.168.0.1.AAA > 192.168.0.2.AAA: Flags [S], cksum 0x68b4 (correct), seq 789457140, win 2048, options [mss 1460], length 0

입니다. 제가 궁금한점은 이 tcpdump는 서버에서 실행한 명령문으로 위의 패킷이 모니터링됬다는 것은

클라이언트로부터 리눅스 서버(192.168.0.2)로 sync 패킷이 들어오는데 리눅스 서버에서 정상적으로 됬을때처럼 S. 패킷을 어떠한 이유로

안보내는 것으로 이해했고 이러한 이유가 무엇인지 짧은 소견으로는 모르겠습니다… 혹시 장비 A가 껏다키면 연결이 아예 안되는것인지

ping을 날려봤지만 첫번째, 두번째와 상관없이 무조건 연결이 된다면 ping은 날라갔고 네트워크적으로 연결은 되는것으로 이해했습니다.

혹시 제가 잘못이해하고있는 부분은 어디인지, 그리고 점검해야될 부분은 무엇인지 선배님께 조언부탁드리겠습니다!

그리고 관심가져주시고 조언해주신점 한번더 감사드립니다!

[quote="happyman":1x8u520w][code:1x8u520w]
09:20:58.124532 IP 192.168.25.40.49133 > 192.168.25.1.http: Flags [S], seq 1016758406, win 29200, options [mss 1460,sackOK,TS val 876277 ecr 0,nop,wscale 7], length 0

09:20:58.126380 IP 192.168.25.1.http > 192.168.25.40.49133: Flags [S.], seq 1233985748, ack 1016758407, win 5792, options [mss 1460,sackOK,TS val 30709144 ecr 876277,nop,wscale 1], length 0

09:20:58.126442 IP 192.168.25.40.49133 > 192.168.25.1.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 876278 ecr 30709144], length 0

09:20:58.126559 IP 192.168.25.40.49133 > 192.168.25.1.http: Flags [P.], seq 1:376, ack 1, win 229, options [nop,nop,TS val 876278 ecr 30709144], length 375

09:20:58.128459 IP 192.168.25.1.http > 192.168.25.40.49133: Flags [.], ack 376, win 3432, options [nop,nop,TS val 30709144 ecr 876278], length 0
[/code:1x8u520w]

위 내용은 제가 제 PC에서 무선 공유기 router에 있는 web server에 web browser로 연결하면서 tcpdump가 준 출력 중에서 처음 5줄만을 보인것입니다. 그 5줄이 잘 구분되도록 하기 위하여, 매 줄마다 비어있는 줄을 하나씩 일부러 집어넣었습니다. client와 server가 TCP로 데이터를 주고 받으려면, 일단 통성명을 해야합니다. client와 server 사이에 연결을 하는 것이죠. 위 code에서는 위로부터 3개 줄이 이에 해당합니다. 연결이 되고 나면 데이터를 주고 받습니다. 위 code에서는 아래 2줄이 데이터 교환의 시작을 보여줍니다.

연결과정을 보면…
(1) 일단 client가 server에 연결 요청(syn)을 합니다. 위 첫 줄에 보이는 [b:1x8u520w]Flags [S][/b:1x8u520w]이 이에 해당합니다.
(2) server가 이 연결 요청을 받으면 연결 요청을 수락한다는 신호(ack)를 client에 보냅니다. 위 두번째 줄에 보이는 [b:1x8u520w]Flags [S.], seq 1233985748, ack[/b:1x8u520w]이 이에 해당합니다. [b:1x8u520w]ack[/b:1x8u520w]이라는 단어를 눈여겨 보세요.
(3) ack를 받은 client는 server의 수락 신호를 받았다는 신호를 server에 보냅니다. 위 세번쨰 줄에 있는 [b:1x8u520w]Flags [.], ack 1[/b:1x8u520w]이 이에 해당합니다.

학생의 경우, 장비 A가 TCP client이고, TCP 서버와 데이터를 교환하는 것이겠죠. 그런데 위 첫줄의 접속 요청만 있고, 두번째, 세번째 줄에 해당하는 handshake 과정이 보이지 않는다는 말이 되겠죠. 원인은 다양할 수 있겠죠. 서버 IP가 틀렸던지, port number가 틀렸던지, firewall에 의하여 막혀 있다던지, 혹은 하드웨어적 결함 등등… 원인은 찾아내셔야죠. 일단, 서버가 범용 컴퓨터이고, 다른 service (에 ftp, web, mail 등등)도 하는 것이라면, 그런 서비스 접속을 해서 서버의 하드웨어적 결함 가능성부터 점검하고, server와 client의 소프트웨어 (설정을 포함하여…)를 점검해야 할 듯합니다. 단, connection request는 나오는 것으로 보아 client의 하드웨어 결함 가능성은 낮아보이긴 합니다. 근데, 혹시 모르죠.[/quote:1x8u520w]

[quote="rura6502":1ld3gu4s]
문제점은 이 장비 A를 두번째 켰을때 이러한 동작이 작동안하는 것이 문제점입니다

그래서 시도해본것이 tcpdump였고 첨부한 그림파일의 왼쪽위 putty 화면을 보시면 서버가 부팅되고 A장비가 처음에 장착됬을때는

정상적으로 3way 핸드쉐이킹 방식으로 ‘S’, ‘S.’, ‘.’ 이 찍히는 것을 확인했는데 이것을 확인하고

A장비를 껏다 키면 모니터링되는 패킷이 첫번째 질문에 올린

192.168.0.1.AAA > 192.168.0.2.AAA: Flags [S], cksum 0x68b4 (correct), seq 789457140, win 2048, options [mss 1460], length 0

입니다. 제가 궁금한점은 …
[/quote:1ld3gu4s]

이건 완전히 다른 질문이잖아요. ㅋㅋㅋ 진작 이렇게 말씀하시지. 그럼, 능력 부족으로 답변하지 못했을텐데 말이죠… ㅎㅎㅎ 어째 답변을 쓰면서도 느낌이 별로 좋지 않았습니다. 질문자가 아는 내용만 쓰고 있다는 느낌이랄까…

첫번째에는 정상 동작되고, 장비 A를 OFF-ON 했을 때에도 ping이 된다는 것은 하드웨어 문제일 가능성은 없다고 볼 수 있다는 것이겠죠. 더구나 첫번째에 정상 동작했다는 것은 TCP의 문제도 아닌 것으로 생각됩니다. 하기야, 수십년 수많은 사람이 사용한 TCP library에 문제가 있을 것 같지는 않죠. 제 짐작으로는 문제는 application layer protocol, 혹은 application program의 문제, 혹은 그 설정의 문제라는 결론에 이르게 되는데요.

서버와의 통신에 사용하는 server/client program이 상용 program이거나, open source program이라면 그 이름을 밝히고 사용해 본 분의 도움을 구하는 것이 맞는 것 같습니다. 이것 없이는 장님 코끼리 만지기식 밖에 안됩니다. 이런 부분이라면, 제가 이런 분야의 상용 program/open source program을 써본 일이 없어서 저는 더이상 도움이 안되겠지만, 경험자가 계실테니 조언을 주실 겁니다.

혹시 대학생이어서 졸업 프로젝트를 위하여 스스로 program한 것이라면 짚이는 것이 있기는 한데, 이것은 잘못 떠들면 저만 망신스러운 일이니, 어느 경우(상용/open source, 스스로 작성)에 해당하는지 밝히시지 않으면, 더 이상 제가 도와드릴 부분은 없네요. 더더구나, 이 경우 스스로가 잘 이해하고 있는 source code가 있으니, 디버거에서 디버깅이 가능할 것 같구요. 혹시 고수님들은 그런 것 모르고도 답변 가능하실지도 모르죠. 근데, 저는 어깨 너머로 배운 얄팍한 지식 밖에 없어서 좀 떠들다 보면 금새 밑바닥이 보이는 지라… ㅎㅎㅎ

그리고, 올리신 사진에 IP는 가리지 않았는데, port number를 가리셨더라고요. port number가 비밀에 해당하나요? 오히려 privacy 문제라면 IP가 더 중요한 것 같은데… 암튼, 장비 A의 port number를 보고 싶었는데, 안보여서 원인을 상상하는데 장애가 있었습니다.

안녕하세요! 먼저 조언해주신점 다시한번 감사드립니다!

클라이언트에 속하는 A장비의 펌웨어가 어떤소스로 구성되어 있는진 모르지만

서버는 우분투 서버버젼으로 php를 구성하여 tcp 소켓 9998번을 구성했습니다.

http://ihelpers.x2soft.co.kr/programmin ... e=overture

여기서 나오는 소켓소스와 로그출력 등을 제외하면 99.99% 동일합니다.

혹시 생각하시는 문제점이 무엇인지 여쭤봐도 될까요?? 최대한 참고하겠습니다.

제 짧은 개인적인 생각으로는 클라이언트와 서버간의 커넥/디스커넥이 제대로 이루어지지 않아서

이러한 현상이 발생하지 않을까 추측하고 있습니다.

tcp연결에서 클라이언트 A와 서버는 처음에 3way 를 통해 연결을 구성하고 데이터를 주고받은후

소켓은 닫는것이 아니라 클라이언트 A와 어떠한 disconnect 작업을 해줘야하는 것일까요??

소켓을 닫지 못하는 이유는

다른 여러 클라이언트 장비 BCDF가 있고 서버는 이러한 다른 클라이언트의 데이터를 받기위해

항상 리스닝중이여야합니다.

시간내주셔서 감사합니다!

[quote="happyman":2tdx9atc][quote="rura6502":2tdx9atc]
문제점은 이 장비 A를 두번째 켰을때 이러한 동작이 작동안하는 것이 문제점입니다

그래서 시도해본것이 tcpdump였고 첨부한 그림파일의 왼쪽위 putty 화면을 보시면 서버가 부팅되고 A장비가 처음에 장착됬을때는

정상적으로 3way 핸드쉐이킹 방식으로 ‘S’, ‘S.’, ‘.’ 이 찍히는 것을 확인했는데 이것을 확인하고

A장비를 껏다 키면 모니터링되는 패킷이 첫번째 질문에 올린

192.168.0.1.AAA > 192.168.0.2.AAA: Flags [S], cksum 0x68b4 (correct), seq 789457140, win 2048, options [mss 1460], length 0

입니다. 제가 궁금한점은 …
[/quote:2tdx9atc]

이건 완전히 다른 질문이잖아요. ㅋㅋㅋ 진작 이렇게 말씀하시지. 그럼, 능력 부족으로 답변하지 못했을텐데 말이죠… ㅎㅎㅎ 어째 답변을 쓰면서도 느낌이 별로 좋지 않았습니다. 질문자가 아는 내용만 쓰고 있다는 느낌이랄까…

첫번째에는 정상 동작되고, 장비 A를 OFF-ON 했을 때에도 ping이 된다는 것은 하드웨어 문제일 가능성은 없다고 볼 수 있다는 것이겠죠. 더구나 첫번째에 정상 동작했다는 것은 TCP의 문제도 아닌 것으로 생각됩니다. 하기야, 수십년 수많은 사람이 사용한 TCP library에 문제가 있을 것 같지는 않죠. 제 짐작으로는 문제는 application layer protocol, 혹은 application program의 문제, 혹은 그 설정의 문제라는 결론에 이르게 되는데요.

서버와의 통신에 사용하는 server/client program이 상용 program이거나, open source program이라면 그 이름을 밝히고 사용해 본 분의 도움을 구하는 것이 맞는 것 같습니다. 이것 없이는 장님 코끼리 만지기식 밖에 안됩니다. 이런 부분이라면, 제가 이런 분야의 상용 program/open source program을 써본 일이 없어서 저는 더이상 도움이 안되겠지만, 경험자가 계실테니 조언을 주실 겁니다.

혹시 대학생이어서 졸업 프로젝트를 위하여 스스로 program한 것이라면 짚이는 것이 있기는 한데, 이것은 잘못 떠들면 저만 망신스러운 일이니, 어느 경우(상용/open source, 스스로 작성)에 해당하는지 밝히시지 않으면, 더 이상 제가 도와드릴 부분은 없네요. 더더구나, 이 경우 스스로가 잘 이해하고 있는 source code가 있으니, 디버거에서 디버깅이 가능할 것 같구요. 혹시 고수님들은 그런 것 모르고도 답변 가능하실지도 모르죠. 근데, 저는 어깨 너머로 배운 얄팍한 지식 밖에 없어서 좀 떠들다 보면 금새 밑바닥이 보이는 지라… ㅎㅎㅎ

그리고, 올리신 사진에 IP는 가리지 않았는데, port number를 가리셨더라고요. port number가 비밀에 해당하나요? 오히려 privacy 문제라면 IP가 더 중요한 것 같은데… 암튼, 장비 A의 port number를 보고 싶었는데, 안보여서 원인을 상상하는데 장애가 있었습니다.[/quote:2tdx9atc]

저는 사실 php에서 socket programming을 해본 경험은 없구요. php에 socket이 있는 줄도 처음 알았네요. ㅎㅎㅎ

예전에 제가 개발했던 C application에 internet support가 필요해서 잠시 해본 경험이 전부이긴 합니다만… client 쪽에 문제가 있는 경우는 드물죠. Client야 사용하다가 전원 꺼버리고 가는 경우도 있고, 참 다양하게 쓰니까요. 첫번째 시도는 된다고 하셨으니, client가 죄를 저질렀을 가능성은 적죠. 아무튼 제가 지금 그 code를 읽어서 분석할 수는 없구요. 그냥 개념적인 문제로 그리고 C언어 system call을 기준으로 말씀드릴께요.

문제는 server program이죠. 예를 들어 application의 규칙(protocol)에 따라 메세지를 주고 받는다고 가정하죠. 근데 이유가 뭐가 되었건 client가 중간에 그대로 나가버리면 (예: 전원 OFF), 그래도 server는 동작해야 합니다. server는 그 client에만 service할 수 없으니까요. 장비 A만 있다면, 모르지만, 다른 장비의 connect request를 들어야 하잖아요? 장비 A에게만 서비스를 한다고 하더라도 2nd service request를 들어야 할 것이구요. 근데, 서버는 client가 나가버린 그 상황을 모르니 마냥 기다리게 될 수도 있고, 다음 service를 위하여 끊어 버리기도 난감하고 그렇다는 것이죠. 제가 의심하는 것은 이런 상황이었습니다. 기존 package들이야 이런 상황에 대비하는 program을 하지만, 학생 project에서는 제대로 된 상황에만 적용되는 program을 하는 것은 흔한 일일 수 있으니까요. 기존 package인지 학생 project인지 물어본 이유가 이것입니다.

그런 이유로, server 쪽은 일단 connection request가 오면, 즉, system call accept() 가 떨어지면, 그다음부터는 fork() call을 이용하여 새로운 child process를 만들어서 그 child process가 나머지 통신 과정을 담당하게 하죠. 그렇게 하면, child process가 첫번째 client와의 통신 과정을 담당하고, parent process는 새로운 sevice를 위하여 port를 듣는 일을 하게 되는 것이죠. 이렇게 하면, 처음 장비와의 통신에 문제가 생겨도 다른 새로운 장비에 서비스를 계속할 수 있다는 것입니다. 문제가 생긴 장비의 경우, timer 같은 것을 이용하여 zombie processs가 생기는 것은 막을 수 있을 것이고요. 요즘은 process를 쓰지 않고 thread를 이용하는 경우도 있다더군요. 저는 thread로 해보진 않아서 잘 모르지만, 장단점이 있겠죠. Client가 protocol를 지킨다는 보장도 없고 Program에 minor bug가 없으라는 법도 없으니, 그런 문제에 대처하기 위하여, 대부분의 서버가 이런 방식으로 처리하는 것으로 저는 알고 있습니다.

rura6502님의 경우에도 그런 문제를 의심했습니다. 첫번째 접속에서는 잘되었겠죠. 그런데, 첫번째 접속에서 protocol에 따라 통신을 마치고 socket을 제대로 닫아주지 않으면, 일종의 dead-lock에 걸릴 수 있다는 것이죠. 그럼 두번째 접속에서 server는 데이터를 기다리고 있는데, client는 connectiom request를 하고 있는 상황에 처할 수 있잖아요? child process에서 담당하도록 떼어 버리면, parent process에서 계속 들으면 되니 문제가 없다는 것이죠.

Server가 통신을 child process에서 처리하는 경우에도 client program에 문제가 있다면 문제가 있을 수 있는데… 사실 가능성은 거의 없는데요. tcp는 server IP/server port/client IP/client port의 4개 묶음으로 연결을 규정합니다. 그런데, Server IP/server port/client IP는 하나의 장비를 가정하면 똑같죠? 그러니, 장비 A의 전원을 끄고, 전원을 다시 켰을 때, 같은 client port를 사용한다면 연결이 동일해지게 됩니다. 따라서, 새로운 연결이 시도되는 것이 아니라 기존의 child process가 이 메세지를 가져갈 수 있다는 것이죠. 전원 OFF 이전의 통신 과정에서 child process가 제대로 끝나지 못했다면 그렇게 될 수 있고, 이 경우, child process는 read() call을 하고 있는데, client는 connect() call을 하는 상황이 될 수도 있다는 생각인 것입니다. 그래서 전원 OFF 이전과 이후 다시 ON했을 때 child port number를 보고 싶었는데 가려 놓으셨더라구요. 근데, 뭐 같은 가능성은 거의 없죠. 제가 알기로는 random number generation에 의하여 child port number가 정해지는 것으로 알고 있으니까요. 그러므로 이 가능성은 없다고 보아도 될 것입니다.

결론적으로, sever가 통신하는 과정이 child process가 담당하게 하는 것이 아니라면 (php code를 제대로 읽지 않아서 모릅니다), 매우 위험합니다. dead-lock에 빠지기 매우 쉽습니다. child process가 담당하게 하는 경우에도 제대로 protocol이 완성된 후, exit하도록 program 하세요. client가 저 혼자 죽어버리는 경우에 대비하여 적절한 timer도 설치하세요.

원인이 이것이 아니라면, 저도 모릅니다. 몇마디 하다보면 바닥이 곧 드러난다고 말씀드렸잖아요. 아무튼 현상을 보면, dead-lock 혹은 유사한 현상으로 보입니다.

정말 정성스럽게 답변해주셔서 감사합니다. 저도 몇일을 고민한결과 클라이언트의 disconnect를 sever에서 알게하는 무언가가

있어야 할거같다고 고민을 많이 했습니다. 조언해주신 말씀을 따라 관련자료를 찾아보도록 하겠습니다.

지방에 작은 대학에 공부하고 있는 학생으로써 교수님의 어드바이스도 없이 공부하다보니 포럼등을 통해

이러한 지식을 나눠주시는 것에대해 정말 감사함을 항상 느낍니다.

쪽지에 카카오톡 아이디라도 남겨주시면 커피한잔 사고싶습니다. 시간내주신점, 정성스럽게 답변해주신점 감사합니다.

아직 해결을 못했고 찾아나가는 과정이지만

해결되면 어떻게 해결했는지 꼭 이 글에 작은 도움이 되고자 올리겠습니다.(저와 같은 무식한 사람이 여기 있지도 않겠지만…)

다시한번 감사드립니다.

[quote="happyman":hznn9i0c]저는 사실 php에서 socket programming을 해본 경험은 없구요. php에 socket이 있는 줄도 처음 알았네요. ㅎㅎㅎ

예전에 제가 개발했던 C application에 internet support가 필요해서 잠시 해본 경험이 전부이긴 합니다만… client 쪽에 문제가 있는 경우는 드물죠. Client야 사용하다가 전원 꺼버리고 가는 경우도 있고, 참 다양하게 쓰니까요. 첫번째 시도는 된다고 하셨으니, client가 죄를 저질렀을 가능성은 적죠. 아무튼 제가 지금 그 code를 읽어서 분석할 수는 없구요. 그냥 개념적인 문제로 그리고 C언어 system call을 기준으로 말씀드릴께요.

문제는 server program이죠. 예를 들어 application의 규칙(protocol)에 따라 메세지를 주고 받는다고 가정하죠. 근데 이유가 뭐가 되었건 client가 중간에 그대로 나가버리면 (예: 전원 OFF), 그래도 server는 동작해야 합니다. server는 그 client에만 service할 수 없으니까요. 장비 A만 있다면, 모르지만, 다른 장비의 connect request를 들어야 하잖아요? 장비 A에게만 서비스를 한다고 하더라도 2nd service request를 들어야 할 것이구요. 근데, 서버는 client가 나가버린 그 상황을 모르니 마냥 기다리게 될 수도 있고, 다음 service를 위하여 끊어 버리기도 난감하고 그렇다는 것이죠. 제가 의심하는 것은 이런 상황이었습니다. 기존 package들이야 이런 상황에 대비하는 program을 하지만, 학생 project에서는 제대로 된 상황에만 적용되는 program을 하는 것은 흔한 일일 수 있으니까요. 기존 package인지 학생 project인지 물어본 이유가 이것입니다.

그런 이유로, server 쪽은 일단 connection request가 오면, 즉, system call accept() 가 떨어지면, 그다음부터는 fork() call을 이용하여 새로운 child process를 만들어서 그 child process가 나머지 통신 과정을 담당하게 하죠. 그렇게 하면, child process가 첫번째 client와의 통신 과정을 담당하고, parent process는 새로운 sevice를 위하여 port를 듣는 일을 하게 되는 것이죠. 이렇게 하면, 처음 장비와의 통신에 문제가 생겨도 다른 새로운 장비에 서비스를 계속할 수 있다는 것입니다. 문제가 생긴 장비의 경우, timer 같은 것을 이용하여 zombie processs가 생기는 것은 막을 수 있을 것이고요. 요즘은 process를 쓰지 않고 thread를 이용하는 경우도 있다더군요. 저는 thread로 해보진 않아서 잘 모르지만, 장단점이 있겠죠. Client가 protocol를 지킨다는 보장도 없고 Program에 minor bug가 없으라는 법도 없으니, 그런 문제에 대처하기 위하여, 대부분의 서버가 이런 방식으로 처리하는 것으로 저는 알고 있습니다.

rura6502님의 경우에도 그런 문제를 의심했습니다. 첫번째 접속에서는 잘되었겠죠. 그런데, 첫번째 접속에서 protocol에 따라 통신을 마치고 socket을 제대로 닫아주지 않으면, 일종의 dead-lock에 걸릴 수 있다는 것이죠. 그럼 두번째 접속에서 server는 데이터를 기다리고 있는데, client는 connectiom request를 하고 있는 상황에 처할 수 있잖아요? child process에서 담당하도록 떼어 버리면, parent process에서 계속 들으면 되니 문제가 없다는 것이죠.

Server가 통신을 child process에서 처리하는 경우에도 client program에 문제가 있다면 문제가 있을 수 있는데… 사실 가능성은 거의 없는데요. tcp는 server IP/server port/client IP/client port의 4개 묶음으로 연결을 규정합니다. 그런데, Server IP/server port/client IP는 하나의 장비를 가정하면 똑같죠? 그러니, 장비 A의 전원을 끄고, 전원을 다시 켰을 때, 같은 client port를 사용한다면 연결이 동일해지게 됩니다. 따라서, 새로운 연결이 시도되는 것이 아니라 기존의 child process가 이 메세지를 가져갈 수 있다는 것이죠. 전원 OFF 이전의 통신 과정에서 child process가 제대로 끝나지 못했다면 그렇게 될 수 있고, 이 경우, child process는 read() call을 하고 있는데, client는 connect() call을 하는 상황이 될 수도 있다는 생각인 것입니다. 그래서 전원 OFF 이전과 이후 다시 ON했을 때 child port number를 보고 싶었는데 가려 놓으셨더라구요. 근데, 뭐 같은 가능성은 거의 없죠. 제가 알기로는 random number generation에 의하여 child port number가 정해지는 것으로 알고 있으니까요. 그러므로 이 가능성은 없다고 보아도 될 것입니다.

결론적으로, sever가 통신하는 과정이 child process가 담당하게 하는 것이 아니라면 (php code를 제대로 읽지 않아서 모릅니다), 매우 위험합니다. dead-lock에 빠지기 매우 쉽습니다. child process가 담당하게 하는 경우에도 제대로 protocol이 완성된 후, exit하도록 program 하세요. client가 저 혼자 죽어버리는 경우에 대비하여 적절한 timer도 설치하세요.

원인이 이것이 아니라면, 저도 모릅니다. 몇마디 하다보면 바닥이 곧 드러난다고 말씀드렸잖아요. 아무튼 현상을 보면, dead-lock 혹은 유사한 현상으로 보입니다.[/quote:hznn9i0c]