walker
驱动牛犊
驱动牛犊
  • 注册日期2001-10-31
  • 最后登录2004-06-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1779回复:3

为什么会丢包

楼主#
更多 发布于:2001-12-14 16:56


     我用了DDK例子的PACKET来收IP包,可发现会存在丢包现象。
 不知是否是程式的毛病。
    我用SNIFFER不会丢包。SNIFFER也写一个sniffer.sys.

   请哪位高手能有解决不丢包的方法,SOS!!!!
                        
walker_zjs
maomao
驱动牛犊
驱动牛犊
  • 注册日期2001-06-22
  • 最后登录2002-12-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2001-12-14 17:11
packet中的收包函数太简单了,没有将接收的缓冲利用好,要想解决不丢包的方法是:组织环形的buffer管理机制,简单来说,缓冲区对收包很关键啊!
你可以参考windump的缓冲管理机制.
[color=red]我只想好好呼吸一下...[/color]
liuhb
驱动牛犊
驱动牛犊
  • 注册日期2001-09-25
  • 最后登录2002-03-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2001-12-14 18:17
用重叠I/O可以提高些性能,往下提交I/O和接收数据用分开的线程,
当然,packet本身也可以改进。
混在深圳
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
地板#
发布于:2001-12-14 21:03
用重叠I/O可以提高些性能,往下提交I/O和接收数据用分开的线程,
当然,packet本身也可以改进。



下面是我98年写的一段代码中的通过packet.sys sniffer
数据包的代码。因为在武汉白云站上曾经有人问过类似的
问题,当时我也曾经贴过。sysinternals版的chyang还曾经
提过一个改进意见,认为event不应该cloaehandle之后又
createevent,而应该复用,我认为他说的很有道理,这样
效率会更高一些。在这里我没有改过来,因为我比较懒。

工作线程应该是for(;;)调用该函数。

这个函数是block的,因此如果要退出程序的时候,有可能
因为这个函数block,无法体面的退出线程,需要用
terminatethread,这显然不够好。解决这个问题的方法
是,增加一个入口参数或者全局变量,hStopEvent,然后
每次waitmultiobject的时候不是等待32个event,而是
33个。当主线程需要退出该线程的时候,只要setevent(
hstopevent),waitmultiobject就会返回,然后判断
返回的event,如果是hstopevent,就返回一个ret_stop,
(需要把这个函数的返回值改为int,而不是boolean)
然后工作线程的for循环判断返回值就可以return 了。
这种退出方法比较体面干净。

希望以后不要再有人提类似的问题:-)。我有点厌倦。

BOOLEAN
RecvPacket(
BYTE *pbuf,
int *piAdapterNum,
PULONG BytesReceived
)
{
static int          iReadAdapterNum=0;
    BOOLEAN Result;
static PACKET       Packet[32];
static HANDLE       hEvent[32];
DWORD dwByteReceive;
HANDLE              hEventTemp;
int i,j,k;
if(g_bFirstCall)  // if first call ,let\'s call 32 times readfile first
{
for(i=0;i<32;i++)
{
   Packet.OverLapped.Offset=0;
Packet.OverLapped.OffsetHigh=0;
       Packet.OverLapped.hEvent=CreateEvent(
                        0,
                        TRUE,  
                        FALSE,
                        NULL
                        );    // manual reset,initial=false
hEvent=Packet.OverLapped.hEvent;
Packet.Length =1514;  // if someone shit send a packet>>1514,what\'s happen?
Result=ReadFile(
     Adapter[iReadAdapterNum].hFile,
 Packet.Buffer,
             Packet.Length,
         &dwByteReceive,
     &Packet.OverLapped
 );
Packet.iAdapterNum =iReadAdapterNum;
iReadAdapterNum++;
iReadAdapterNum=iReadAdapterNum%g_iAdapterNum;  // need use a global
}
g_bFirstCall=false;
}
        
i= WaitForMultipleObjects(  // which read return?
32,            
hEvent,  
false,         //  wait untill one hevent signal
INFINITE       //  wait ever
);
if(i==WAIT_FAILED) return false;
for(j=0;j<32;j++)
if(Packet[j].OverLapped.hEvent ==hEvent) break;  // which read return?
k=j;
dwByteReceive=0;
    Result=GetOverlappedResult(
                   Adapter[Packet[k].iAdapterNum].hFile,
                   &Packet[k].OverLapped,
                   &dwByteReceive,
                   false
                   );

if(!Result)
{
AfxMessageBox(\"!!!\");
return false;
}
*piAdapterNum=Packet[k].iAdapterNum ;  // return value
memcpy((void *)pbuf,(void *)Packet[k].Buffer,dwByteReceive);
    *BytesReceived=dwByteReceive;
CloseHandle(Packet[k].OverLapped.hEvent);
for(j=i;j<32;i++)
hEvent=hEvent[++j];
hEventTemp=CreateEvent(0, TRUE, 0, NULL);
if(!hEventTemp) {
MessageBox(NULL,\"Can not create event\",NULL,MB_OK);
return false;
}
Packet[k].OverLapped.hEvent=hEventTemp;
memset(Packet[k].Buffer,0,1514);
Packet[k].Length =1514;
hEvent[31]=hEventTemp;
        
// k返回了,就再读K一次
Result=ReadFile(
     Adapter[Packet[k].iAdapterNum].hFile,
 Packet[k].Buffer,
             Packet[k].Length,
         &dwByteReceive,
     &Packet[k].OverLapped
 );
    return Result;
}
不再回忆从前,我已经生活在幸福当中。
游客

返回顶部