程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 服務器與客戶機互傳消息

服務器與客戶機互傳消息

編輯:關於C++

一、服務器程序

創建一個名為“server"的項目,單文檔界面。

在serverview.h中加入代碼:

#include“winsock.h"

添加變量:

      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;// 是 否 連 接
  

在serverview.cpp中重載CServerView()構造器,創建並綁定嵌套字:

   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....";
    if((status=WSAStartup(0x0101, &wsaData))==0)
    {   m_data[0] +=“Succeeded";
       m_bInitialized=TRUE;
    }
    else
    {   m_bInitialized=FALSE;
    }
    m_sock=socket(AF_INET,SOCK_DGRAM,0);
    m_data[1]=“Creating socket....";
    if(m_sock==INVALID_SOCKET)
    {   m_data[1] +=“Failed";
    }
    m_data[1] +=“Succeeded";
    m_data[2]=“Binding socket....";
    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";
       closesocket(m_sock);
    }
    m_data[2] +=“Succeeded";
    m_data[3]=“Creating listener thread....";
    unsigned long idThread;
m_hListenThread=CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)Listen,
(void    if(m_hListenThread)
    {   m_data[3] +=“Succeeded";
       m_data[4] +=“Listening....";
    }
    else
       m_data[4] +=“Failed";
}

在析構函數中完成必需的清除操作:

   CServerView:: ~CServerView()
{   if(m_bInitialized)
    WSACleanup();
    closesocket(m_sock);
    if(m_hListenThread)
    ::TerminateThread(m_hListenThread,0);
}
   

定義接收和處理消息的線程:

   long WINAPI Listen(CServerView *pView)
{   char msg[2000]=“";
    int  nchar;
    SOCKADDR_IN saClnt;
    int saClntLen;
    while(1)
    { saClntLen=sizeof(saClnt);
     nchar=recvfrom(pView ->m_sock,msg,1024,0,
(PSOCKADDR) &saClnt, &saClntLen);
     if(nchar<0)
     {   pView ->m_data[pView ->count + +] +
        =“Error in recvfrom\n";
     pView ->InvalidateRect(NULL);
     }
     else
     {switch(msg[0])
     {
     case ‘A':
     wsprintf(msg,“A:Client from %s attached\n",
         inet_ntoa(saClnt.sin_addr));
     pView ->m_data[pView ->count + +]=msg;
     pView ->flag=TRUE;
     pView ->InvalidateRect(NULL);
     pView ->Isconnect=TRUE;
     pView ->saClnt=saClnt;
     pView ->saClntLen=saClntLen;
     sendto(pView ->m_sock,msg,1024,0,(PSOCKADDR)
     &saClnt,saClntLen);
     break;
          
     case ‘D':
     wsprintf(msg,“D: Client form %s detached\n",
         inet_ntoa(saClnt.sin_addr));
     pView ->m_data[pView ->count + +]=msg;
     pView ->flag=TRUE;
     pView ->InvalidateRect(NULL);
     pView ->Isconnect=FALSE;
     sendto(pView ->m_sock,msg,1024,0,(PSOCKADDR)
     &saClnt,saClntLen);
     break;
     case ‘R':
     saClntLen=sizeof(saClnt);
     pView ->m_data[pView ->count + +]=msg;
     pView ->flag=TRUE;
     pView ->InvalidateRect(NULL);
     break;
     default:
     break;
     }
     }
       
    }
    return(0);
}

在程序菜單項中添加“本機IP地址":

   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",
( pHostEnt ->h_addr_list[0][0] & 0x00ff ),
( pHostEnt ->h_addr_list[0][1] & 0x00ff ),
( pHostEnt ->h_addr_list[0][2] & 0x00ff ),
( pHostEnt ->h_addr_list[0][3] & 0x00ff ) );
    CString out;   
    out.Format(Hostaddress);
    AfxMessageBox(out);
    }
    }
}

在程序菜單中添加“發送消息":

   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: " +Sendmessage.m_Message);
    sendto(m_sock,msg,1024,0,(PSOCKADDR)
    &saClnt,saClntLen);
    m_data[count + +]=Sendmessage.m_Message;
    flag=TRUE;
    InvalidateRect(NULL);
    }
}

為發送消息項添加一個對話框的類,名為send,有一個文本框,用來發送消息,並為文本框添加CStringm_Message變量,在ServerView.cpp中添加#include“send.h"

為發送消息項添加一個判斷函數:

   void CServerView::OnUpdateSendmessage(CCmdUI *
pCmdUI)
{// TODO: Add your command update UI handler code here
    pCmdUI ->Enable(FALSE);
    if(Isconnect)
    pCmdUI ->Enable(TRUE);
}

再窗口顯示消息:

   void CServerView::OnDraw(CDC * pDC)
{   if(flag)
    {sizeTotal.cy +=20;
     for(int j=65;j
TextOut(10,y,m_data[i]);
       y +=20;}
    // TODO: add draw code for native data here
}

在Project中點擊Settings中選擇Link項添加wsock32.lib。

----最後編譯程序,就可以得到Server.exe程序。

二、客戶機程序

創建一個名為“client"的項目,單文檔界面。

在clientview.h中加入代碼:

#include “winsock.h"

添加變量:

      CString m_data[1000];
       HANDLE   m_hListenThread;
       SOCKET   m_sock;
       SOCKADDR_IN m_saSrvr;
       BOOL Isconnect;
       int  count;
       CSize    sizeTotal;
       BOOL flag;

在構造函數中初始化變量:

   CClientView::CClientView()
{   // TODO: add construction code here
    Isconnect=FALSE;
    sizeTotal.cy=350;
    sizeTotal.cx=300;
    flag=FALSE;
}

在析構函數中完成清除操作,代碼如上。

在菜單中添加“撥號"項:

   void CClientView::OnDial()
{// TODO: Add your command handler code here
    count=5;
    if(m_bInitialized)
    {   AfxMessageBox(“Already dialing");
       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....";
     if((status=WSAStartup(0x0101, &wsaData))==0)
    {   m_data[0] +=“Succeeded";
       m_bInitialized=TRUE;}
    else
    {   m_bInitialized=FALSE;}
    m_sock=socket(AF_INET,SOCK_DGRAM,0);
    m_data[1]=“Creating socket....";
    if(m_sock==INVALID_SOCKET)
    {   m_data[1] +=“Failed";}
    m_data[1] +=“Succeeded";
    m_data[2]=“Binding socket....";
    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";
       closesocket(m_sock);}
    m_data[2] +=“Succeeded";
    m_data[3]=“Creating listener thread....";
    unsigned long idThread;
    m_hListenThread=CreateThread(NULL 0,
(LPTHREAD_START_ROUTINE)Listen,
(void *)this,0, &idThread);
    if(m_hListenThread)
    {   m_data[3] +=“Succeeded";
       m_data[4] +=“Waiting....";}
    else
    m_data[4] +=“Failed";
    InvalidateRect(NULL);
    }
}

添加一個撥號對話框,名為dial,有一個文本框用來寫IP地址.並在clientview.cpp中添加代碼:

#include dial.h

在撥號項添加一個判斷函數:

  void CClientView::OnUpdateDial(CCmdUI *
pCmdUI)
{// TODO: Add your command update UI handler code here
    pCmdUI ->Enable(TRUE);
    if(Isconnect)
    pCmdUI ->Enable(FALSE);
}

添加接收與發送消息的線程:

   long WINAPI Listen(CClientView *pView)
{   char msg[2000];
    pView ->m_data[5]=“Sending ATTACH command";
    pView ->InvalidateRect(NULL);
    wsprintf(msg,“A: ");
    sendto(pView ->m_sock,msg,1024,0,(PSOCKADDR)
    &pView ->m_saSrvr,sizeof(pView ->m_saSrvr));
    int saSrvrLen ,nchar;
    while(1)
    {saSrvrLen=sizeof(pView ->m_saSrvr);
    nchar=recvfrom(pView ->m_sock,msg,1024,0,
   (PSOCKADDR) &pView ->m_saSrvr, &saSrvrLen);
    if(nchar<0)
    {  pView ->m_data[pView ->count + +]=
        “Error in recvform";
    pView ->InvalidateRect(NULL);}
    else
    { pView ->m_data[pView ->count + +]=msg;
          pView ->Isconnect=TRUE;
          pView ->flag=TRUE;
          pView ->InvalidateRect(NULL);
       }
    }
    return(0);
}

同主程序一樣做一個發送消息項,代碼如上。

顯示程序也與主程序一樣,代碼如上。

在Project中點擊Settings中選擇Link項添加wsock32.lib。

編譯程序便可得到client.exe程序。

----server.exe和client.exe做完後,就可以在具有TCP/IP協議下的網絡中執行。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved