在vs2008中编译通过,vs2010应该也没有问题。
使用静态MFC dll。
其他配置保持默认即可。
可能需要设置/MTD运行时。
可以实现向指定客户端ip发送信息
(该客户端必须首先连接进服务器)
从指定客户端ip中取出数据。
我使用C++类进行了封装,
对各种异常进行了处理。
进行了较详细的注释,
如果有函数不清楚,可以去msdn上查一查。
1,客户端类
#pragma once
#define RECEIVE_SIZE 1024
/****************************************************
//Client
function :
save info of client
***************************************************/
class Client
{
public:
Client();
~Client();
public:
CCriticalSection m_cs;
BYTE m_pRemainBuf[RECEIVE_SIZE]; //数据缓存区
BYTE m_nDataLen; //数据缓冲区中已有数据的长度
BYTE m_pReceBuf[RECEIVE_SIZE]; //接受到的数据
OVERLAPPED m_OverLapped;
WSABUF m_DataBuf;
SOCKADDR_IN m_ClientAddress;
//[!if NET_TYPE_TCP]
SOCKET m_hClientSock; //communication socket;
//[!endif]
public:
//***********将数据存入Client对应的缓冲区中*******************
BOOL SetData(int len);
//***********从Client对应的缓冲区中取出数据*******************
int GetData(char * buff, int len);
};
实现:
#include "stdafx.h"
#include "Client.h"
/****************************************************************************
* Name
Client
* Type
public
* Function
construction function
* Return Value
null
* Parameters
null
*****************************************************************************/
Client::Client()
{
//[!if NET_TYPE_TCP]
m_hClientSock = INVALID_SOCKET;
//[!endif]
m_nDataLen = 0;
memset(m_pRemainBuf, 0, RECEIVE_SIZE);
memset(m_pReceBuf,0,RECEIVE_SIZE);
memset(&m_OverLapped, 0, sizeof(m_OverLapped));
}
/****************************************************************************
* Name
~Client
* Type
public
* Function
* Return Value
null
* Parameters
null
*****************************************************************************/
Client::~Client()
{
int a=0;
a=3;
}
//*********************TCP接受数据************************
//**************缓冲区没有溢出,则将数据追加其后**********
BOOL Client::SetData( int len )
{
if (len<0)
{
return FALSE;
}
if (len==0)
{
return TRUE;
}
m_cs.Lock();
if (m_nDataLen+len>=RECEIVE_SIZE)
{
if (len<RECEIVE_SIZE)
{
memcpy_s(m_pRemainBuf, RECEIVE_SIZE, m_pReceBuf, len);
m_nDataLen = len;
}
else
{
memcpy_s(m_pRemainBuf, RECEIVE_SIZE, m_pReceBuf, RECEIVE_SIZE);
m_nDataLen = (BYTE)RECEIVE_SIZE;
}
}
else
{
memcpy_s(m_pRemainBuf + m_nDataLen, RECEIVE_SIZE-m_nDataLen, m_pReceBuf, len);
m_nDataLen += len;
}
m_cs.Unlock();
return TRUE;
}
int Client::GetData( char * buff, int len )
{
if (!buff)
{
return 0;
}
int result=0;
m_cs.Lock();
if (m_nDataLen <= len)
{
memcpy_s(buff, len, m_pRemainBuf, m_nDataLen);
result = m_nDataLen;
m_nDataLen = 0;
}
else
{
memcpy_s(buff, len, m_pRemainBuf, len);
memmove_s(m_pRemainBuf, RECEIVE_SIZE, m_pRemainBuf + len, m_nDataLen-len);
m_nDataLen -= len;
result = len;
}
m_cs.Unlock();
return result;
}
2,TCP完成端口的封装
头文件:
/************************************************************************/
//* 文件名称: IOCP_TCP.h
//* 文件标示:
//* 摘 要:采用完成端口技术处理网络数据
//*
//* 当前版本:1.0
//* 作 者:hxy
//* 完成日期:2013-11-16
//*
/************************************************************************/
#ifndef _COMPLETIONPORT_H__
#define _COMPLETIONPORT_H__
#include <winsock2.h>
#include <mswsock.h>
#include "afxmt.h"
#include <vector>
#include "Client.h"
using namespace std;
#pragma once
#define MAXTHREAD_COUNT 8
#define RECEIVE_SIZE 1024
#define PORT 502
class Client;
class CompletionPort
{
public:
CompletionPort();
~CompletionPort();
//************初始化****************************
// 参数: 需要绑定的ip和port
// 功能: 初始化socket库
// 设置需要绑定的ip和port
//**********************************************
BOOL Init(char * lpszHostAddress, UINT nHostPort);
//************启动***************