zoukankan      html  css  js  c++  java
  • 基于VC++的WinCE网口通信

    基于VC++的WinCE网口通信

    WinCE下的网络编程与Windows下的非常类似,只是个别API函数有所不同。同样分为UDPTCP两种,UDP就是无连接的通信,通过“用户数据报协议”(UDP)来完成的;而TCP是有连接的,即传输控制协议,实现无差错无重复的顺序数据传输。

    一、UDP编程

    UDP编程相对简单:首先调用socket函数创建数据报套接字,然后调用bind函数绑定本地地址后,接着就可以调用sendtorecvfrom函数来直接发送数据和接收数据了。在sendto函数里参数to直接指定了接收方的地址和端口号,而recvfrom函数里的参数from可以直接得到接收数据的来源。

    UDP最大的特定就是不存在客户端与服务器之说,故编制的客户端程序也就是服务器端程序,下面建立一个WinCE充当客户端,而上位机的Windows做服务器。

    WinCE用参考书目1中的现成类,主要代码如下:

    #define WM_RECV_UDP_DATA WM_USER + 101     //UDP 接收数据消息

    afx_msg LONG OnRecvUdpData(WPARAM wParam,LPARAM lParam);  // UDP接收数据处理函数

    //UDP接收数据事件

    static void CALLBACK OnUdpCERecv(void * pOwner,char*buf,DWORD dwBufLen,sockaddr * addr);

    static void CALLBACK OnUdpCEError(void * pOwner,intnErrorCode);     //UDP通讯错误事件

    CUDP_CEm_CEUdp;     //定义UDP通讯类变量

    void CUDP_WinceDlg::OnBnClickedButtonOpen()        //建立,打开UDP通讯端口函数

    {

       UpdateData(TRUE);

       m_CEUdp.m_OnUdpRecv =OnUdpCERecv;

       m_CEUdp.m_OnUdpError =OnUdpCEError;

       DWORD nResult =m_CEUdp.Open(this,m_LocalPort,m_RemoteHost.GetBuffer(m_RemoteHost.GetLength()),m_RemotePort);  //Open函数包括创建UDP套接字,绑定地址,创建通讯线程,让线程开始运行等函数

       if (nResult <=0)

       {

            AfxMessageBox(_T("打开端口失败"));

       }

       else

       {

            AfxMessageBox(_T("打开端口成功"));

       }

    }

    m_CEUdp.Close();   //关闭UDP端口函数很简单,一条命令即可,纸条调用线程退出事件,通知线程退出

    void CUDP_WinceDlg::OnBnClickedButtonSend()

    {    //由于下面的SendData函数的定义原因,此处只能是发送char型数据了,不能发送unsigned char 

         char send_byte[14];

         char *buf = NULL;

         unsigned charuch1,uch2;

         send_byte[0]= 'A';    send_byte[1] = 'A'; //AA 170

         send_byte[2]= 0x0;    send_byte[3] =0x0;

         send_byte[4]= 0x0;    send_byte[5] =0xf;

         send_byte[6]= 0x1;    send_byte[7] =0xf;

     

         uch1 = (unsigned char)(num1>>8);

         send_byte[8]= char(uch1/16);

         send_byte[9]= char(uch1-(send_byte[8]*16));

         uch2 = (unsigned char)num1;

         send_byte[10]= char(uch2/16);

         send_byte[11]= char(uch2-(send_byte[10]*16));

         send_byte[12]= 'F'; send_byte[13] = 'F';

         buf =send_byte;

        

       m_CEUdp.SendData(buf,15);    //发送数据

         num1 = num1+ 1;

         delete[] buf;    //释放内存

         buf = NULL;

    }

    更多代码,参考书目1

    Windows下面的服务器代码如下:

    CSocket m_sockRecv;

    m_sockRecv.Create(5800,SOCK_DGRAM,"192.168.1.113");

    m_sockRecv.Bind(5800,"192.168.1.113");

    SetTimer(1,2000,NULL);

    void CSocket1_serverDlg::OnTimer(UINT nIDEvent)

    {

             //TODO: Add your message handler code here and/or call default

             char szRecv[20];

             CString szIP("192.168.1.112");

             //CString szIP("10.11.200.251");

             UINTnPort=5804;

             int iRecv =m_sockRecv.ReceiveFrom(szRecv,10,szIP,nPort,0);  //接受数据,此处的10是接受10个字节的数据

             TRACE("received %d byten",iRecv);

             szRecv[iRecv]='';

     

             m_sockRecv.SendTo(szRecv,iRecv,5804,"192.168.1.112",0); //将接受到的数据返回,看是否正确

     

             m_StrRecv=szRecv;

             UpdateData(FALSE);

             CDialog::OnTimer(nIDEvent);

    }

    二、TCP编程

    TCP编程相对于UDP编程而言要复杂的多,TCP服务器编程的一般流程为:首先TCP服务器端调用socket函数建立流式套接字,然后调用bind函数绑定本地地址,接着调用Listen函数进行监听客户端连接,一旦监听到客户端连接请求以后,服务器套接字就会调用Accpet函数接受客户端连接请求,并建立连接,同时服务器端会新增加一个单独的套接字与可无端进行通讯。

    对于TCP客户端来说,编程的过程就相对简单多了。首先客户端调用socket函数建立流式套接字,然后调用connect函数,请求与服务器端TCP建立连接,成功建立连接后,就可以同服务器端进行通讯了。

    1、  WinCE客户端编程

    这里主要还是参考书目1中的CTPClient_CE类来完成的,该类的主要特点是,执行Open方法后将创建一个单独的线程来检测通讯事件,检测通讯的工作通过Select函数来完成。

    2、  WinCE服务器端编程

    参考书目1中的TCP服务器端支持多个客户端连接,是典型的C/S结构。在该实例中创建CTCPServer_CECTCPCustom_CE两个类,其中CTCPServer_CE类也创建了一个线程,并通过Select函数来检测是否有客户端连接,一旦有客户端请求连接,它就负责接收此连接,并创建一个新的CTCPCustom_CE对象与客户端进行通讯,然后CTCPServer_CE类接着监听其它客户端的请求。

    CTCPCustom_CE类与上面的CTCPClient_CE类非常相似,不同的就是少了一个Connect方法,这是因为只有服务器端接收了一个客户端的连接后,才有CTCPCustom_CE类与客户端进行通讯。

    3Windows服务器端编程

    Windows服务器端编程采用的是CWSocket类来完成的,这个函数比较复杂。首先建立服务,然后开启服务(开启服务的同时,已经服务器的侦听函数带入类中),通过try,catch函数开启,然后是死循环一直在执行,通过ReadData函数读取,读的过程中使用了超时控制函数TimeoutControl;发送过程相对简单,直接调用SendData函数发送。

    参考文献

    [1] 汪兵.Windows CE 嵌入式高级编程与实例详解(C++实现),[M].中国水利水电出版社,2008

  • 相关阅读:
    http 请求头设置缓存
    手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单
    django如何用邮箱代替用户名登录
    python函数式编程学习之map,reduce,filter,sorted
    python traceback学习(转)
    python logging模块学习(转)
    python pip安装lxml失败(转)
    python下性能提示
    python移植性提示
    python测试与调试提示
  • 原文地址:https://www.cnblogs.com/fozu/p/3616079.html
Copyright © 2011-2022 走看看