???????

最近自己因?yàn)閷?shí)際需要,用winpcap開(kāi)發(fā)一個(gè)程序里面有需要轉(zhuǎn)發(fā)包.自己就寫了一個(gè),發(fā)現(xiàn)轉(zhuǎn)發(fā)時(shí)延>500ms.也確實(shí)把自己嚇到了.便把轉(zhuǎn)發(fā)的那段代碼開(kāi)始精減,大致如下
while((j=pcap_next_ex(slecadopt,&pkt_header,(const?u_char**)&pkt_data))>=0)


{???
?????if(j==0)

?????
{
?????continue;
?????}
?????if(*(unsigned?short?*)(pkt_data+12)==htons(ETH_IP)&&(!(memcmp(pkt_data+6,myip->mac,6)==0))&&*(unsigned?long?*)(pkt_data+30)!=myip->ip&&(!(memcmp(pkt_data,bcast,6)==0)))

?????
{?
?????for(z=Pipmachead;z!=NULL;z=z->next)

?????
{
?????????if(*(unsigned?long?*)(pkt_data+30)==z->ip)

?????????????
{
?????????????????????? ?memcpy(cmac->mac,z->mac,6);
??????????????????????? memcpy(cmac->mac+6,myip->mac,6);
????????????????????????memcpy(sendbuf,pkt_data,pkt_header->caplen);
??????????????????????? memcpy(sendbuf,cmac,12);
?????????????????????? pcap_sendpacket(slecadopt,sendbuf,pkt_header->caplen);??????
?????????}?
?????????continue;
?????}
?????}
}??????? 過(guò)程很簡(jiǎn)單,pcap_next_ex()收包,在做判斷處理,然后用pcap_sendpacket()發(fā)包.

怎么想都不會(huì)有那么大的時(shí)延.很不解就搜索了下關(guān)于pcap_sendpacket()發(fā)包效能的網(wǎng)頁(yè),其中有一個(gè)
http://community.csdn.net/Expert/TopicView3.asp?id=4153633來(lái)里面有人說(shuō)
我用winpcap做個(gè)一個(gè)初步的試驗(yàn),我得機(jī)器是奔4?2。6,內(nèi)存512,我一個(gè)線程接包,一個(gè)線程收包,用動(dòng)態(tài)連表做緩存,一秒鐘轉(zhuǎn)發(fā)1-2個(gè)包沒(méi)有多大問(wèn)題,要是再多了,就會(huì)又丟包,轉(zhuǎn)發(fā)上千萬(wàn)包要丟幾百個(gè)。還有人說(shuō)
winpcap的sendpacket超級(jí)慢,而且延遲很大。

我試圖實(shí)現(xiàn)一個(gè)bridge,即一個(gè)端口進(jìn)入的包不經(jīng)修改從一個(gè)端口出,反之亦然。結(jié)果ping的結(jié)果顯示延遲為數(shù)百毫秒級(jí)別,個(gè)別時(shí)候甚至到了1秒。運(yùn)行其它應(yīng)用更是不可忍受。

我想使用sendQuene,結(jié)果sendQuene的具體用法只見(jiàn)過(guò)預(yù)先準(zhǔn)備好所有的包然后整體發(fā)送的,沒(méi)見(jiàn)過(guò)隨著包來(lái)隨著發(fā)送的例子。或許對(duì)于我的bridge,winpcap是一個(gè)錯(cuò)誤的選擇?又或者大家有什么新鮮的思路?愿意聽(tīng)大家說(shuō)說(shuō)。???? ?? 使我也開(kāi)始懷疑pcap_sendpacket()了.難道真實(shí)pcap_sendpacket()效率底.但是我還是不相信.堂堂winpcap怎么可能怎么慢.使我發(fā)現(xiàn)破綻的使貼子里最后一的人的說(shuō)法:
我也寫了個(gè)類似的程序,延時(shí)穩(wěn)定在20ms左右,帶寬可以達(dá)到10M
我發(fā)現(xiàn)一個(gè)有趣的事情,即我在運(yùn)行brigde的服務(wù)器上,運(yùn)行一個(gè)fluke的抓包工具,居然發(fā)現(xiàn)運(yùn)行后,通過(guò)bridge后的時(shí)延居然只有1ms左右了,停止抓包工具后,延時(shí)又回到20ms左右,試了多次情況都一樣

打開(kāi)網(wǎng)卡的句柄是按下面的參數(shù)執(zhí)行的
pcap_open(d->name,?//?name?of?the?device?
65536,?//?portion?of?the?packet?to?capture.
PCAP_OPENFLAG_PROMISCUOUS,?//?promiscuous?mode?
1,?//?read?timeout?
NULL,?//?remote?authentication?
errbuf?//?error?buffer?
);?
對(duì)數(shù)據(jù)報(bào)的捕獲是用pcap_loop函數(shù),我試過(guò)將pcap_open的read?timeout參數(shù)設(shè)置為-1,即讀取立即返回,但這樣對(duì)系統(tǒng)資源占用太大,cpu利用率增加到100%,此時(shí)bridge的延時(shí)就很不穩(wěn)定了,從1ms到1s都有。?????? 他在里面特意提到了pcap_open()的read timeout參數(shù),我回想起我的設(shè)的1000ms,也就是一秒.嫌疑很大.(注:我用的是pcap_open_live())
pcap_open_live(d->name,?1000,?1,?1000,?error)然后就去查Winpcap的官方資料
http://www.winpcap.org/docs/docs31/html/group__wpcapfunc.html里面說(shuō)的很清楚:
to_ms?specifies?the?read?timeout?in?milliseconds.?The?read?timeout?is?used?to?arrange?that?the?read?not?necessarily?return?immediately?when?a?packet?is?seen,?but?that?it?wait?for?some?amount?of?time?to?allow?more?packets?to?arrive?and?to?read?multiple?packets?from?the?OS?kernel?in?one?operation.????? 當(dāng)已經(jīng)發(fā)現(xiàn)包之后還會(huì)等多一些的包一起返回,等待時(shí)間就是read timeout.明白了,我把read timeout設(shè)為1以后時(shí)延降到了<10ms.
?????其中還需要提醒的是用Ethereal等一些抓包工具看到收包到轉(zhuǎn)發(fā)時(shí)延很大時(shí)就以為是pcap_next_ex()和pcap_sendpacket()函數(shù)之間的處理造成了時(shí)延.這里容易給我們產(chǎn)生一個(gè)假相.以為網(wǎng)卡收到包的時(shí)刻就是轉(zhuǎn)發(fā)程序就要開(kāi)始處理.實(shí)際上pcap_next_ex()還在等待更多的包一起返回.
?????所以事發(fā)的原因離事發(fā)現(xiàn)場(chǎng)比較遠(yuǎn).在pcap_open()那.程序就就是怎么千絲萬(wàn)縷的關(guān)聯(lián)著.
???? 大家一定要多懷疑自己,別去怪罪工具.winpcap很無(wú)辜的.嘻嘻!!
肚子餓了去吃飯
!!
?????????????????????????????????????????????????????????????????????-----saga.constantine