1. Socket?

  • 통신할때 쓰는 것.

2. 작동 시나리오

2.1. 서버

  • 소켓을 연다.
  • 클라이언트의 접속을 기다린다.

2.2. 클라이언트

  • 서버에 접속한다.

3. 구현

3.1. 서버

  • 서버를 구현하기 위해서 CSocket을 상속받아서 클래스를 하나 생성한다. CSocket은 MFC에서 제공해주는 클래스

~cpp
class CServerSocket : public CSocket
{

	///////////////////////
	// member variables
	///////////////////////
protected:
	CWnd *m_pWnd;
	int id;	

public:

	///////////////////////
	// member functions
	///////////////////////
	CServerSocket();
	virtual ~CServerSocket();
	void Init(CWnd *pWnd, int nPortNum);

// Overrides
public:
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CServerSocket)
	public:
	virtual void OnAccept(int nErrorCode);
	//}}AFX_VIRTUAL

	// Generated message map functions
	//{{AFX_MSG(CServerSocket)
		// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG

};
  • 아래는 서버소켓 구현부분중 중요부분

~cpp
void CServerSocket::Init(CWnd *pWnd, int nPortNum)
{
	m_pWnd = pWnd;
	id = nPortNum;
	Create(nPortNum); //특정 포트 번호로 서버를 생성한다.
	Listen(); //클라이언트의 접속을 기다린다.
}

3.1.1. 만든 클래스를 사용하는 부분

~cpp
void COmokView::OnServercreate() 
{
	m_serverSocket.Init(this,SERVERPORT); //서버를 생성한다.
} 

///클라이언트가 접속하는 경우 이벤트가 발생하여 아래 함수가 호출된다.
LRESULT COmokView::OnAcceptClient(WPARAM wParam, LPARAM lParam)
{
	m_dataSocket = new CDataSocket;

	// accept to connect
	if(!m_serverSocket.Accept(*m_dataSocket)) // 접속을 받는다. m_dataSocket을 통해 통신한다.
	{
		AfxMessageBox(_T("Accept failed"));
		return 0;
	}

	// init socket
	m_dataSocket->Init(this); //초기화
	m_dataSocket->SetPort(SERVERPORT); //포트 설정
	CData temp;
	*m_dataSocket >> temp; //클라이언트로부터 메시지를 받았다.
	AfxMessageBox(temp.m_strData); //테스트 확인용으로 받은 메시지를 띄워준다.
	temp.m_strData = "TEST2"; 
	*m_dataSocket << temp; // 클라이언트에게 메시지를 보낸다.
	return 0L;
}

3.2. 클라이언트

  • 소스 참고.. -_- 너무 길다.
  • 크게 아래와 같은 절차
    • m_dataSocket.Create() //
    • m_dataSocket.Connect(dlg1.m_strIpAddress, createBlkFile)
    • m_dataSocket.Init(this);

~cpp
	CIpAddressDlg dlg1;
	m_dataSocket = new CDataSocket;
	if(dlg1.DoModal() == IDOK)
	{
		if(!m_dataSocket->Create()) 
		{
			AfxMessageBox(_T("클라이언트 소켓 생성 실패"));
			return FALSE;
		}
		// request to connect
		if(!m_dataSocket->Connect(dlg1.m_strIpAddress, 2000)) 
		{
			int err = GetLastError();
			AfxMessageBox(_T("서버 접속 실패"));
			return FALSE;
		}		
	}
	else
		return false;
	m_dataSocket->Init(this);
	CData data;
	data.m_strData = "TEST";
	data.m_index = 0;
	*m_dataSocket << data; //데이터 주고 받기 테스트
	*m_dataSocket >> data;
	AfxMessageBox(data.m_strData);
	return true;

3.3. 참고 소스

  • 아래 소스는 소켓 테스트 용으로 간단하게 서버와 클라이언트가 메시지를 주고 받는 프로그램
    • 이 프로그램을 2개 실행 시킨다.
    • 한쪽에서는 서버 생성을 선택 (XP의 경우 이 프로그램의 서버를 허용할지 물어볼때 예 선택)
    • 다른 한쪽에서는 서버 접속을 선택 IP와, ID를 나와 있는 그대로 놔두고(현재 컴퓨터라는 의미) OK 선택
    • 그러면 서버쪽에서 TEST 메시지를 받았다는것이 나오고, 그것을 OK 누르면 클라이언트쪽에서 TEST2메시지를 받았다고 나온다.
  • 이런것을 이용해서 해 나갈 예정
Upload:OmokSocketTest.zip

3.4. Thread

서버에 MFC의 CSocket을 쓰는 것은 그리 바람직해보이지 않네요. 상대적으로 사용하기 좀 어렵겠지만 CAsyncSocket을 써보도록 하세요. (개인적으로는 이것도 별로 추천하지 않습니다. 하지만 MSN이나 네이트온처럼 대형 메신저를 만드는게 아니니까 CAsyncSocket으로도 충분해 보이네요.) 기회가 된다면 MFC Socket말고 Winsock으로 코딩해보세요. --인수
Retrieved from http://wiki.zeropage.org/wiki.php/MFC/Socket
last modified 2021-02-07 05:23:42