我用完成端口写的游戏服务器,它是处于监听,等待客户端的连接,现在数据库服务器也需要用完成端口写,但数据库服务器需主动去联多台游戏服务器,谁能给个数据库服务器简单的源代码实例程序,需用完成端口写。谢谢。
解决方案 »
- CWindow::CenterWindow函数
- ACCESS 数据源路径问题
- 在XP下,当有光盘弹入光驱时,会自动弹出选择框让你选择打开的程序,请问如何将自己的应用程序加入到选择框中?
- 有谁知道SMTP服务器之间是怎样传输邮件的!
- 这是为什么?
- dll?
- 在线等待,马上送分:怎样将Query查询的数据集全部删除,数据库SQL中的数据也删除
- 在Edit中显示二进制数
- SDK下如何debug?
- 在各位现在的实际工作中,你什么时候会用MFC?
- 刚才在VC中使用Word的VBA,其中的VBA有一段:Selection.Delete Unit:=wdCharacter, Count:=1,后来在网上搜索 wdCharacter 才知道等于 00
- 本人正在联系一个数据库应用项目该要价多少???
你正在做什么项目?跟我要做的很像。
完成端口的程序我这里有你留个地址给发给你好了。
[email protected]
[email protected]
创建client的连接socket指定为WSA_FLAG_OVERLAPPED的, 发送与接收就用WSASend和WSARecv, 其中传入overlapped结构, 这样就可以在工作者线程那里用GetQueuedCompletionStatus等待IO操作完成了.
//
//////////////////////////////////////////////////////////////////////#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_)
//
//////////////////////////////////////////////////////////////////////#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;
}