|
아.... 제가 잘못 이해하고있었네요.
요는 Accept는 처음에 한번 연결할때 망개통하는 것이고, Listen을 통해 메시지 받을 준비를 하고 Read, write를 통해서 메시지를 전달하는 것이군요.
답변 감사합니다.
Nibble 님이 쓰신 글 :
: 질문을 자세히 읽어보지 않았습니다.
: 어쨌든 몇 줄 읽어본 바로는, 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;
: : }
|