因為我必須用一個Client Socket 以跑 loop 的方式傳同樣的一份資料給很多個neighbor BSs,所以遇到了這個問題。
Encode_DATA();
for(i = 0; i < neighbor_number; i++)
{Socket->Address = Neighbor_DB[i].IP_Addr;
Socket->Port = Neighbor_Port;
Socket->Open();
Socket->SendBuf(&Data_Buf, Data_length);
Socket->Close();
}
起初,兩台BS互傳,接收端沒有收到任何東西,所以把socket轉向到我寫的echo server去,但echo server也是什麼都沒收到,還試過一次傳很多資料(怕是有buffer住的情況),也試過用另一個socket傳送(還是失敗了)。
陷入困境,開始把程式碼到處亂移,把不必要的部分全部註解掉,甚至把loop也註解掉,結果最後發現,連續傳送兩次的話,只有第二次送出的資料會傳到echo server,又進一步發現,只有偶數次的傳送會成功,雖然是一大發現,但還是摸不著頭緒。
發呆,亂晃,隨手開了BCB的Help逛逛TClientSocket的各種Methods看看有沒有出清buffer的方法,結果沒有。再看看一堆Property,忽然看到ClientType的值分為Blocking和NonBlocking,隱約覺得:「好像就是這個。」
Description裡面說,NonBlocking是讓Socket的讀、寫動作不會讓程式的運作中斷,在我的想法又可以解釋為,讀、寫的動作不會馬上執行,而可能會先執行後面的程式碼,所以我的Socket->Close()可能比Socket->SendBuf()還先執行,那想當然資料送不出去囉。
而設定為Blocking,便可以使Socket的任何讀、寫動作先中斷程式的進行,等讀、寫動作完成之後,程式再繼續跑下去。果不其然,這個bug莫名其妙的解決了…
補述:
後來用google查 socket, nonblocking 找到 gracefully close socket的方法,就是在Socket->Close()之前先寫一個Socket->OnWrite,這會讓socket在關閉之前把資料清出,這應該是比較正確的解決方式。

yeah.. very good article…help me so much !~
HOHO
Comment by wenjin — June 5, 2008 @ 9:38 am