winCE平台聊天器的设计

来源:互联网 发布:冰点营销软件 编辑:程序博客网 时间:2024/06/17 00:21

刚开学找了个工作,要做嵌入式方面的,用的是winCE平台,因为之前没有用过,指导我们的大虾就让我们写一个聊天器,一个是客户端的,一个是服务端,要求使用时,有服务器开启服务,然后客户端便可以连接到服务端,连接成功后双方便可以通信聊天等,我费了一周时间才基本做了出来,给各位参考参考,里面共涉及到以下知识:

VC++语言,(这个我之前可是不会的,一直用C,区别太大了。)

多线程,(创建线程,接收数据时用,我不会用非阻塞式socket,只好创建新的线程,这个要好好看看。)

socket,(socket的创建,连接,接收,发送,断开等,挺复杂的。)

下面就给出程序,供大家参考,因为前段时间重装了系统,没有vs2008,只能上传程序,没有截图,凑活看吧。


// chat_clientDlg.cpp : 实现文件// Edit by lineter// QQ: 542375845#include "stdafx.h"#include "chat_client.h"#include "chat_clientDlg.h"DWORD ReciveThread(PVOID   pArg);#ifdef _DEBUG#define new DEBUG_NEW#endif// Cchat_clientDlg 对话框Cchat_clientDlg::Cchat_clientDlg(CWnd* pParent /*=NULL*/): CDialog(Cchat_clientDlg::IDD, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void Cchat_clientDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);DDX_Control(pDX, IDC_EDIT1, idcEdit1);}BEGIN_MESSAGE_MAP(Cchat_clientDlg, CDialog)#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)ON_WM_SIZE()#endif//}}AFX_MSG_MAPON_BN_CLICKED(IDC_BUTTON1, &Cchat_clientDlg::OnBnClickedButton1)ON_BN_CLICKED(IDC_BUTTON2, &Cchat_clientDlg::OnBnClickedButton2)ON_BN_CLICKED(IDC_BUTTON3, &Cchat_clientDlg::OnBnClickedButton3)ON_EN_CHANGE(IDC_EDIT2, &Cchat_clientDlg::OnEnChangeEdit2)ON_BN_CLICKED(IDC_BUTTON4, &Cchat_clientDlg::OnBnClickedButton4)END_MESSAGE_MAP()// 接收线程DWORD ReciveThread(PVOID   pArg){// TODO: 在此添加控件通知处理程序代码Cchat_clientDlg *p=(Cchat_clientDlg *)pArg;CString csContent;//接收到的数据int recv_no=0;char cRecvBuf[100];while(1){// 清空字符串memset(cRecvBuf,0,sizeof(cRecvBuf));// 接收数据recv_no=recv(p->sockClient,cRecvBuf,100,0);// 处理接收到的数据csContent.Empty();csContent.Append((CString)cRecvBuf);csContent.Insert(0,CString("Server:"));csContent.Append(CString("\r\n"));// 调用类中显示数据的函数p->DispRecive(csContent);Sleep(1000);}return 0;}// 显示接收到的内容void Cchat_clientDlg::DispRecive(CString csContent){CString csAllcontent;// 得到文本框内容,并将数据加上顶端显示GetDlgItemText(IDC_EDIT1,csAllcontent);SetDlgItemText(IDC_EDIT1,csContent+csAllcontent);}// Cchat_clientDlg 消息处理程序BOOL Cchat_clientDlg::OnInitDialog(){CDialog::OnInitDialog();// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标// 显示默认服务器ipCString csContent;csContent="";csContent.Append(CString("192.168.3.73"));SetDlgItemText(IDC_EDIT3,csContent);return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)void Cchat_clientDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/){if (AfxIsDRAEnabled()){DRA::RelayoutDialog(AfxGetResourceHandle(), this->m_hWnd, DRA::GetDisplayMode() != DRA::Portrait ? MAKEINTRESOURCE(IDD_CHAT_CLIENT_DIALOG_WIDE) : MAKEINTRESOURCE(IDD_CHAT_CLIENT_DIALOG));}}#endifvoid Cchat_clientDlg::OnEnChangeEditIp(){// TODO:  如果该控件是 RICHEDIT 控件,则它将不会// 发送该通知,除非重写 CDialog::OnInitDialog()// 函数并调用 CRichEditCtrl().SetEventMask(),// 同时将 ENM_CHANGE 标志“或”运算到掩码中。// TODO:  在此添加控件通知处理程序代码}void Cchat_clientDlg::OnEnChangeEditPort(){// TODO:  如果该控件是 RICHEDIT 控件,则它将不会// 发送该通知,除非重写 CDialog::OnInitDialog()// 函数并调用 CRichEditCtrl().SetEventMask(),// 同时将 ENM_CHANGE 标志“或”运算到掩码中。// TODO:  在此添加控件通知处理程序代码}// 发送内容void Cchat_clientDlg::OnBnClickedButton1(){CString csContent;char cRecvBuf[100];CString csAllcontent;char cAllcontent[500];csContent = "";memset(cRecvBuf,0,sizeof(cRecvBuf));memset(cAllcontent,0,sizeof(cAllcontent));// 得到输入内容并发送GetDlgItemText(IDC_EDIT2,csContent);WCharToMByte(csContent,(LPSTR)cRecvBuf,sizeof(cRecvBuf)/sizeof(cRecvBuf[0]));send(sockClient,cRecvBuf,strlen(cRecvBuf)+1,0);// 将输入内容处理后显示csContent.Insert(0,CString("Client:"));csContent.Append(CString("\r\n"));DispRecive(csContent);}// 关闭连接void Cchat_clientDlg::OnBnClickedButton2(){// TODO: 在此添加控件通知处理程序代码DWORD ExitCode;// 线程退出码// 得到线程退出码GetExitCodeThread(handle1,&ExitCode);// 通过线程退出码结束线程TerminateThread(handle1,ExitCode);// 关闭线程句柄CloseHandle(handle1); handle1=NULL;// 关闭socketclosesocket(sockClient);WSACleanup();// 显示断开信息CString csCancel;csCancel.Append(CString("Disconnected !"));SetDlgItemText(IDC_EDIT2,csCancel);// 更改控件属性GetDlgItem(IDC_BUTTON1)-> EnableWindow(FALSE);GetDlgItem(IDC_BUTTON2)-> EnableWindow(FALSE);GetDlgItem(IDC_BUTTON4)-> EnableWindow(FALSE);GetDlgItem(IDC_BUTTON3)-> EnableWindow(TRUE);}// 建立连接void Cchat_clientDlg::OnBnClickedButton3(){// TODO: 在此添加控件通知处理程序代码CString csContent;//输入框中内容,即IP地址(CString 类型)char cIP[100];//输入框中内容,即IP地址(char    类型)csContent.Empty();//清空原始内容memset(cIP,0,sizeof(cIP));//清空字符串//得到输入框中内容并转换为char型GetDlgItemText(IDC_EDIT3,csContent);WCharToMByte(csContent,(LPSTR)cIP,sizeof(cIP)/sizeof(cIP[0]));// 创建socket,客服端wVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ){AfxMessageBox(CString("WSAStartup error"),0,0);return;}if ( LOBYTE( wsaData.wVersion ) != 1 ||        HIBYTE( wsaData.wVersion ) != 1 ){AfxMessageBox(CString("LOBYTE error"),0,0);WSACleanup( );AfxMessageBox(CString("LOBYTE OK error"),0,0);return;}sockClient=socket(AF_INET,SOCK_STREAM,0);// 客户端socket// 通过ip地址和端口和服务器连接SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=inet_addr(cIP);//addrSrv.sin_addr.S_un.S_addr=inet_addr("192.168.3.73");addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(1000);connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));// 显示连接成功信息CString csOk;csOk.Append(CString("Connected !"));SetDlgItemText(IDC_EDIT2,csOk);// 修改控件属性GetDlgItem(IDC_BUTTON1)-> EnableWindow(TRUE);GetDlgItem(IDC_BUTTON2)-> EnableWindow(TRUE);GetDlgItem(IDC_BUTTON4)-> EnableWindow(TRUE);GetDlgItem(IDC_BUTTON3)-> EnableWindow(FALSE);// 创建接收数据进程handle1=CreateThread(NULL,0,ReciveThread,this,0,NULL);}void Cchat_clientDlg::OnEnChangeEdit2(){// TODO:  如果该控件是 RICHEDIT 控件,则它将不会// 发送该通知,除非重写 CDialog::OnInitDialog()// 函数并调用 CRichEditCtrl().SetEventMask(),// 同时将 ENM_CHANGE 标志“或”运算到掩码中。// TODO:  在此添加控件通知处理程序代码}// CString转char 函数BOOL Cchat_clientDlg::WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize){DWORD dwMinSize;dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);if(dwSize+1 < dwMinSize){return FALSE;}WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE);return TRUE;}// 按键接收函数。警告:按下后将卡死至接收到数据void Cchat_clientDlg::OnBnClickedButton4(){// TODO: 在此添加控件通知处理程序代码CString csContent;CString csAllcontent;int recv_no=0;char cRecvBuf[100];// 通过socket接收数据,阻塞式recv_no=recv(sockClient,cRecvBuf,100,0);// 将接收到的数据处理后放入输入框顶端csContent.Empty();csContent.Append((CString)cRecvBuf);csContent.Insert(0,CString("Server:"));csContent.Append(CString("\r\n"));DispRecive(csContent);}

共有两个文本编辑框,4个按键,对应的头文件也有相应更改如下


// chat_clientDlg.h : 头文件//#pragma once#include <Winsock2.h>#pragma comment(lib, "Ws2.lib")#include <stdio.h>#include "afxwin.h"// Cchat_clientDlg 对话框class Cchat_clientDlg : public CDialog{// 构造public:Cchat_clientDlg(CWnd* pParent = NULL);// 标准构造函数// 对话框数据enum { IDD = IDD_CHAT_CLIENT_DIALOG };WORD wVersionRequested;WSADATA wsaData;int err;SOCKET sockClient,sockSrv;BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize);DWORD WINAPI revThread(LPVOID lpParameter);void DispRecive(CString csContent);//显示接收到的数据HANDLE   handle1;//进程的句柄protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持// 实现protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)afx_msg void OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/);#endifDECLARE_MESSAGE_MAP()public:afx_msg void OnEnChangeEdit1();afx_msg void OnEnChangeEditIp();afx_msg void OnEnChangeEditPort();afx_msg void OnBnClickedButton1();afx_msg void OnBnClickedButton2();afx_msg void OnBnClickedButton3();afx_msg void OnEnChangeEdit2();afx_msg void OnBnClickedButton4();CEdit idcEdit1;};

以上是客户端,还有服务端,和客户端很像,但也有一些不同。


// chat_serverDlg.cpp : 实现文件//#include "stdafx.h"#include "chat_server.h"#include "chat_serverDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#endifDWORD ReciveThread(PVOID   pArg);// CString转char 函数BOOL Cchat_serverDlg::WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize){DWORD dwMinSize;dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);if(dwSize+1 < dwMinSize){return FALSE;}WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE);return TRUE;}// 接收线程DWORD ReciveThread(PVOID   pArg){// TODO: 在此添加控件通知处理程序代码Cchat_serverDlg *p=(Cchat_serverDlg *)pArg;int recv_no=0;char cRecvBuf[100];CString csContent;SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);memset(cRecvBuf,0,sizeof(cRecvBuf));p->sockConn=accept(p->sockSrv,(SOCKADDR*)&addrClient,&len);p->DispInfo(CString("one connected."));p->EnableSend(TRUE);while(1){recv(p->sockConn,cRecvBuf,100,0);csContent.Empty();csContent.Append((CString)cRecvBuf);csContent.Insert(0,CString("Server:"));csContent.Append(CString("\r\n"));if(cRecvBuf[0]!=0){p->DispRecive(csContent);}else{p->EnableSend(FALSE);closesocket(p->sockConn);p->DispInfo(CString("one disconnected."));p->sockConn=accept(p->sockSrv,(SOCKADDR*)&addrClient,&len);p->DispInfo(CString("one connected."));p->EnableSend(TRUE);}}return 0;}// 是否使能发送框void Cchat_serverDlg::EnableSend(BOOL enable_send){if(enable_send){GetDlgItem(IDC_BUTTON1)-> EnableWindow(TRUE);}else{GetDlgItem(IDC_BUTTON1)-> EnableWindow(FALSE);}}// 将数据显示在文本框之上void Cchat_serverDlg::DispRecive(CString csContent){CString csAllcontent;GetDlgItemText(IDC_EDIT1,csAllcontent);SetDlgItemText(IDC_EDIT1,csContent+csAllcontent);}// 显示提示信息void Cchat_serverDlg::DispInfo(CString csContent){SetDlgItemText(IDC_EDIT2,csContent);}Cchat_serverDlg::Cchat_serverDlg(CWnd* pParent /*=NULL*/): CDialog(Cchat_serverDlg::IDD, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void Cchat_serverDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(Cchat_serverDlg, CDialog)#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)ON_WM_SIZE()#endif//}}AFX_MSG_MAPON_BN_CLICKED(IDC_BUTTON3, &Cchat_serverDlg::OnBnClickedButton3)ON_BN_CLICKED(IDC_BUTTON2, &Cchat_serverDlg::OnBnClickedButton2)ON_BN_CLICKED(IDC_BUTTON1, &Cchat_serverDlg::OnBnClickedButton1)END_MESSAGE_MAP()// Cchat_serverDlg 消息处理程序BOOL Cchat_serverDlg::OnInitDialog(){CDialog::OnInitDialog();// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标// TODO: 在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)void Cchat_serverDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/){if (AfxIsDRAEnabled()){DRA::RelayoutDialog(AfxGetResourceHandle(), this->m_hWnd, DRA::GetDisplayMode() != DRA::Portrait ? MAKEINTRESOURCE(IDD_CHAT_SERVER_DIALOG_WIDE) : MAKEINTRESOURCE(IDD_CHAT_SERVER_DIALOG));}}#endifvoid Cchat_serverDlg::OnBnClickedButton3(){// TODO: 在此添加控件通知处理程序代码WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ){return;}if ( LOBYTE( wsaData.wVersion ) != 1 ||        HIBYTE( wsaData.wVersion ) != 1 ){WSACleanup( );return;}sockSrv=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(1000);bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));listen(sockSrv,5);handle1=CreateThread(NULL,0,ReciveThread,this,0,NULL);GetDlgItem(IDC_BUTTON1)-> EnableWindow(FALSE);GetDlgItem(IDC_BUTTON2)-> EnableWindow(TRUE);GetDlgItem(IDC_BUTTON3)-> EnableWindow(FALSE);DispInfo(CString("Server start!"));}void Cchat_serverDlg::OnBnClickedButton2(){// TODO: 在此添加控件通知处理程序代码DWORD ExitCode;// 线程退出码// 得到线程退出码GetExitCodeThread(handle1,&ExitCode);// 通过线程退出码结束线程TerminateThread(handle1,ExitCode);// 关闭线程句柄CloseHandle(handle1); handle1=NULL;// 关闭socketclosesocket(sockSrv);WSACleanup();// 更改控件属性GetDlgItem(IDC_BUTTON1)-> EnableWindow(FALSE);GetDlgItem(IDC_BUTTON2)-> EnableWindow(FALSE);GetDlgItem(IDC_BUTTON3)-> EnableWindow(TRUE);// 显示断开信息DispInfo(CString("Server closed!"));}void Cchat_serverDlg::OnBnClickedButton1(){CString csContent;char cRecvBuf[100];CString csAllcontent;char cAllcontent[500];
// chat_serverDlg.h : 头文件//#pragma once#include <Winsock2.h>#pragma comment(lib, "Ws2.lib")#include <stdio.h>#include "afxwin.h"// Cchat_serverDlg 对话框class Cchat_serverDlg : public CDialog{// 构造public:Cchat_serverDlg(CWnd* pParent = NULL);// 标准构造函数// 对话框数据enum { IDD = IDD_CHAT_SERVER_DIALOG };/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/SOCKET sockSrv;SOCKET sockConn;void DispRecive(CString csContent);//显示接收到的数据HANDLE   handle1;//进程的句柄BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize);void Cchat_serverDlg::DispInfo(CString csContent);//显示信息void EnableSend(BOOL enable_send);// 是否使能发送键/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持// 实现protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)afx_msg void OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/);#endifDECLARE_MESSAGE_MAP()public:afx_msg void OnBnClickedButton3();afx_msg void OnBnClickedButton2();afx_msg void OnBnClickedButton1();};

int len=sizeof(SOCKADDR);csContent = "";memset(cRecvBuf,0,sizeof(cRecvBuf));memset(cAllcontent,0,sizeof(cAllcontent));// 得到输入内容并发送GetDlgItemText(IDC_EDIT2,csContent);WCharToMByte(csContent,(LPSTR)cRecvBuf,sizeof(cRecvBuf)/sizeof(cRecvBuf[0]));send(sockConn,cRecvBuf,strlen(cRecvBuf)+1,0);// 将输入内容处理后显示csContent.Insert(0,CString("Client:"));csContent.Append(CString("\r\n"));DispRecive(csContent);}




以上就是全部代码,有需要源文件的可以直接留言,告诉我邮箱,我会尽快发送给各位。


原创粉丝点击