我用csocket的类写了一个 服务器的程序,但只有我自己在自己的机器上运行客户端才成功,比如我服务端bind80,我在自己的机器上用ie看自己的ip,服务端可以收到客户端的信息,并返回一个信息给客户端,但我在局域网中别的机器的ie看我的ip,我的服务端可以收到它发过来的信息,但我却发不过去,但我的收发在同一个socket上的,我以前用api写的一个是可以的,难道就封装的问题吗?还是其它什么问题?
还有在使用cfile类时,我看csdn上是afx.h但我的上面没有,stdafx.h可以吗?

解决方案 »

  1.   

    有篇文章不知是否有帮助!《服务器与客户机互传消息》 一、 服 务 器 程 序
    创 建 一 个 名 为“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, 有 一 个 文 本 框, 用 来 发 送 消 息, 并 
    为 文 本 框 添 加CString m_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);
    }
      

  2.   

    再 窗 口 显 示 消 息: 
          void CServerView::OnDraw(CDC * pDC)
    {     if(flag)
          {sizeTotal.cy +=20;
           for(int j=65;jTextOut(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 协 议 下 的 网 络 中 执 行。 
     
      

  3.   

    stdafx.h一般包含afxwin.h,afxwin.h包含afx.h