本人是Delphi老程式員,開發Windows下異步底層通信組件已經好多年,最高性能的完成埠組件也已經實作好多年了,可以說對Winsock已經是相當熟悉,完成埠的運行機制也比較熟悉,所開發的組件應用于公司的系統,成功應答數千大資料量并發連接的考驗,應該說技術上算是比較成熟穩定了,
我開發電腦上,目前使用2個版本的Delphi,古老的Delphi7和稍微新點的XE2,Delphi7夠老,不支持64位平臺,XE2是支持的,由于系統性能一直還不錯,所以也就沒有抽出時間來對完成埠組件進行64位升級改造,最近心血來潮,決定把這個撿起來,后續會開放源代碼到Github上,原來32位的封裝有的地方也有點不合理,新的64位封裝會盡量改造好一些,介面卻會簡化,
寫這篇博客的原因,其實我早就發現Delphi的Winsock2在64位下有點問題,Winsock2.pas單元定義的WSABUF結構帶有packed字樣,表明結構是按位元組對齊,一個資料長度,一個資料指標,這個在32位程式里沒有問題,因為大家都是4位元組,無論怎么對,都是8位元組大小,換到64平臺,如果帶packed,程式運行肯定不會成功,WSABUF此時的大小應該是12位元組,這個問題在改寫一個重疊I/O的UDP組件時發現,把packed去掉WSARecvFrom和WSASendTo就可以正確呼叫,
我封裝新的64位完成埠組件的時候,發現呼叫WSARecv總回傳10014(WSAEFAULT)的錯誤,看MSDN,說是WSABUF的地址不對,系統無法訪問它,因此回傳這個10014的錯誤,如果不是有前人的經驗,大家想破腦袋,也無法解決這個問題,因為WSABUF的指標看起來不會有任何問題,實際上是微軟玩了手腳,要求WSABUF的指標必須對齊到4的倍數,換句話說,這個指標整數必須是4的倍數,NativeUInt(pBuf) mod 4=0,這里pBuf就是WSABUF指標,有如下兩篇文章可以參考,他們也發現這個問題,并解決,感謝兩位的努力和分享,文章鏈接如下:http://www.cppblog.com/Tim/archive/2011/07/07/150391.html https://blog.csdn.net/shandongmachao/article/details/48541971,
按照他們兩位的說法,我是這么解決的,代碼例子如下:
var
buf:array[0..127] of Byte;
dd:NativeUInt;
pBuf:PWSABUF;
err:Integer;
FinishLen,Flag:DWORD;
begin
FillChar(buf, SizeOf(buf), 0);
dd:=NativeUInt(@buf[0]);
dd:=dd + (WSABUF_ALIGN_NUM - dd mod WSABUF_ALIGN_NUM);
pBuf:=PWSABUF(dd);
err:=WSARecv(sock, //客戶端套接字
pBuf, //接識訓沖區
1, //緩沖區個數
FinishLen, //接收到的位元組數,完成包里有,這里不用管
Flag, //標志,必須初始化為0或有效值,否則會出錯
nil, //重疊結構
nil) ;
...
end;
這么搞一下以后,WSARecv和WSASend就正常了,
最后透露一下未來我的64位完成埠通信組件的功能,目前已經初具雛形,第一波測驗已經基本結束:
1、可以同時監聽多個埠,每個埠都可以自由控制接收發送
2、支持高性能檔案發送,使用TransmitFile API函式
3、支持高性能使用完成埠控制的檔案讀寫
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/551169.html
標籤:其他
上一篇:[Python自動化]使用Python Pexpect模塊實作自動化互動腳本使用心得
下一篇:返回列表
