從csdn上下載的該軟件的教程:
作為一個初學者,深感Socket編程入門的困難,但當把一些問題弄懂之后,回過頭來看以前遇到的一些問題,才發現 Socket編程其實並沒有那么復雜。接下來我就把我遇到的一些困難講述下,並補上解決的辦法。
首先我們要想實現一個簡單的點對點網絡通信,就應該有一個客戶和一個服務器
我們先來做客戶端。先按照如下圖所示建立好客戶對話框模塊:
首先創建一個基於MFC AppWizard[EXE] 工程,工程名為Socket__002 (這里是以我的工程名為准,你們也可以自己命名工程。)點擊確定只收選擇基本對話框,如圖:
點擊下一步,在Windows Sockets[W]處鈎上之后就點擊【完成】。
建立如圖所示的客戶端對話框:
控件屬性:
說明:IDC_EDIT1 端口號編輯框,IDC_EDIT3 發送文本框, IDC_IPADDRESS1 IPd地址框,IDC_LIST1 列表框。
現在模塊已經建好了,接下來就是寫代碼了,不過寫代碼之前我們要先理清思路。
客戶端與服務器是怎樣來實現通信的呢,其實就是由數據的發送者客戶端將要發送的信息寫入一個套接字,在通過中間環節傳輸到接收端服務器的套接字中,就可以由接收端的應用程序將套接字從中取出。因此,兩個應用程序間的數據傳輸要通過套接字來完成,至於兩個套接字間是怎么傳輸的我們就不要管了,我們只要把信息裝入套接字中就可以了。
作為一個客戶端,應該具備以下功能:
1,、向指定地址的服務器發送連接請求;
2、向已經連接成功的服務器發送信息;
3、主動斷開與服務器的連接;
當我們已經知道客戶端的功能時就應該想到,我們該怎樣用代碼實現這些功能呢;當然對於初學者來說編寫這些代碼還有點困難,我們可以先參考網絡上的資料把原理弄懂,這才是我寫這篇文章的本意。
VC6.0界面中的工作區點擊ClassView 選項卡,右擊【Socket_002 classes】-----【NewClass】添加新類 “Client_Socket” 基類為 generic CWnd。
右擊 CSocket_002Dlg 為CSocket_002Dlg 類添加共有成員變量 m_StartC;
為了使新建的類與對話框類有關聯需要在Socket_002Dlg.h頭文件中加入
#include”ClientSocket.h”記住一定要放在第一行。在類定義的public中加入 CClientSocket m_CClientSocket; 同樣的道理,在”ClientSocket.h”頭文件里加入#include” Socket_002Dlg.h”
為新添加的類Client_Socket 添加成員函數OnConnect(),函數原型void OnConnect(int nErrorCode)。在OnConnect()函數中添加如下代碼:
void CClientSocket::OnConnect(int nErrorCode)//CAsyncSocket::OnConnect { if(nErrorCode) { AfxMessageBox("連接失敗,請你重試!"); return ; } ((CSocket_002Dlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.AddString("連接服務器成功!"); ((CSocket_002Dlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.SetTopIndex( ((CSocket_002Dlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.GetCount()-1); }
接下來就是對對話框連接按鈕創建單擊函數,函數內容如下:
void CChat_ClientDlg::OnButton1() { // TODO: Add your control notification handler code here if(!m_StartC) { BYTE nFild[4]; CString sIP; UpdateData(); m_ServerIP.GetAddress(nFild[0],nFild[1],nFild[2],nFild[3]); sIP.Format("%d.%d.%d.%d",nFild[0],nFild[1],nFild[2],nFild[3]); m_CClientSocket.Create();//創建socket m_CClientSocket.Connect(sIP,m_sPort);//連接 m_StartC=~FALSE;//開始連接 } } 斷開按鈕程序: void CSocket_002Dlg::OnButton2() { // TODO: Add your control notification handler code here m_CClientSocket.Close();//關閉soket連接 m_ListWords.AddString("從服務器斷開"); m_StartC=FALSE;//斷開連接 } 發送按鈕程序: void CSocket_002Dlg::OnButton3() { // TODO: Add your control notification handler code here UpdateData(); m_CClientSocket.Send(m_sWords,m_sWords.GetLength());//發送字符串 m_ListWords.AddString("發送:"+m_sWords); m_ListWords.SetTopIndex(m_ListWords.GetCount()-1);//滾動條 } 同時在CSocket_002Dlg::OnInitDialog()中加入如下所示代碼 BOOL CSocket_002Dlg::OnInitDialog() { …… m_StartC=FALSE;//初始化窗體時,還沒有建立連接 …… }
服務器對話框Char_Server模塊
同客戶端模塊一樣創建一個Char_Server的工程,
服務器的功能:
1、 監聽;
2、 接受客戶端請求;
3、 停止監聽;
4、 接收信息;
原理同客戶端設置基本類似創建兩個類 一個用來監聽的類CListenSocket,一個用來接收信息的類CServerSocket,同樣是以generic CWnd類為基類。在”Chat_ServerDlg.h”中添加
#include"ServerSocket.h"
#include"ListenSocket.h"
再添加兩個public成員變量
CServerSocket m_ServerSocket;
CListenSocket m_ListenSocket;
接着分別在"ServerSocket.h","ListenSocket.h"頭文件中加入include”Chat_ServerDlg.h”,注意include”Chat_ServerDlg.h”放置的位置,放在預編譯之前,以防出錯。
服務器對話框
接下來就開始在創建好的CListenSocket類中添加成員函數void OnAccept(int nErrorCode) 具體怎么添加我就不做詳細說了。成員函數代碼如下:
void CListenSocket::OnAccept(int nErrorCode) { Accept(((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ServerSocket); ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ServerSocket.AsyncSelect(FD_READ|FD_CLOSE); ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.AddString("接受了一個客戶端的連接請求");//接受連接請求 ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.SetTopIndex( ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.GetCount()- } 緊接着在CServerSocket類中添加兩個成員函數:void OnReceive(int nErrorCode),void OnClose(int nErrorCode),代碼如下: void CServerSocket::OnReceive(int nErrorCode) { char SzTemp[200];//字符數組 int n=Receive(SzTemp,200);//接收到的字符串保存到SzTemp[]中。 SzTemp[n]='\0'; CString sTemp; sTemp.Format("收到:%s",SzTemp);//接收到的字符數組內容,格式化為字符串 ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.AddString(sTemp);//將接收到的內容顯示到主對話框上 ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.SetTopIndex( ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.GetCount()-1); } void CServerSocket::OnClose(int nErrorCode) { ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.AddString("客戶端斷開"); ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.SetTopIndex( ((CCSock_ChatServerDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.GetCount()-1); Close();//斷開連接 }
接下來就可以運行了,運行結果如下:
任務完成,若是有不明白的地方可以參考《Visual C++網絡編程》----主編 正阿奇;