我们公司是网络防火墙的,客户通过外网来访问我们的服务器资源。
我们实现的流程是:首先经过过滤包找到使用权限,可以访问我们的资源。用到的是SPI技术我现在做的是访问前台客户端,也就是Activex控件,需要在ipfliter.dll中加入QOS功能我是在
int WSPAPI WSPConnect(
SOCKET s,
const struct sockaddr FAR * name,
int namelen,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPINT lpErrno);
在WSPConnect中找到有QOS参数的,我现在想问怎么实现:通过客户端访问我们服务器时,达到限速和控制流量的功能呢?我目前的做法是:定义了一个QOS参数,在里面设置了限制的速度,和流量参数。并传递给WSPConnect中的lpSQOS参数。但是测试的时候从我们服务器上下东西,并没有起到相应的功能。请问各位高手们,我应该怎么做,才能起到限制客户端的流速和流量的功能呢? 请大侠们教我,非常着急! 谢谢!!!
我们实现的流程是:首先经过过滤包找到使用权限,可以访问我们的资源。用到的是SPI技术我现在做的是访问前台客户端,也就是Activex控件,需要在ipfliter.dll中加入QOS功能我是在
int WSPAPI WSPConnect(
SOCKET s,
const struct sockaddr FAR * name,
int namelen,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPINT lpErrno);
在WSPConnect中找到有QOS参数的,我现在想问怎么实现:通过客户端访问我们服务器时,达到限速和控制流量的功能呢?我目前的做法是:定义了一个QOS参数,在里面设置了限制的速度,和流量参数。并传递给WSPConnect中的lpSQOS参数。但是测试的时候从我们服务器上下东西,并没有起到相应的功能。请问各位高手们,我应该怎么做,才能起到限制客户端的流速和流量的功能呢? 请大侠们教我,非常着急! 谢谢!!!
解决方案 »
- directdraw显示大尺寸图片出错
- 命令行参数问题
- CRecordset::AddNew()打开MS Access数据库文件是打不开?
- 非常简单的问题,如何在MFC规则DLL里定义全局变量??我是不是很傻?:(
- 怎样实现这样的属性?类似FlexGrid控件的DataSource属性,在同一个容器里有相应数据源控件的时候,可以直接在属性页里选取?
- 這個函數取後邊的參數怎取? (10分)
- ID_FILE_NEW 操作发送的是哪个消息?
- 怎样和组合框交换数据呀? :(
- 关于使用Shell_NotifyIcon函数的问题!
- 简单问题容易得分:关于CComboBox
- 挺有用的richEdit例子,但粘贴功能不能用啊,高手帮看看
- 编译没问题,但不能运行,提示下面界面,不知道该怎么解决
lpproctable->lpWSPRecv = WSPRecv;int WSPAPI WSPSend(
SOCKET s,
LPWSABUF lpBuffers, DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
LPWSAOVERLAPPED lpOverlap
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, //执行调用的应用程序线程
LPINT lpErrno)
{}
请问是否可以在重载的WSPSend和WSPRecv函数中lpBuffers里的缓冲区char *Buff,ULONG len,做拆包并延时发送处理呢? 具体要如何实现呢? 我写过一段但有问题:不知道怎么回事:lFlowVariable //为限制的速度值
if(dwBufferCount = 1)
{
DWORD i = 0;
WSABUF SendBuffers;
DWORD m = lpBuffers->len/lFlowVariable; //计算拆包数并得到每包长度
DWORD unCount = m;
//首次发送拆包后的第一包
SendBuffers.len = m;
SendBuffers.buf = lpBuffers->buf;
nextproctable.lpWSPSend(s, &SendBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
//remanent中放的是:当前缓冲去中剩余包的长度
DWORD remanent = 0;
remanent = lpBuffers->len - m;
DWORD len2 = 0;
Sleep(m);//首次延迟的秒数
DWORD j = 0; //剩余长度的偏移量
//下面循环体实现发送当前缓冲去剩余包数
while(remanent>0)
{
j++;
len2=remanent>m?m:remanent;
SendBuffers.len = len2;
SendBuffers.buf = lpBuffers->buf+len2*j;
nextproctable.lpWSPSend(s, &SendBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
lpOverlapped, lpCompletionRoutine, lpThreadId,lpErrno);
if( j == m )
{
SendBuffers.len = len2;
SendBuffers.buf = lpBuffers->buf+m*i;
nextproctable.lpWSPSend(s, &SendBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
lpOverlapped, lpCompletionRoutine, lpThreadId,lpErrno);
break;
}
remanent = remanent - m;
if(unCount--) //此处现实限速功能
{
Sleep(m);
}
}
WriteLog("WSPSend:SOCKET=%ld:dwBufferCount=%ld:len=%ld",
s,dwBufferCount,lpBuffers->len);
return nextproctable.lpWSPSend(s, &SendBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
}
}
/*
else
{
WSABUF SendBuffers;
for(DWORD i = 0;i<dwBufferCount; i++) //循环体根据缓冲区的个数
{
if((lpBuffers+i)->len != 0) //判断缓冲区偏移量的长度是否为零
{
DWORD m = (lpBuffers+i)->len/lFlowVariable; //计算拆包数并得到每包长度
DWORD unCount = m;
//首次发送拆包后的第一包
SendBuffers.len = m;
SendBuffers.buf = (lpBuffers+i)->buf;
nextproctable.lpWSPSend(s, &SendBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
//remanent中放的是:当前缓冲去中剩余包的长度
DWORD remanent = 0;
remanent = (lpBuffers+i)->len - m;
DWORD len2 = 0;
Sleep(m);//首次延迟的秒数
DWORD j = 0; //剩余长度的偏移量
//下面循环体实现发送当前缓冲去剩余包数
while(remanent>0)
{
j++;
len2=remanent>m?m:remanent;
SendBuffers.len = len2;
SendBuffers.buf = (lpBuffers+i)->buf+len2*j;
nextproctable.lpWSPSend(s, &SendBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
lpOverlapped, lpCompletionRoutine, lpThreadId,lpErrno);
if( j == m )
{
SendBuffers.len = len2;
SendBuffers.buf = (lpBuffers+i)->buf+m*i;
nextproctable.lpWSPSend(s, &SendBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
lpOverlapped, lpCompletionRoutine, lpThreadId,lpErrno);
break;
}
remanent = remanent - m;
if(unCount--) //此处现实限速功能
{
Sleep(m);
}
}
}
}
}
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
char szExePath[512]={0};
GetModuleFileName(NULL,szExePath,512);
DebugTrace("[NetLimitRecv]The recv Applaction is %s",szExePath);
DebugTrace("[NetLimitRecv]The dwBufferCount is %d",dwBufferCount);
DebugTrace("[NetLimitRecv]The *lpNumberOfBytesRecvd is %d before lpWSPRecv call",
*lpNumberOfBytesRecvd); if(lpOverlapped&&lpCompletionRoutine)
{
DebugTrace("[NetLimitRecv]The recv is overlapped.");
} int iret=0;
if(*lpNumberOfBytesRecvd<4096)
{
DebugTrace("[NetLimitRecv]<4096 don't reduce packet.");
iret=NextProcTable.lpWSPRecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,
lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno); for(DWORD i=0;i<dwBufferCount;i++)
DebugTrace("[NetLimitRecv]the buf klen:%d",lpBuffers[i].len);
}else
{
DebugTrace("[NetLimitRecv]>4096 reduce the packet.");
DWORD dwRecv=4096;
char *pbuf=lpBuffers[0].buf;
DWORD dwRecvCount=0;
while(dwRecvCount<*lpNumberOfBytesRecvd)
{
WSABUF tmp={0};
tmp.buf=pbuf+dwRecvCount;
tmp.len=4096;
DebugTrace("[NetLimitRecv]lpBuffers[0].len is %d",lpBuffers[0].len); if(*lpNumberOfBytesRecvd-dwRecvCount<4096)//如果差值小于4096了,那么就接受最后一个包。
{
tmp.len=*lpNumberOfBytesRecvd-dwRecvCount;
dwRecv=*lpNumberOfBytesRecvd-dwRecvCount;
} iret=NextProcTable.lpWSPRecv(s,&tmp,1,&dwRecv,lpFlags,
lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno);
if(iret==0&&dwRecv!=0)
{
DebugTrace("[NetLimitRecv]4096 limit recv suc!dwRecvCount %d,dwRecv %d",
dwRecvCount,dwRecv);
dwRecvCount+=dwRecv;
}else
{
DebugTrace("[NetLimitRecv]recv err %d,dwRecv %d",iret,dwRecv);
break;
}
}
*lpNumberOfBytesRecvd=dwRecvCount;
}
DebugTrace("[NetLimitRecv]The *lpNumberOfBytesRecvd is %d end lpWSPRecv call",
*lpNumberOfBytesRecvd); return iret;
}