U E D R , A S I H C RSS

5�용C++스터디/소켓프로그래�

1:1 채팅 프로그램� 만들 수 있� 정�로 발표 준비를 할 것.
----

소켓 �해하기


소켓� 멀리 떨어진 �개� 호스트(서버와 ���언트)를 연결하는 매개체�다.

전화기� 비유!!!전화기≒소켓

전화기 소켓
전화를 받기 위한 '전화 번호' IP주소
전화선� 연결�어 전화를 받� 수 있는 �태 대기�태(Listen)
전화가 걸려옴 연결 요청(Connect)
전화를 받� 연결 허�(Accept)

서버-���언트 환경� 만들기 위한 과정� 서버측�서 보�면 다�� 과정� 거치게 �다.
~cpp 
    Socket �성 -> Socket � �름연결 (bind)
    -> ���언트� 연결� 기다림(listen)
    -> ���언트를 받아들임 (Accept)
    -> ���언트� 명령� 받아서 �절한 서비스를 수행

���언트측�서 서버� 접근하기 위해서는 단순히 소켓� �성후 서버� 연결(connect) 하기만 하면 �다.
~cpp 
     Socket �성 -> 서버� 연결 시�(connect) -> 서버� �종 명령� 전달


예제(서버)

Dialog based -> Windows Sockets를 설정
기초 �래스가 CAsyncSocket� 새로운 �래스 CListenSock, CChildSock� 새로 �성한다.
새로 추가� �개� �래스를 다�과 같� 편집한다.
�래스위저드� CListenSock� 가� 함수 OnAccept()를 추가한 후 다� ��� 삽입한다.

~cpp 
	((CServerApp*)AfxGetApp())->Accept();

�래스위저드� CChildSock� 가� 함수 OnReceive()와 OnClose()를 추가한 후 다� 코드를 삽입한다.

~cpp 
	((CServerApp*)AfxGetApp())->CloseChild();
~cpp 
	((CServerApp*)AfxGetApp())->ReceiveData();
어플리케�션 �래스� 다�� 멤버변수와 함수 �형� 선언한다.

~cpp 
#include "ChildSock.h"
#include "ListenSock.h"
~cpp 
	void InitServer();
	void Accept();
	void SendData(CString& strData);
	void ReceiveData();
	void CloseChild();
	void CleanUp();
	
	CListenSock* m_pServer;
	CChildSock* m_pChild;
어플리케�션 �래스� �성��서 추가한 멤버변수를 초기화한다.

~cpp 
	m_pServer = NULL;
	m_pChild = NULL;
그리고 나서 추가한 멤버함수를 다�과 같� 정�한다.

~cpp 
void CServerApp::InitServer()
{
	m_pServer = new CListenSock;
	m_pServer->Create(7000);
	m_pServer->Listen();
}

void CServerApp::Accept()
{
	AfxMessageBox("접� 허용");
	m_pChild = new CChildSock;
	m_pServer->Accept(*m_pChild);
	m_pMainWnd->GetDlgItem(IDC_SEND)->EnableWindow(TRUE);
}
다�으로 ��터 송수신 작업� 하는 함수를 추가한다. 그 다�, ��터 송수신 후 마무리 작업� 한다.

~cpp 
void CServerApp::SendData(CString& strData)
{
	m_pChild->Send(LPCSTR(strData), strData.GetLength()+1);
	
	CString strText;
	UINT nPort;
	m_pChild->GetSockName(strText, nPort);
	strText = "[" + strText + "]" + strData;
	((CListBox*)m_pMainWnd->GetDlgItem(IDC_LIST1))->InsertString(-1, strText);
}

void CServerApp::ReceiveData()
{
	char temp[1000];
	m_pChild->Receive(temp, sizeof(temp));

	CString strText;
	UINT nPort;
	m_pChild->GetPeerName(strText, nPort);
	strText = "[" + strText + "]" + temp;
	((CListBox*)m_pMainWnd->GetDlgItem(IDC_LIST1))->InsertString(-1, strText);
}

void CServerApp::CleanUp()
{
	if (m_pChild)
		delete m_pChild;
	if (m_pServer)
		delete m_pServer;

}

void CServerApp::CloseChild()
{
	AfxMessageBox("종료");
	delete m_pChild;
	
	m_pMainWnd->GetDlgItem(IDC_SEND)->EnableWindow(FALSE);
}

리소스뷰�서 다�얼로그 항목� "IDD_SERVER_DIALOG"� 편집한다.

~cpp 
리스트박스ID : IDC_LIST1
�디트 컨트롤ID : IDC_DATA
버튼 컨트롤ID : IDC_SEND
다�얼로그가 초기화� 때 서버로 작�하�� CServerDlg �래스� OnInit Dialog()함수� 다� 코드를 삽입한다.

~cpp 
	((CServerApp*)AfxGetApp)->InitServer();
	GetDlgItem(IDC_SEND)->EnableWindow(FALSE);
그리고 나서 �래스위저드� CServerDlg� IDC_SEND를 맵핑한 후 다� 코드를 추가한다.

~cpp 
	CString strData;
	GetDlgItemText(IDC_DATA, strData);
	((CServerApp*)AfxGetApp())->SendData(strData);
	SetDlgItemText(IDC_DATA,"");

예제(���언트)


서버와 ��한 방법으로 ���언트 프로그램�서 사용할 소켓 �래스 CClientSock� �성(기초 �래스: CAsyncSocket)한다. 그리고 나서 �래스위저드� CClientSock� 가�함수 OnReceive()와 OnClose()를 추가한 후, 다� 코드를 삽입한다.

~cpp 
	((CClientApp*)AfxGetApp())->CloseChild();
~cpp 
	((CClientApp*)AfxGetApp())->ReceiveData();
서버 접�시 필요한 IP 주소를 입력받기 위해 리소스뷰�서 다�얼로그를 하나 추가한 후 다�과 같� 편집한다.

~cpp 
IP주소 컨트롤ID : IDC_IPADDRESS1
버튼 ID : IDOK, IDCANCLE
�래스위저드를 실행하여 CConnectDlg �래스를 새로 �성한 후 CConnectDlg �래스� 다� 변수를 추가한다.

~cpp 
	CString m_strAddress;
그리고 �래스위저드� CConnectDlg� IDOK를 맵핑하여 사용�가 입력한 IP 주소를 멤버변수 m_strAddress� 저장한다.

~cpp 
	GetDlgItemText(IDC_IPADDRESS1, m_strAddress);
어플리케�션 �래스� 다�과 같� 멤버변수와 함수 �형� 선언한다.

~cpp 
	#include "ClientSock.h"
~cpp 
	void Connect();
	void SendData(CString& strData);
	void ReceiveData();
	void CloseChild();
	void CleanUp();

	CClientSock* m_pClient;
어플리케�션 �래스� �성��서 추가한 멤버변수를 초기화한다.
~cpp 
	m_pClient = NULL;

그리고 나서 추가한 멤버함수를 다�과 같� 정�한다.
~cpp 
#include "ConnectDlg.h"
void CClientApp::Connect()
{
	CConnectDlg dlg;
	if (dlg.DoModal() == IDOK)
	{
		m_pClient = new CClientSock;
		m_pClient->Create();

		m_pClient->Connect(dlg.m_strAddress, 7000);
		m_pMainWnd->GetDlgItem(IDC_SEND)->EnableWindow(TRUE);
		m_pMainWnd->GetDlgItem(IDC_CONNECT)->EnableWindow(FALSE);
	}
}
�때 중요한 것� 서버 프로그램� �트 번호(7000)와 설정할 �트 번호가 �치해야 한다.
�외� ��터 송수신 과정과 마무리 작업� 서버 프로그램과 유사하다.

~cpp 
void CClientApp::SendData(CString& strData)
{
	m_pClient->Send(LPCSTR(strData), strData.GetLength()+1);
	
	CString strText;
	UINT nPort;
	m_pClient->GetSockName(strText, nPort);
	strText = "[" + strText + "]" + strData;
	((CListBox*)m_pMainWnd->GetDlgItem(IDC_LIST1))->InsertString(-1, strText);
}

void CClientApp::ReceiveData()
{
	char temp[100];
	m_pClient->Receive(temp, sizeof(temp));

	CString strText;
	UINT nPort;
	m_pClient->GetPeerName(strText, nPort);
	strText = "[" + strText + "]" + temp;
	((CListBox*)m_pMainWnd->GetDlgItem(IDC_LIST1))->InsertString(-1, strText);
}

void CClientApp::CleanUp()
{
	if (m_pClient)
		delete m_pClient;
}

void CClientApp::CloseChild()
{
	AfxMessageBox("종료");
	m_pMainWnd->GetDlgItem(IDC_SEND)->EnableWindow(FALSE);
}
리소스뷰�서 다�얼로그 항목� "IDD_CLIENT_DIALOG"� �블�릭한 후 다�과 같� 편집한다.

~cpp 
리스트 ID : IDC_LIST1
�디트 박스ID : IDC_DATA
버튼 ID : IDC_SEND, IDC_CONNECT
�래스위저드� CClientDlg� IDC_CONNECT� 맵핑한 후 다� 코드를 삽입한다.

~cpp 
	((CClientApp*)AfxGetApp())->Connect();
�래스위저드� CClientDlg� IDC_SEND를 맵핑한 후 다� 코드를 삽입한다.

~cpp 
	CString strData;
	GetDlgItemText(IDC_DATA, strData);
	((CClientApp*)AfxGetApp())->SendData(strData);
	SetDlgItemText(IDC_DATA,"");

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:18
Processing time 0.0093 sec