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

C++빌더 Q&A
C++Builder Programming Q&A
[62282] Re:소켓 통신 서버/클라이언트 구현하는데 잘 모르겠어요
Nibble [] 1260 읽음    2010-08-31 22:44
질문을 자세히 읽어보지 않았습니다.
어쨌든 몇 줄 읽어본 바로는, Accept가 항상 일어나야 한다고 생각하시는 것 같은데요.
소켓의 통신 구조는 전화기를 사용하는 방식과 유사합니다.
아래의 간략한 요약에서 감을 잡으시기 바랍니다.

Open / Close 전화선을 전화소켓에 꽂거나 뽑습니다.
Bind 우리가 사용하는 전화기는 다목적이기 때문에 내선(포트) 설정을 합니다.
Listen 전화를 받는쪽이 전화오는 소리를 들을 수 있는 위치에 있게 합니다.
Connect 전화번호(IP Address)를 이용해 목적지에 전화를 겁니다.
Accept 전화 벨은 울리는데 받을지 말지 결정합니다.
Read / Write 송수화기를 통해 말을 하거나 듣습니다.
Disconnect 전화를 끊습니다.

대충 이런식입니다.
즉, Accept는 클라이언트로 부터의 접속을 허용할지 말지에 대해 딱 한 번 결정내리는 용도로 사용하지,
송수신시 매번 행해지는것이 아닙니다.

이영섭 님이 쓰신 글 :
: 볼랜드로 서버/클라이언트를 만들어보려고 하는데 잘 안되서 문의드려요
:
: 클라이언트에서 소켓 연결할때는 accept에서 반응을 하는데, 패킷을 만들어서 보내니까 accept에서 반응을 안하더라구요.
: 아래 부분은 서버 쪽 소스인데, MFC로 구현된걸 찾으면서 C빌더로 바꾸다보니 마음대로 안되네요;;;
:
: 질문을 정리하면
: - 소켓 연결할 때는 accept에 반응이 있는데, 패킷을 보낼때는 왜 반응이 없는지 알고싶습니다.
:
: -----
: void TForm1::Main()
: { 
:     int clen;
:     cmdMessage *rcvState, *sendMsg;
:    
:     byte *rcvbuf;
:              
:     SOCKADDR_IN client_addr;
:
:     while(1)
:     {     
:         if(!SocketListenTCP(ssock))
:         {
:             ShowMessage("실패");
:             return;
:         }
:          csock = accept(ssock, (SOCKADDR*)&client_addr, &clen);  // 반응있음
:           // Receive
:          int nRecvPacketSize = sizeof(cmdMessage); 
:          rcvbuf = (Byte*)malloc(nRecvPacketSize);
:          memset(rcvbuf, 0x00,nRecvPacketSize);        
:
:          if(listen(ssock, 5) == SOCKET_ERROR)
:          {
:             ShowMessage("ERROR");
:          }
:    
: //        read(csock, (char*)rcvbuf, nRecvPacketSize);
:          int nRecvCount = ReceiveTCPData(csock, (char*)rcvbuf,
:                                       nRecvPacketSize, 10);
:
:          int length = strlen(rcvbuf);
:          if(length <= 0)
:          {
:             Sleep(1);
:             continue;
:          }
:        //  Send       
:          rcvState = (cmdMessage*)rcvbuf;        
:          Parsing(rcvState); // 메시지를 만들어서 클라이언트에 던지는 함수
:          return;
:     }
: }
:
: //-----------------------------------------------------------------
:
: int ReceiveTCPData(SOCKET s, char * lpBuffer, int nSizeToRead, int nTimeout)
: {
:     register int i;
:     register int nread = 0;
:     register int rtn;
:     int     elapsed = 0;
:     int     nErrorResult = 0;
:     char    szMessage[100] = "0x00,";
:     bool    flag;
:     u_long FAR arg; /* blocking, non-blocking 변환용 */
:     int        nReturn;
:     unsigned long time_start, time_elps;  // time out 시간보정
:
:     if(nTimeout >= 0)
:     {
:         arg = 1;
:         ioctlsocket(s, FIONBIO, &arg);   /* non-blocking mode */
:     }
:     else
:     {
:         arg = 0;
:         nReturn = ioctlsocket(s, FIONBIO, &arg);   /* blocking mode */
:     }
:
:     for(i = 0; i < nSizeToRead; )
:     {
:         time_start = GetTickCount();
:
:         rtn = recv(s, lpBuffer + i, nSizeToRead - nread, 0);
:         if (rtn == 0) /* EOF */ //-- Disconnect Occurs
:         {
:             if( flag == true ) return nread;
:             arg = 0; ioctlsocket(s, FIONBIO, &arg);   //* blocking mode */
:             return SOCKET_DISCONNECTED;
:         }
:         else if (rtn < 0) // error
:         {
:
:             //if( flag == true ) return nread;
:             nErrorResult = GetLastSocketErrorMessage(szMessage);
:             if(nErrorResult == WSAECONNABORTED)
:             {
:                 return SOCKET_CLOSED;
:             }
:             else if(nErrorResult == WSAECONNRESET)
:             {
:                 return SOCKET_DISCONNECTED;
:             }
:             else if (nTimeout >= 0)
:             {
:                 if (elapsed >= nTimeout)  // Occur Timeout
:                 { //* time out
:                     arg = 0; ioctlsocket(s, FIONBIO, &arg);   // blocking mode
:                     if( flag == true ) return nread;
:                     return SOCKET_READTIMEOUT;
:                 }
:                 Sleep(1);
:
:                 time_elps = GetTickCount() - time_start;
:                 elapsed += time_elps;
:             }
:             else // Socket Disconnected      // Socket Closed
:             {
:                 if( flag == true ) return nread;
:                 return SOCKET_CLOSED;
:             }
:         }
:         else //* rtn(bytes)를 read한 경우 */
:         {
:             if( i == 0 ) flag = true;
:             nread += rtn;
:             i += rtn;
:         }
:     }
:
:     arg = 0;
:         ioctlsocket(s, FIONBIO, &arg);   /* blocking mode */
:
:     return nread;
: }

+ -

관련 글 리스트
62278 소켓 통신 서버/클라이언트 구현하는데 잘 모르겠어요 이영섭 1104 2010/08/31
62282     Re:소켓 통신 서버/클라이언트 구현하는데 잘 모르겠어요 Nibble 1260 2010/08/31
62285         Re:Re:소켓 통신 서버/클라이언트 구현하는데 잘 모르겠어요 이영섭 1234 2010/09/01
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.