我用完成端口写的游戏服务器,它是处于监听,等待客户端的连接,现在数据库服务器也需要用完成端口写,但数据库服务器需主动去联多台游戏服务器,谁能给个数据库服务器简单的源代码实例程序,需用完成端口写。谢谢。

解决方案 »

  1.   

    ~ 就是 connet 处理麻烦些, connectex 又只能在 WINXP以上版本 中才能使用.其它的和服务器差不多吧. 最近也得写一个, 不过还没开工.
      

  2.   

    不是,我的数据库服务器也是win2000,没有问题的。我的系统是三层体系架构,只不过数据库服务器要用完成端口写,把它作为游戏服务器的客户端。另外还有客户端(用户,玩家)
      

  3.   

    vcclass (黑山老妖) :
    你正在做什么项目?跟我要做的很像。
    完成端口的程序我这里有你留个地址给发给你好了。
      

  4.   

    能给我个例子吗,谢谢
    [email protected]
      

  5.   

    也给我一个吧,谢谢!
    [email protected]
      

  6.   

    创建iocp handle 的步骤与server端没有什么区别.
    创建client的连接socket指定为WSA_FLAG_OVERLAPPED的, 发送与接收就用WSASend和WSARecv, 其中传入overlapped结构, 这样就可以在工作者线程那里用GetQueuedCompletionStatus等待IO操作完成了.
      

  7.   

    // IOCPClient.h: interface for the CIOCPClient class.
    //
    //////////////////////////////////////////////////////////////////////#if !defined(AFX_IOCPCLIENT_H__B621137F_B194_4772_85AD_1241CF7687AC__INCLUDED_)
    #define AFX_IOCPCLIENT_H__B621137F_B194_4772_85AD_1241CF7687AC__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000#include <string>
    #include <vector>#define WM_SOCKET_RECV (WM_USER + 1)
    #define DATA_BUFSIZE (1024 * 2)
    #define SEND_COUNT 3
    #pragma comment (lib , "Ws2_32.lib")class CIOCPClient  
    {
    enum OVERLAPPED_TYPE{ otSend = 0, otRecv};
    typedef struct{
    OVERLAPPED m_overlapped;
    SOCKET m_socket;
    WSABUF m_wsaSendbuf;
    char m_SendBuf[DATA_BUFSIZE];
    WSABUF m_wsaRecvbuf;
    char m_Recvbuf[DATA_BUFSIZE];
    OVERLAPPED_TYPE m_otType;
    UINT m_nSend;//发送次数
    } TCompletionKey;
    public:
    CIOCPClient();
    virtual ~CIOCPClient();
    //
    static int InitSocket();
    static int CleanupSocket();
    //
    bool Connect();
    bool Disconnect();
    //
    bool Create(LPCTSTR lpIP, UINT nPort, unsigned short nSocketCount, UINT nSendCount, HWND hWnd);
    protected:
    void OnCompletionData(TCompletionKey *pCmpKey);
    //
    static unsigned WINAPI WorkThread(LPVOID lpVoid);
    //
    HANDLE GetIocpHandle() { return m_hiocp;};protected:
    HWND m_hWnd;
    //
    HANDLE m_hiocp;
    //
    unsigned short m_nSocketCount; //连接的总数
    std::string m_strIP; //连接的服务器IP
    UINT m_nPort; //连接的服务器PORT
    UINT m_nSendCount;
    std::vector<TCompletionKey> m_vCmpKey;
    volatile bool m_bWorkThreadRun;
    };#endif // !defined(AFX_IOCPCLIENT_H__B621137F_B194_4772_85AD_1241CF7687AC__INCLUDED_)
      

  8.   

    // IOCPClient.cpp: implementation of the CIOCPClient class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "TestIcop.h"
    #include "IOCPClient.h"
    #include <process.h>
    #include <algorithm>using namespace std;#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    #define Log TRACECIOCPClient::CIOCPClient()
    {
    m_hiocp = 0;
    m_nSocketCount = 0; //连接的总数
    m_strIP = ""; //连接的服务器IP
    m_nPort = 0; //连接的服务器PORT
    m_bWorkThreadRun = true;
    m_hWnd = NULL;
    m_nSendCount = SEND_COUNT;
    }CIOCPClient::~CIOCPClient()
    {}int CIOCPClient::InitSocket()
    {
    return WSAStartup(MAKEWORD(2, 2), &WSADATA());
    }int CIOCPClient::CleanupSocket()
    {
    return WSACleanup();
    }bool CIOCPClient::Create(LPCTSTR lpIP, UINT nPort, unsigned short nSocketCount, UINT nSendCount, HWND hWnd)
    {
    m_nSocketCount = nSocketCount; //连接的总数
    m_strIP = lpIP; //连接的服务器IP
    m_nPort = nPort; //连接的服务器PORT
    m_nSendCount = nSendCount;
    ASSERT(m_nSendCount > 0);
    m_hWnd = hWnd;
    m_vCmpKey.resize(m_nSocketCount);
    TCompletionKey key;
    ZeroMemory(&key, sizeof(key));
    fill(m_vCmpKey.begin(), m_vCmpKey.end(), key);
    //
    m_hiocp = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
    if(!m_hiocp)
    {
    Log("CreateIoCompletionPort failed. #%d\n", GetLastError());
    return false;
    } //create work thread:
    SYSTEM_INFO  sysInfo ;
    GetSystemInfo(&sysInfo);
    int nThreadCount = sysInfo.dwNumberOfProcessors * 2 + 2;
    UINT dwThreadID = 0;
    m_bWorkThreadRun = true;
    for(; nThreadCount; --nThreadCount)
    {
    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0
    , CIOCPClient::WorkThread, this
    , 0, NULL);
    if(hThread)
    CloseHandle(hThread);
    }
    // return true;
    }unsigned WINAPI CIOCPClient::WorkThread(LPVOID lpVoid)
    {
    CIOCPClient *pClient = (CIOCPClient*)lpVoid;
    DWORD dwBytesTrans;
    TCompletionKey *pCmpKey;
    LPOVERLAPPED lpOverlapped(0);

    while(pClient->m_bWorkThreadRun)
    {
    if(!GetQueuedCompletionStatus(pClient->GetIocpHandle(), &dwBytesTrans
    , (LPDWORD)&pCmpKey, &lpOverlapped, INFINITE))
    {
    if(dwBytesTrans == 0 || !lpOverlapped)
    {
    closesocket(pCmpKey->m_socket);
    pCmpKey->m_socket = 0;
    Log( "GetQueuedCompletionStatus failed.");
    }
    else if(lpOverlapped)
    {
    Log("Illegal call to GetQueueCompletionStatus");
    }
    continue;
    } if(dwBytesTrans <= 0)
    {
    closesocket(pCmpKey->m_socket);
    pCmpKey->m_socket = 0;
    Log("GetQueueCompletionStatus() succeed, but trans 0 byte.");
    } pClient->OnCompletionData(pCmpKey);
    }//while
    return 0;
    }
    void CIOCPClient::OnCompletionData(TCompletionKey *pCmpKey)
    {
    DWORD dwBytesTrans = 0, dwBytesSend(0), dwBytesRecv(0), dwFlags(0);
    if(pCmpKey->m_otType == otSend)
    {
    --pCmpKey->m_nSend;//发送成功, 减少次数// pCmpKey->m_wsaRecvbuf.buf = pCmpKey->m_Recvbuf;
    // pCmpKey->m_wsaRecvbuf.len = DATA_BUFSIZE;
    // pCmpKey->m_otType = otRecv;
    // WSARecv(pCmpKey->m_socket, &pCmpKey->m_wsaRecvbuf, 1, &dwBytesRecv
    // , &dwFlags, &pCmpKey->m_overlapped, NULL);
    if(pCmpKey->m_nSend){
    pCmpKey->m_otType = otSend;
    pCmpKey->m_wsaSendbuf.len = DATA_BUFSIZE;
    pCmpKey->m_wsaSendbuf.buf = pCmpKey->m_SendBuf;
    sprintf(pCmpKey->m_SendBuf, "%d", pCmpKey->m_nSend);
    WSASend(pCmpKey->m_socket, &pCmpKey->m_wsaSendbuf, 1, &dwBytesSend
    , dwFlags, &pCmpKey->m_overlapped, NULL);
    }
    }
    else if(pCmpKey->m_otType = otRecv)
    {
    SendMessage(m_hWnd, WM_SOCKET_RECV, (WPARAM)pCmpKey->m_wsaRecvbuf.buf, pCmpKey->m_socket);
    if(pCmpKey->m_nSend)
    {
    pCmpKey->m_otType = otSend;
    pCmpKey->m_wsaSendbuf.len = DATA_BUFSIZE;
    pCmpKey->m_wsaSendbuf.buf = pCmpKey->m_SendBuf;
    sprintf(pCmpKey->m_SendBuf, "%d", pCmpKey->m_nSend);
    WSASend(pCmpKey->m_socket, &pCmpKey->m_wsaSendbuf, 1, &dwBytesSend
    , dwFlags, &pCmpKey->m_overlapped, NULL);
    }
    }
    }
    bool CIOCPClient::Connect()
    {
    if(!m_nSocketCount)
    return false;
    DWORD dwBytesSend = 0, dwFlags = 0;
    for(int i = 0; i < m_nSocketCount; ++i)
    {
    TCompletionKey *pCmpKey = &m_vCmpKey[i];
    ZeroMemory(pCmpKey, sizeof(*pCmpKey));
    if((pCmpKey->m_socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
    {
    Log("WSASocket failed.");
    continue;
    }
    sockaddr_in addr;
    ZeroMemory(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(m_strIP.c_str());
    addr.sin_port = htons(m_nPort);
    if(connect(pCmpKey->m_socket, (const sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
    {
    Log("connect failed , #%d", WSAGetLastError());
    continue;
    }
    if(!CreateIoCompletionPort((HANDLE)pCmpKey->m_socket, m_hiocp, (DWORD)pCmpKey, 0))
    {
    Log("CreateIoCompletionPort failed, (bind iocp failed).");
    continue;
    }

    pCmpKey->m_otType = otSend;
    pCmpKey->m_wsaSendbuf.len = DATA_BUFSIZE;
    pCmpKey->m_wsaSendbuf.buf = pCmpKey->m_SendBuf;
    pCmpKey->m_nSend = m_nSendCount;
    sprintf(pCmpKey->m_SendBuf, "%d", pCmpKey->m_nSend);
    //for(int i = 0; i < m_nSendCount; ++i)
    WSASend(pCmpKey->m_socket, &pCmpKey->m_wsaSendbuf, 1, &dwBytesSend
    , dwFlags, &pCmpKey->m_overlapped, NULL);
    }
    return true;
    }bool CIOCPClient::Disconnect()
    {
    for(int i = 0; i < m_nSocketCount; ++i)
    {
    TCompletionKey *pCmpKey = &m_vCmpKey[i];
    closesocket(pCmpKey->m_socket);
    pCmpKey->m_socket = 0;
    }
    CloseHandle(m_hiocp);
    m_bWorkThreadRun = false;
    return true;
    }