C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 강좌/문서
C++Builder Programming Tutorial&Docments
[6] C++Builder Socket 분석 (2) - Socket이 접속할 때
정남영 [kermi] 14780 읽음    2002-01-22 16:34
2. Socket이 접속할 때

2. Socket이 접속할 때

작성자 : 정남영(kermi)

E-mail : kermi@borlandforum.com  

 

 

0. 강의에 들어가면서

Þ

1. Socket Class의 구조

 

2. Socket이 접속할 때

 

3. Socket이 종료될 때

 

4. Socket에 Data가 전달될 때

 

5. Socket에서 Error 처리

 

TCP의 연결 성립은 Three way hand shaking을 거치게 된다. 이를 무시한 Socket Application의 구현은 당연히 문제를 발생할 수밖에 없다. 우선 Three way hand shaking에 대해서 간략히 설명을 하고 문제점을 예를 들겠다.

Client에서 Server에 연결을 요청하게 되면 SYN 신호를 가지고 Server로 연결요청을 하게 된다.

SYN신호를 수신 받은 Server에서는 SYN메시지와 ACK메시지를 Client에게 보내게 되며 SYN-ACK 신호를 수신 받은 Client는 SYN신호가 자기가 ①번에서 보낸 SYN과 같은지 확인한다.

Client에서 확인한 SYN신호가 정상적이면 Server에게 ACK신호를 보내게 되며 TCP 연결작업은 완료된다.

 

Three way hand shaking 작업은 실제 이보다 훨씬 더 자세한 내용과 절차가 있지만 개략적인 내용으로 설명하였다. 자세한 사항은 다른 문서를 참고하기 바란다. 그럼 다음과 같은 Client에서 Server로 데이터를 전송할 때 다음과 같이 구현을 하게 되면 어떻게 될까?

 

void __fastcall TfrmMain::btnSyncClick(TObject *Sender)

{

// Address Port 설정된 상태

ClentSocket->Open();

ClientSocket->Socket->SendText(“Hello”);

}

 

Code상으론 별다른 문제가 없는 것 같지만 심각한 오류가 있는 코드이다. 왜 그럴까? 그건 Three way hand shaking 규칙을 고려하지 않은 구현을 했기 때문이다. 차근차근 설명을 해 나가겠다. 다음 그림을 살펴보자.

ClientSocket->Open()을 호출하게 되면 TCP에 의해 Three way hand shaking으로 접속연결을 진행하게 된다. Three way hand shaking작업이 완료되는 시간은 정확히 예측할 수 없다. 네트워크 트래픽이 많으면 Three way hand shaking작업이 수초 이상 걸릴수도 있으며 그렇지 않을수도 있다. 만약 트래픽이 많은 상황이라고 가정해 보자(위의 그림은 수많은 경우 중 한가지 예를 표현한 것이다.). 그림에서 SYN신호를 보내게 된 상태에서 Client 프로그램은 ClientSocket->Socket->SendText를 이용하여 문자를 전송하게 된다. 그럼 현재 활성화 되지 않은 소켓을 사용하게 되며 오류가 발생하게 된다.

 

그럼 해결책은 무엇일까? WSAAsyncSelect에 대한 MSDN문서를 참고해 보면 알겠지만 소켓이 연결이 완료되면 FD_CONNECT라는 메시지가 발생 된다. FD_CONNECT메시지가 발생하면 OnConnect 이벤트가 발생하게 되며 이때부터 활성화된 소켓을 사용할 수 있게 된다.

수정된 코드는 다음과 같다.

 

void __fastcall TfrmMain::btnSyncClick(TObject *Sender)

{

ClentSocket->Open();

}

 

void __fastcall TfrmMain::ServerSocketClientConnect(TObject *Sender,

      TCustomWinSocket *Socket)

{

    Socket->SendText(“Hello”);

}

 

 

지금까지는 TClientSocket에 대해 알아보았다. 이제부턴 TServerSocket에 대해서 언급을 하겠다.

 

Client가 TServerSocket에 접속하게 되면 TServerSocket에서 Accept 이벤트가 발생하게 된다. Accept 이벤트가 발생하면 winsock API함수인 accept을 이용하여 새로이 연결이 설정된 소켓의 핸들을 가진 TserverClientWinSocket 클래스를 생성하게 되며 그 뒤의 순서는 1회에서 설명했던 <그림1>의 모습대로 동작을 완료하게 된다.(1회 참조)

 

이번 회에서 설명한 내용들은 1회에서 연재한 내용보다 이해하기가 쉬웠으리라 생각한다. 1회는 전체적인 구조를 설명한 것이므로 대충 그렇다는 것만 이해하고 넘어가면 별 무리가 없다. 조언을 하자면 WSAAsyncSelect방식으로 소켓을 사용한다면 FD_ACCEPT, FD_READ등의 이벤트 지향적인 코딩을 하면 구조적인 견고함을 갖추게 된다. 다음회에서는 Socket의 종료에 대해서 설명을 할 것이다.

 

 


+ -

관련 글 리스트
6 C++Builder Socket 분석 (2) - Socket이 접속할 때 정남영 14780 2002/01/22
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.