读书人

运用CAsyncSocket类进行网络编程

发布时间: 2013-01-28 11:49:56 作者: rapoo

使用CAsyncSocket类进行网络编程
1 服务器端

由先得专门为服务器端做一个Socket通信类CNewSocket类,此类继承CAsyncSocket类,专门负责服务器端socket通信事情:

NewSocket.h:

// SocketTestDlg.cpp : implementation file//#include "stdafx.h"#include "SocketTest.h"#include "SocketTestDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialogEx{public:CAboutDlg();// Dialog Dataenum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support// Implementationprotected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CSocketTestDlg dialogCSocketTestDlg::CSocketTestDlg(CWnd* pParent /*=NULL*/): CDialogEx(CSocketTestDlg::IDD, pParent), m_Address(_T("127.0.0.1")), m_Port(0), m_MsgS(_T("")), m_nTryTimes(0){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CSocketTestDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);DDX_Text(pDX, IDC_ET_IPADDRESS, m_Address);DDX_Text(pDX, IDC_ET_PORT, m_Port);DDX_Control(pDX, IDC_LIST_R, m_MsgR);DDX_Text(pDX, IDC_ET_SEND, m_MsgS);}BEGIN_MESSAGE_MAP(CSocketTestDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BT_CLEAR, &CSocketTestDlg::OnBnClickedBtClear)ON_BN_CLICKED(IDOK, &CSocketTestDlg::OnBnClickedOk)ON_BN_CLICKED(IDC_BT_CONNECT, &CSocketTestDlg::OnBnClickedBtConnect)ON_WM_TIMER()ON_BN_CLICKED(IDC_BT_SEND, &CSocketTestDlg::OnBnClickedBtSend)ON_BN_CLICKED(IDC_BT_CLOSE, &CSocketTestDlg::OnBnClickedBtClose)END_MESSAGE_MAP()// CSocketTestDlg message handlersBOOL CSocketTestDlg::OnInitDialog(){CDialogEx::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.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);}}// Set the icon for this dialog.  The framework does this automatically//  when the application's main window is not a dialogSetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE);// Set small icon// TODO: Add extra initialization herereturn TRUE;  // return TRUE  unless you set the focus to a control}void CSocketTestDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}}// If you add a minimize button to your dialog, you will need the code below//  to draw the icon.  For MFC applications using the document/view model,//  this is automatically done for you by the framework.void CSocketTestDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}}// The system calls this function to obtain the cursor to display while the user drags//  the minimized window.HCURSOR CSocketTestDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CSocketTestDlg::OnBnClickedBtClear(){// TODO: Add your control notification handler code herem_MsgR.ResetContent();}void CSocketTestDlg::OnBnClickedOk(){// TODO: Add your control notification handler code here/*CDialogEx::OnOK();*/UpdateData(TRUE);if(m_MsgS.IsEmpty()){AfxMessageBox(_T("please type the message you want to send!"));return;}}void CSocketTestDlg::OnBnClickedBtConnect(){// TODO: Add your control notification handler code here//如果当前已经与服务器建立了连接,则直接返回if(m_ClientSocket.m_bConnected){AfxMessageBox(_T("当前已经与服务器建立连接"));return;}UpdateData(TRUE);if(m_Address.IsEmpty()){AfxMessageBox(_T("服务器的IP地址不能为空!"));return;}if(m_Port <=1024){AfxMessageBox(_T("服务器的端口设置非法!"));return;}//使Connect按键失能GetDlgItem(IDC_BT_CONNECT)->EnableWindow(FALSE);//启动连接定时器,每1秒中尝试一次连接SetTimer(1,1000,NULL);}void CSocketTestDlg::OnTimer(UINT_PTR nIDEvent){// TODO: Add your message handler code here and/or call defaultif(m_ClientSocket.m_hSocket ==INVALID_SOCKET){BOOL bFlag =m_ClientSocket.Create(0,SOCK_STREAM,FD_CONNECT); //创建套接字if(!bFlag){AfxMessageBox(_T("Socket创建失败!"));m_ClientSocket.Close();PostQuitMessage(0);//退出return;}}m_ClientSocket.Connect(m_Address,m_Port);//连接服务器if(m_nTryTimes >=10){KillTimer(1);AfxMessageBox(_T("连接失败!"));GetDlgItem(IDC_BT_CONNECT)->EnableWindow(TRUE);return;}else if(m_ClientSocket.m_bConnected){KillTimer(1);GetDlgItem(IDC_BT_CONNECT)->EnableWindow(TRUE);return;}CString strTextOut =_T("尝试连接服务器第");m_nTryTimes ++;CString str;str.Format(_T("%d"),m_nTryTimes);strTextOut +=str;strTextOut +=_T("次...");m_MsgR.InsertString(0,strTextOut);CDialogEx::OnTimer(nIDEvent);}void CSocketTestDlg::OnBnClickedBtSend(){// TODO: Add your control notification handler code hereUpdateData(TRUE);if(m_ClientSocket.m_bConnected){//将用户输入的数据从CString转化为char *字符串,即Unicode-->ANSI,并保存到m_ClientSocket.m_szBuffer中int len =WideCharToMultiByte(CP_ACP,0,m_MsgS,-1,NULL,0,NULL,NULL);WideCharToMultiByte(CP_ACP,0,m_MsgS,-1,m_ClientSocket.m_szBuffer,len,NULL,NULL );m_ClientSocket.m_nLength =strlen(m_ClientSocket.m_szBuffer);m_ClientSocket.AsyncSelect(FD_WRITE);//触发写事件m_MsgS =_T("");UpdateData(FALSE);}}void CSocketTestDlg::OnBnClickedBtClose(){// TODO: Add your control notification handler code herem_ClientSocket.ShutDown();EndDialog(0);}

OK,完!

读书人网 >编程

热点推荐