SOcket通信に基づくMFCによるTCP通信を実現するC/Sアーキテクチャプログラム
9882 ワード
1.プログラムの説明
開発環境はVS 2012であり、TCP接続クライアントとサービス側の通信プログラムに基づいており、サービス側IPはローカルネットワークカードipアドレスまたは127.0.0.1であり、デフォルトポートは1234である(プログラム作成中に接続ポートが1000より大きくなければ、コンピュータ内の一部のプログラムポートと衝突しやすく通信できない).
2.socketの概要
MFCクラスライブラリでは、Windows Socketsのすべての機能がほぼカプセル化されており、マイクロソフトベースクラスライブラリには、CAsyncSocketクラスが非同期ソケット(非ブロックモード)の基本機能をカプセル化している2つのベースクラスがある.CSocketクラスはCAsyncSocketクラスに割り当てられ、シリアル化機能(ブロックモード)を有する.
CAsyncSocketクラスのデータ転送手順は次のとおりです.
(1)コンストラクション関数を呼び出してソケットオブジェクトを作成する.
(2)サーバソケットが作成された場合、Bind()関数を呼び出してローカルIPとポートをバインドし、Listen()関数を呼び出してクライアント要求をリスニングする.要求が来た場合、Accept()関数を呼び出して要求が鳴ります.クライアントソケットを作成する場合は、直接関数Connect()を呼び出してサーバに接続すればよい.
(3)Send()などの機能関数を呼び出してデータ伝送と処理を行う.
(4)ソケットオブジェクトを閉じるか破棄する.
CSocketクラスのデータ転送を実現するには、次の手順に従います.
(1)CSocketクラスオブジェクトの作成;
(2)サーバ側ソケットが作成された場合、Bind()関数を呼び出してローカルIPとポートをバインドし、Listen()関数を呼び出してクライアント要求をリスニングする.要求が来た場合、Accept()関数を呼び出して要求が鳴ります.クライアントソケットを作成する場合は、直接関数Connect()を呼び出してサーバに接続すればよい.
(3)CSocketクラスオブジェクトに関連付けられたCSocketFileクラスオブジェクトを作成する.
(4)CSocketクラスオブジェクトに関連付けられたCArchiveクラスオブジェクトを作成する.
(5)CArchiveクラスオブジェクトを用いてクライアントとサーバ間でデータ転送を行う.
(6)CSocketクラス,CSocketFileクラス,CArchiveクラスの3つのオブジェクトを閉じるか破棄する.
これらの2つのステップはいずれもマイクロソフトクラスライブラリを用いて開発プロセスを行い,MFC通信開発を用いてMFCパッケージクラスライブラリを呼び出せばよい.
3.関連関数の概要
(1)struct sockaddr_in
{
short sin_family;//アドレスファミリー、すなわちアドレスフォーマットを指定し、デフォルトはAF_INETは、TCP/IPプロトコルです
unsigned short sin_port;//ポート番号
struct in_addr sin_addr;//ipアドレス
char sin_zero[8];//0を指定する必要があります
}
(2)BOOL Bind(const SOCKADDR* lpSockAddr,int nSockAddrLen);
lpSockAddrバインドするサーバアドレス構造を指定
nSockAddrLenアドレス構造の長さ
(3)BOOL Listen(int nConnectionBacklog=5);
最大リスニングクライアント数、デフォルトは5
(4)BOOL Connect(const SOCKADDR* lpSockAddr,int nSockAddrLen);
lpSockAddrサーバアドレス構造
nSockAddrLenアドレス構造長
(5)virtual int Send(const void* lpBuf,int nBufLen,int nFlags=0);
lpBuf送信対象データアドレス
nBufLen送信対象データサイズ
nFlags送信フラグ
(6)virtual int Receive(const void* lpBuf,int nBufLen,int nFlags=0);
lpBuf受信データアドレス
nBufLen受信データサイズ
nFlagsフラグ
4.キーコード
(1)サーバ側コード
開発環境はVS 2012であり、TCP接続クライアントとサービス側の通信プログラムに基づいており、サービス側IPはローカルネットワークカードipアドレスまたは127.0.0.1であり、デフォルトポートは1234である(プログラム作成中に接続ポートが1000より大きくなければ、コンピュータ内の一部のプログラムポートと衝突しやすく通信できない).
2.socketの概要
MFCクラスライブラリでは、Windows Socketsのすべての機能がほぼカプセル化されており、マイクロソフトベースクラスライブラリには、CAsyncSocketクラスが非同期ソケット(非ブロックモード)の基本機能をカプセル化している2つのベースクラスがある.CSocketクラスはCAsyncSocketクラスに割り当てられ、シリアル化機能(ブロックモード)を有する.
CAsyncSocketクラスのデータ転送手順は次のとおりです.
(1)コンストラクション関数を呼び出してソケットオブジェクトを作成する.
(2)サーバソケットが作成された場合、Bind()関数を呼び出してローカルIPとポートをバインドし、Listen()関数を呼び出してクライアント要求をリスニングする.要求が来た場合、Accept()関数を呼び出して要求が鳴ります.クライアントソケットを作成する場合は、直接関数Connect()を呼び出してサーバに接続すればよい.
(3)Send()などの機能関数を呼び出してデータ伝送と処理を行う.
(4)ソケットオブジェクトを閉じるか破棄する.
CSocketクラスのデータ転送を実現するには、次の手順に従います.
(1)CSocketクラスオブジェクトの作成;
(2)サーバ側ソケットが作成された場合、Bind()関数を呼び出してローカルIPとポートをバインドし、Listen()関数を呼び出してクライアント要求をリスニングする.要求が来た場合、Accept()関数を呼び出して要求が鳴ります.クライアントソケットを作成する場合は、直接関数Connect()を呼び出してサーバに接続すればよい.
(3)CSocketクラスオブジェクトに関連付けられたCSocketFileクラスオブジェクトを作成する.
(4)CSocketクラスオブジェクトに関連付けられたCArchiveクラスオブジェクトを作成する.
(5)CArchiveクラスオブジェクトを用いてクライアントとサーバ間でデータ転送を行う.
(6)CSocketクラス,CSocketFileクラス,CArchiveクラスの3つのオブジェクトを閉じるか破棄する.
これらの2つのステップはいずれもマイクロソフトクラスライブラリを用いて開発プロセスを行い,MFC通信開発を用いてMFCパッケージクラスライブラリを呼び出せばよい.
3.関連関数の概要
(1)struct sockaddr_in
{
short sin_family;//アドレスファミリー、すなわちアドレスフォーマットを指定し、デフォルトはAF_INETは、TCP/IPプロトコルです
unsigned short sin_port;//ポート番号
struct in_addr sin_addr;//ipアドレス
char sin_zero[8];//0を指定する必要があります
}
(2)BOOL Bind(const SOCKADDR* lpSockAddr,int nSockAddrLen);
lpSockAddrバインドするサーバアドレス構造を指定
nSockAddrLenアドレス構造の長さ
(3)BOOL Listen(int nConnectionBacklog=5);
最大リスニングクライアント数、デフォルトは5
(4)BOOL Connect(const SOCKADDR* lpSockAddr,int nSockAddrLen);
lpSockAddrサーバアドレス構造
nSockAddrLenアドレス構造長
(5)virtual int Send(const void* lpBuf,int nBufLen,int nFlags=0);
lpBuf送信対象データアドレス
nBufLen送信対象データサイズ
nFlags送信フラグ
(6)virtual int Receive(const void* lpBuf,int nBufLen,int nFlags=0);
lpBuf受信データアドレス
nBufLen受信データサイズ
nFlagsフラグ
4.キーコード
(1)サーバ側コード
#define WM_SOCKET_SERVER WM_USER+1000
// CSocket_Connect_ServerDlg
class CSocket_Connect_ServerDlg : public CDialogEx
{
//
public:
CSocket_Connect_ServerDlg(CWnd* pParent = NULL); //
//
enum { IDD = IDD_SOCKET_CONNECT_SERVER_DIALOG };
SOCKET s,s1;//
sockaddr_in addr,add1;//
int n;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
//
protected:
HICON m_hIcon;
//
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
afx_msg LRESULT OnSocketServer(WPARAM wParam, LPARAM lParam);
public:
afx_msg void OnClickedButton1();
};
BOOL CSocket_Connect_ServerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// “ ...” 。
// IDM_ABOUTBOX 。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 。 ,
//
SetIcon(m_hIcon, TRUE); //
SetIcon(m_hIcon, FALSE); //
// TODO:
n=0;
addr.sin_family=AF_INET;
addr.sin_port=htons(1234);
addr.sin_addr.S_un.S_addr=INADDR_ANY;
s=::socket(AF_INET,SOCK_STREAM,0);
::bind(s,(sockaddr*)&addr,sizeof(addr));
::listen(s,5);
GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);
GetDlgItem(IDC_STATIC)->SetWindowTextA(" !");
::WSAAsyncSelect(s,this->m_hWnd,WM_SOCKET_SERVER,FD_ACCEPT|FD_READ|FD_CONNECT);//
return TRUE; // , TRUE
}
afx_msg LRESULT CSocket_Connect_ServerDlg::OnSocketServer(WPARAM wParam, LPARAM lParam)
{
CString str13;
char cs[100] = {0};
//int err_log=listen(s,10);
//if (err_log != 0)
//{
// perror("listen");
// //close(s);
// exit(-1);
//}
switch (lParam)
{
case FD_ACCEPT: //
{
int lenth=sizeof(add1);
s1=::accept(s,(sockaddr*)&add1,&lenth);
n=n+1;
str13.Format(" %d
",n);
str13+=::inet_ntoa(add1.sin_addr);
str13+="\r
\r
";
GetDlgItem(IDC_EDIT1)->SetWindowTextA(str13);
}
case FD_READ: //
{
CString num="";
::recv(s1,cs,100,0);
GetDlgItem(IDC_EDIT1)->GetWindowTextA(num);
num += "\r
";
num += (LPTSTR)::inet_ntoa(add1.sin_addr);
num += " :";
num += (LPTSTR)cs;
GetDlgItem(IDC_EDIT1)->SetWindowTextA(num);
}
default:
break;
}
return 0;
}
void CSocket_Connect_ServerDlg::OnClickedButton1()
{
// TODO:
CString str="";
GetDlgItem(IDC_EDIT2)->GetWindowTextA(str);
if (str=="")
{
MessageBox(" !");
}
else
{
if (::send(s1,str.GetBuffer(1),str.GetLength(),0)!= SOCKET_ERROR)
{
GetDlgItem(IDC_EDIT1)->GetWindowTextA(str);
str += "\r
!\r
";
GetDlgItem(IDC_EDIT1)->SetWindowTextA(str);
}
else
{
GetDlgItem(IDC_EDIT1)->SetWindowTextA(" !\r
");
}
}
}
(2)
#define WM_SOCKET WM_USER+100
// CSocket_ConnectDlg
class CSocket_ConnectDlg : public CDialogEx
{
//
public:
CSocket_ConnectDlg(CWnd* pParent = NULL); //
//
enum { IDD = IDD_SOCKET_CONNECT_DIALOG };
SOCKET s;
sockaddr_in addr;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
//
protected:
HICON m_hIcon;
//
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnSocket(WPARAM wParam,LPARAM lParam);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnClickedButton1();
afx_msg void OnClickedButton2();
};
BOOL CSocket_ConnectDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// “ ...” 。
// IDM_ABOUTBOX 。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 。 ,
//
SetIcon(m_hIcon, TRUE); //
SetIcon(m_hIcon, FALSE); //
// TODO:
this->GetDlgItem(IDC_EDIT3)->EnableWindow(FALSE);
this->GetDlgItem(IDC_EDIT4)->EnableWindow(FALSE);
this->GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
s=::socket(AF_INET,SOCK_STREAM,0); //
::WSAAsyncSelect(s,this->m_hWnd,WM_SOCKET,FD_READ);//
return TRUE; // , TRUE
}
void CSocket_ConnectDlg::OnClickedButton1()
{
// TODO:
CString str,str1;
int port;
GetDlgItem(IDC_EDIT1)->GetWindowTextA(str);
GetDlgItem(IDC_EDIT2)->GetWindowTextA(str1);
if (str==""||str1=="")
{
MessageBox(" ");
}
else
{
port=atoi(str1.GetBuffer(1));//
addr.sin_family=AF_INET;
addr.sin_addr.S_un.S_addr=inet_addr(str.GetBuffer(1));
// IP
addr.sin_port=ntohs(port);
GetDlgItem(IDC_EDIT3)->SetWindowTextA(" ......\r
");
//
if (::connect(s,(sockaddr *)&addr,sizeof(addr)))
{
GetDlgItem(IDC_EDIT3)->GetWindowTextA(str);
str +=" !\r
";
GetDlgItem(IDC_EDIT3)->SetWindowTextA(str);
GetDlgItem(IDC_EDIT4)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE);
}
else
{
GetDlgItem(IDC_EDIT3)->GetWindowTextA(str);
str += " ! \r
";
GetDlgItem(IDC_EDIT3)->SetWindowTextA(str);
}
}
}
void CSocket_ConnectDlg::OnClickedButton2()
{
// TODO:
CString str,str1;
GetDlgItem(IDC_EDIT4)->GetWindowTextA(str);
if (str=="")
{
GetDlgItem(IDC_EDIT3)->GetWindowTextA(str1);
str1 += "\r
";
str1 += " \r
";
GetDlgItem(IDC_EDIT3)->SetWindowTextA(str1);
}
else
{
::send(s,str.GetBuffer(1),str.GetLength(),0);
//
GetDlgItem(IDC_EDIT3)->GetWindowTextA(str1);
str1 += "\r
";
str1 += str;
GetDlgItem(IDC_EDIT3)->SetWindowTextA(str1);//
}
}
LRESULT CSocket_ConnectDlg::OnSocket(WPARAM wParam,LPARAM lParam)
{
char cs[100]=""; //
if (lParam==FD_READ) //
{
CString num=""; //
recv(s,cs,100,NULL); //
GetDlgItem(IDC_EDIT3)->GetWindowText(num);
num += "\r
";
num += (LPTSTR)cs; //
GetDlgItem(IDC_EDIT3)->SetWindowText(num);//
}
return 0;
}
5. :http://download.csdn.net/detail/u011028345/9869271