⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lc_bcb_70.html

📁 C++Builder教学大全
💻 HTML
字号:
<html>



<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<meta name="GENERATOR" content="Microsoft FrontPage 4.0">

<meta name="ProgId" content="FrontPage.Editor.Document">

<title>服务器与客户机互传消息</title>

</head>



<body>



<p align="center"><b><font size="5">服务器与客户机互传消息</font></b>

<h3>一、 服 务 器 程 序</h3>

<ol>

  <li>创 建 一 个 名 为“server&quot; 的 项 目, 单 文 档 界 面。  

  <li>在serverview.h 中 加 入 代 码:  

    <pre>           #include “winsock.h&quot;

      添 加 变 量:

            CSize       sizeTotal;// 控 制 滚 动 条

            int   count;// 信 息 条 数

            CString m_data[1000];// 信 息 存 放

            char    Hostname[260];

            char  Hostaddress[20];// 主 机IP 地 址

            SOCKET      m_sock;

            HANDLE      m_hListenThread;// 线 程

            BOOL  m_bInitialized;// 是 否 初 始 化

            WSADATA     WSAData;

            BOOL  flag;

            SOCKADDR_IN saClnt;

            int   saClntLen;

            BOOL  Isconnect;// 是 否 连 接    

</pre>  

  <li>在serverview.cpp 中 重 载CServerView() 构 造 器, 创 建 并 绑   

    定 嵌 套 字:  

    <pre>      CServerView::CServerView()

{     // TODO: add construction code here

      Isconnect=FALSE;

      flag=FALSE;

      sizeTotal.cy=350;

      sizeTotal.cx=300;

      m_hListenThread;

      count=5;

      int status;

      WSADATA wsaData;

   m_data[0]=“initializing Windows Sockets DLL....&quot;;

      if((status=WSAStartup(0x0101, &wsaData))==0)

      {     m_data[0] +=“Succeeded&quot;;

            m_bInitialized=TRUE;

      }

      else

      {     m_bInitialized=FALSE;

      }

      m_sock=socket(AF_INET,SOCK_DGRAM,0);

      m_data[1]=“Creating socket....&quot;;

      if(m_sock==INVALID_SOCKET)

      {     m_data[1] +=“Failed&quot;;

      }

      m_data[1] +=“Succeeded&quot;;

      m_data[2]=“Binding socket....&quot;;

      sockaddr_in sa;

      sa.sin_family=AF_INET;

      sa.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

      sa.sin_port=htons(5050);

      if(bind(m_sock,(PSOCKADDR) 

     &sa,sizeof(sa))==SOCKET_ERROR)

      {     m_data[2] +=“Failed&quot;;

            closesocket(m_sock);

      }

      m_data[2] +=“Succeeded&quot;;

      m_data[3]=“Creating listener thread....&quot;;

      unsigned long idThread;

 m_hListenThread=CreateThread(NULL,0,

(LPTHREAD_START_ROUTINE)Listen,

(void        if(m_hListenThread)

      {     m_data[3] +=“Succeeded&quot;;

            m_data[4] +=“Listening....&quot;;

      }

      else

            m_data[4] +=“Failed&quot;;

} 

</pre>  

  <li>在 析 构 函 数 中 完 成 必 需 的 清 除 操 作:  

    <pre>      CServerView:: ~CServerView()

{     if(m_bInitialized)

      WSACleanup();

      closesocket(m_sock);

      if(m_hListenThread)

      ::TerminateThread(m_hListenThread,0);

}     

</pre>  

  <li>定 义 接 收 和 处 理 消 息 的 线 程:  

    <pre>      long WINAPI Listen(CServerView *pView)

{     char msg[2000]=“&quot;;

      int   nchar;

      SOCKADDR_IN saClnt;

      int saClntLen;

      while(1)

      { saClntLen=sizeof(saClnt);

        nchar=recvfrom(pView -&gt;m_sock,msg,1024,0, 

(PSOCKADDR) &saClnt, &saClntLen);

        if(nchar&lt;0)

        {     pView -&gt;m_data[pView -&gt;count + +] +

             =“Error in recvfrom\n&quot;;

        pView -&gt;InvalidateRect(NULL);

        }

        else

        {switch(msg[0])

        {

        case  ‘A':

        wsprintf(msg,“A:Client from %s attached\n&quot;,

               inet_ntoa(saClnt.sin_addr));

        pView -&gt;m_data[pView -&gt;count + +]=msg;

        pView -&gt;flag=TRUE;

        pView -&gt;InvalidateRect(NULL);

        pView -&gt;Isconnect=TRUE;

        pView -&gt;saClnt=saClnt;

        pView -&gt;saClntLen=saClntLen;

        sendto(pView -&gt;m_sock,msg,1024,0,(PSOCKADDR) 

        &saClnt,saClntLen);

        break;

                  

        case ‘D':

        wsprintf(msg,“D: Client form %s detached\n&quot;,

                inet_ntoa(saClnt.sin_addr));

        pView -&gt;m_data[pView -&gt;count + +]=msg;

        pView -&gt;flag=TRUE;

        pView -&gt;InvalidateRect(NULL);

        pView -&gt;Isconnect=FALSE;

       sendto(pView -&gt;m_sock,msg,1024,0,(PSOCKADDR) 

       &saClnt,saClntLen);

        break;



        case ‘R':

        saClntLen=sizeof(saClnt);

        pView -&gt;m_data[pView -&gt;count + +]=msg;

        pView -&gt;flag=TRUE;

        pView -&gt;InvalidateRect(NULL);

        break;



        default:

        break;

        }

        }

            

      }

      return(0);

}

</pre>  

  <li>在 程 序 菜 单 项 中 添 加“ 本 机IP 地 址&quot;:  

    <pre>    void CServerView::OnIp() 

{int WSAReturn;

 WSAReturn=WSAStartup( 0x0101, &WSAData );

 if( WSAReturn == 0 ){

 gethostname( Hostname, 260 );

 struct hostent *pHostEnt;

 pHostEnt = gethostbyname( Hostname);

 if( pHostEnt != NULL ){

 wsprintf( Hostaddress, “ %d. %d. %d. %d&quot;,

( pHostEnt -&gt;h_addr_list[0][0] & 0x00ff ),

( pHostEnt -&gt;h_addr_list[0][1] & 0x00ff ),

( pHostEnt -&gt;h_addr_list[0][2] & 0x00ff ),

( pHostEnt -&gt;h_addr_list[0][3] & 0x00ff ) );

    CString out;      

    out.Format(Hostaddress);

    AfxMessageBox(out);

    }

      }

}

</pre>  

  <li>在 程 序 菜 单 中 添 加“ 发 送 消 息&quot;:  

    <pre>    void CServerView::OnSendmessage() 

{// TODO: Add your command handler code here

      char msg[2000];

      Csend Sendmessage;

      if(Sendmessage.DoModal()==IDOK 

    & &!Sendmessage.m_Message.IsEmpty())

    { wsprintf(msg,“R: &quot; +Sendmessage.m_Message);

    sendto(m_sock,msg,1024,0,(PSOCKADDR) 

      &saClnt,saClntLen);

    m_data[count + +]=Sendmessage.m_Message;

    flag=TRUE;

    InvalidateRect(NULL);

    }

}

</pre>  

  <li>为 发 送 消 息 项 添 加 一 个 对 话 框 的 类, 名 为send,   

    有 一 个 文 本 框, 用 来 发 送 消 息, 并 为 文 本 框 添   

    加CString m_Message 变 量, 在ServerView.cpp 中 添 加 #include   

    “send.h&quot;  

  <li>为 发 送 消 息 项 添 加 一 个 判 断 函 数:  

    <pre>     void CServerView::OnUpdateSendmessage(CCmdUI * 

pCmdUI) 

{// TODO: Add your command update UI handler code here

      pCmdUI -&gt;Enable(FALSE);

      if(Isconnect)

      pCmdUI -&gt;Enable(TRUE);

}

</pre>  

  <li>再 窗 口 显 示 消 息:  

    <pre>      void CServerView::OnDraw(CDC * pDC)

{     if(flag)

      {sizeTotal.cy +=20;

       for(int j=65;j<M_DATA[COUNT - pDC { +) + i="0;i>count;i" for(int y="10;" int ASSERT_VALID(pDoc); pDoc="GetDocument();" * CServerDoc } flag="FALSE;" OnInitialUpdate(); sizeTotal.cx -1].GetLength();j>

TextOut(10,y,m_data[i]);

            y +=20;}

      // TODO: add draw code for native data here

}

</pre>  

  <li>在Project 中 点 击Settings 中 选 择Link 项 添 加wsock32.lib。</li>  

</ol>  

<p><font color="#ffffff">----</font>最 后 编 译 程 序, 就 可 以 得 到Server.exe   

程 序。  

<h3>二、 客 户 机 程 序</h3>  

<ol>  

  <li>创 建 一 个 名 为“client&quot; 的 项 目, 单 文 档 界 面。  

  <li>在clientview.h 中 加 入 代 码:  

    <pre>            #include “winsock.h&quot;

    添 加 变 量:

            CString m_data[1000];

            HANDLE      m_hListenThread;

            SOCKET      m_sock;

            SOCKADDR_IN m_saSrvr;

            BOOL  Isconnect;

            int   count;

            CSize       sizeTotal;

            BOOL  flag;

</pre>  

  <li>在 构 造 函 数 中 初 始 化 变 量:  

    <pre>      CClientView::CClientView()

{     // TODO: add construction code here

      Isconnect=FALSE;

      sizeTotal.cy=350;

      sizeTotal.cx=300;

      flag=FALSE;

}

</pre>  

  <li>在 析 构 函 数 中 完 成 清 除 操 作, 代 码 如 上。  

  <li>在 菜 单 中 添 加“ 拨 号&quot; 项:  

    <pre>      void CClientView::OnDial() 

{// TODO: Add your command handler code here

      count=5;

      if(m_bInitialized)

      {     AfxMessageBox(“Already dialing&quot;);

            return;}

      Cdial dial;

    if(dial.DoModal()==IDOK 

    & &!dial.m_HostAddress.IsEmpty())

      {m_saSrvr.sin_family=AF_INET;

       m_saSrvr.sin_addr.S_un.S_addr=htonl

(INADDR_ANY);

       m_saSrvr.sin_addr.S_un.S_addr=inet_addr

(dial.m_HostAddress);

       m_saSrvr.sin_port=htons(5050);

       int status;

       WSADATA wsaData;

       m_data[0]=“initializing Windows Sockets DLL....&quot;;

       if((status=WSAStartup(0x0101, &wsaData))==0)

      {     m_data[0] +=“Succeeded&quot;;

            m_bInitialized=TRUE;}

      else

      {     m_bInitialized=FALSE;}

      m_sock=socket(AF_INET,SOCK_DGRAM,0);

      m_data[1]=“Creating socket....&quot;;

      if(m_sock==INVALID_SOCKET)

      {     m_data[1] +=“Failed&quot;;}

      m_data[1] +=“Succeeded&quot;;

      m_data[2]=“Binding socket....&quot;;

      sockaddr_in sa;

      sa.sin_family=AF_INET;

      sa.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

      sa.sin_port=htons(0);

      if(bind(m_sock,(PSOCKADDR) 

     &sa,sizeof(sa))==SOCKET_ERROR)

      {     m_data[2] +=“Failed&quot;;

            closesocket(m_sock);}

      m_data[2] +=“Succeeded&quot;;

      m_data[3]=“Creating listener thread....&quot;;

      unsigned long idThread;

      m_hListenThread=CreateThread(NULL 0,

(LPTHREAD_START_ROUTINE)Listen,

(void *)this,0, &idThread);

      if(m_hListenThread)

      {     m_data[3] +=“Succeeded&quot;;

            m_data[4] +=“Waiting....&quot;;}

      else

      m_data[4] +=“Failed&quot;;

      InvalidateRect(NULL);

      }

}

</pre>  

  <li>添 加 一 个 拨 号 对 话 框, 名 为dial, 有 一 个 文 本 框   

    用 来 写IP 地 址. 并 在clientview.cpp 中 添 加 代 码:  

    <pre>      #include dial.h

</pre>  

  <li>在 拨 号 项 添 加 一 个 判 断 函 数:  

    <pre>    void CClientView::OnUpdateDial(CCmdUI * 

pCmdUI) 

{// TODO: Add your command update UI handler code here

      pCmdUI -&gt;Enable(TRUE);

      if(Isconnect)

      pCmdUI -&gt;Enable(FALSE);

}

</pre>  

  <li>添 加 接 收 与 发 送 消 息 的 线 程:  

    <pre>      long WINAPI Listen(CClientView *pView)

{     char msg[2000];

      pView -&gt;m_data[5]=“Sending ATTACH command&quot;;

      pView -&gt;InvalidateRect(NULL);

      wsprintf(msg,“A: &quot;);

     sendto(pView -&gt;m_sock,msg,1024,0,(PSOCKADDR)

     &pView -&gt;m_saSrvr,sizeof(pView -&gt;m_saSrvr));

      int saSrvrLen ,nchar;

      while(1)

      {saSrvrLen=sizeof(pView -&gt;m_saSrvr);

      nchar=recvfrom(pView -&gt;m_sock,msg,1024,0,

   (PSOCKADDR) &pView -&gt;m_saSrvr, &saSrvrLen);

      if(nchar&lt;0)

     {    pView -&gt;m_data[pView -&gt;count + +]=

             “Error in recvform&quot;;

      pView -&gt;InvalidateRect(NULL);}

      else

     { pView -&gt;m_data[pView -&gt;count + +]=msg;

                  pView -&gt;Isconnect=TRUE;

                  pView -&gt;flag=TRUE;

                  pView -&gt;InvalidateRect(NULL);

            }

      }

      return(0);

}

</pre>  

  <li>同 主 程 序 一 样 做 一 个 发 送 消 息 项, 代 码 如   

    上。  

  <li>显 示 程 序 也 与 主 程 序 一 样, 代 码 如 上。  

  <li>在Project 中 点 击Settings 中 选 择Link 项 添 加wsock32.lib。  

  <li>编 译 程 序 便 可 得 到client.exe 程 序。</li>  

</ol>  

<p><font color="#ffffff">----</font>server.exe 和 client.exe 做 完 后, 就   

可 以 在 具 有 TCP/IP 协 议 下 的 网 络 中 执 行。</p>  

  

</body>  

  

</html>  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -