好象要使用多线程的,
各位大哥给个原代码好吗?

解决方案 »

  1.   

    http://www.cic.tsinghua.edu.cn/sys/book2/eight8.htm
    WinSock 2应用实例
      

  2.   

    listen(..,允许连接的客户数量)
      

  3.   

    首先在服务端要有一个listen socket:#define WM_SOCKET_CLOSED          WM_USER + 0x100
    #define WM_SOCKET_RECEIVE         WM_USER + 0x101
    #define WM_SOCKET_ACCEPT          WM_USER + 0x102 
    #define WM_MESSAGE_RECEIVED       WM_USER + 0x104
    #if !defined(AFX_LISTENSOCKET_H__1B86B62D_030A_4CCC_BD59_71626576315F__INCLUDED_)
    #define AFX_LISTENSOCKET_H__1B86B62D_030A_4CCC_BD59_71626576315F__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // ListenSocket.h : header file
    ///////////////////////////////////////////////////////////////////////////////
    // CListenSocket command targetclass CListenSocket : public CAsyncSocket
    {
    // Attributes
    public:

    // Operations
    public:
    CListenSocket();
    virtual ~CListenSocket();// Overrides
    public:
    CWnd * m_pWnd;//由它来处理事件.一般为App的CMainFrame的对象
    void SetNotifyWnd(CWnd * pWnd );
    BOOL Create(int iPort = 3000);
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CListenSocket)
    public:
    virtual void OnAccept(int nErrorCode);
    //}}AFX_VIRTUAL // Generated message map functions
    //{{AFX_MSG(CListenSocket)
    // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG// Implementation
    protected:
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_LISTENSOCKET_H__1B86B62D_030A_4CCC_BD59_71626576315F__INCLUDED_);
    //CListenSocket implementention 
    #include "stdafx.h"
    #include "Server.h"
    #include "ListenSocket.h"
    #include "ServerSocket.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CListenSocketCListenSocket::CListenSocket()
    {
    m_pWnd = NULL ;
    }CListenSocket::~CListenSocket()
    {
    }
    // Do not edit the following lines, which are needed by ClassWizard.
    #if 0
    BEGIN_MESSAGE_MAP(CListenSocket, CAsyncSocket)
    //{{AFX_MSG_MAP(CListenSocket)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    #endif // 0/////////////////////////////////////////////////////////////////////////////
    // CListenSocket member functionsvoid CListenSocket::OnAccept(int nErrorCode) 
    {
    CServerSocket *pSocket = new CServerSocket ; if ( CAsyncSocket::Accept(*pSocket)){
    if ( pSocket->AsyncSelect(FD_READ | FD_WRITE | FD_OOB | FD_CLOSE ))
    m_pWnd->PostMessage(WM_SOCKET_ACCEPT,(WPARAM)pSocket,0L);
    } CAsyncSocket::OnAccept(nErrorCode);
    }BOOL CListenSocket::Create(int iPort)
    {
    return CAsyncSocket::Create(iPort, SOCK_STREAM, FD_ACCEPT);
    }
    //该函数一定要在create后调用.
    void CListenSocket::SetNotifyWnd(CWnd *pWnd)
    {
    m_pWnd = pWnd ;
    }//还要有一个跟客户通信的socket 
    // CServerSocket.h
    #if !defined(AFX_SERVERSOCKET_H__747ABF4A_A739_44F8_8164_7178FFCBC14E__INCLUDED_)
    #define AFX_SERVERSOCKET_H__747ABF4A_A739_44F8_8164_7178FFCBC14E__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // ServerSocket.h : header file
    ///////////////////////////////////////////////////////////////////////////////
    // CServerSocket command targetclass CServerSocket : public CAsyncSocket
    {
    // Attributes
    public:// Operations
    public:
    CServerSocket();
    CServerSocket( const UINT timeout );
    virtual ~CServerSocket();// Overrides
    public:
    BOOL Create(const UINT timeout = SOCKET_RX_TIME_OUT);
    public:
    CWnd * m_pWnd;
    void SetNotifyWnd(CWnd *pWnd);
    UINT m_TimeOut;
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CServerSocket)
    public:
    virtual void OnReceive(int nErrorCode);
    virtual void OnClose(int nErrorCode);
    //}}AFX_VIRTUAL // Generated message map functions
    //{{AFX_MSG(CServerSocket)
    // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG// Implementation
    protected:
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_SERVERSOCKET_H__747ABF4A_A739_44F8_8164_7178FFCBC14E__INCLUDED_)
      

  4.   

    // ServerSocket.cpp : implementation file
    //#include "stdafx.h"
    #include "Server.h"
    #include "ServerSocket.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CServerSocketCServerSocket::CServerSocket()
    {}CServerSocket::CServerSocket( const UINT timeout )
    {
    m_TimeOut = timeout ;
    }CServerSocket::~CServerSocket()
    {
    }
    // Do not edit the following lines, which are needed by ClassWizard.
    #if 0
    BEGIN_MESSAGE_MAP(CServerSocket, CAsyncSocket)
    //{{AFX_MSG_MAP(CServerSocket)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    #endif // 0/////////////////////////////////////////////////////////////////////////////
    // CServerSocket member functionsBOOL CServerSocket::Create(const UINT timeout)
    {
    m_TimeOut = timeout ;
    m_pWnd    = NULL ;
    return CAsyncSocket::Create(0, SOCK_STREAM, FD_READ | FD_WRITE | FD_CLOSE );
    }void CServerSocket::OnReceive(int nErrorCode) 
    {
    if  ( m_pWnd )
    m_pWnd->PostMessage( WM_SOCKET_RECEIVE , (WPARAM)this , 0 );
    CAsyncSocket::OnReceive(nErrorCode);
    return ; CAsyncSocket::OnReceive(nErrorCode);
    }void CServerSocket::OnClose(int nErrorCode) 
    {
    if ( m_pWnd )
    m_pWnd->PostMessage(WM_SOCKET_CLOSED, (WPARAM)this, 0 );
    CAsyncSocket::OnClose(nErrorCode);
    }
    //该函数一定要在create后发送数据前调用.
    void CServerSocket::SetNotifyWnd(CWnd *pWnd)
    {
    m_pWnd = pWnd ;
    }
    /*说明:
    CListenSocket 和 CServerSocket都有一个成员m_pWnd ,它是处理socket收到的数据的窗口指针(也可以说是句柄),Socket只管收发数据,它并不处理数据的内容.
    在CListenSocket的OnAccept中,new的那个pSocket会被保存在App的MainFrame中的一个列表中,代码如下:
    LRESULT CMainFrame::OnSocketAccept(WPARAM wParam, LPARAM lParam)
    {
    CServerSocket *pSocket = (CServerSocket *)wParam ;
    if ( pSocket ){
    pSocket->m_pWnd = this ;
    m_aSockList.Add(pSocket);
    } return 0 ;
    }
    还有几个相关的函数如下:
    LRESULT CMainFrame::OnSocketClosed(WPARAM wParam, LPARAM lParam)
    {
    CServerSocket *pSocket = ( CServerSocket *)wParam;
    if ( pSocket ){
    int i = GetSocketIndex(pSocket);
    if ( i >= 0 ){
    pSocket->Close();
    m_aSockList.RemoveAt(i);
    delete pSocket ;
    }
    }
    return 0 ;
    }
    LRESULT CMainFrame::OnSocketReceive(WPARAM wParam, LPARAM lParam)
    {
    CServerSocket *pSocket = (CServerSocket *)wParam ; if ( !pSocket ) return -1;
    TCHAR tmpbuf[BUFFER_LEN];
    memset(tmpbuf,0,BUFFER_LEN); int iLen = pSocket->Receive(tmpbuf, BUFFER_LEN, 0); if ( iLen == 0 ) return -1 ;
             //想干什么就干什么
    return 0 ;
    }
    这几个处理函数是消息处理函数,所以在CMainFrame大消息映射表中要加上.
    ON_MESSAGE(WM_SOCKET_CLOSED, OnSocketClosed)
    ON_MESSAGE(WM_SOCKET_RECEIVE, OnSocketReceive)
    ON_MESSAGE(WM_SOCKET_ACCEPT, OnSocketAccept)
    GetSocketIndex是这样的:
    int CMainFrame::GetSocketIndex(CServerSocket *pSocket)
    {
    for ( int i = 0 ; i < m_aSockList.GetSize() ; i ++ ){
    if ( pSocket == m_aSockList.GetAt(i)){
    return i ;
    }
    }
    return -1 ;
    }
    m_aSockList被定义为CMainFrame的成员,用以保存当前建立连接的serversocket:
    CArray<CServerSocket *, CServerSocket *> m_aSockList;
    */
    最后要说明的就是在程序退出时要清空m_aSockList,代码如下:
        m_ListenSocket.Close();    for ( int i = 0 ; i < m_aSockList.GetSize() ; i ++ ){
      CServerSocket *pSocket = (CServerSocket *)   
                                          (m_aSockList.GetAt(i));
    pSocket->Close();
    delete pSocket ;
        }
        m_aSockList.RemoveAll();