2011-01-26 68 views
1

有沒有任何方法檢查使用winsock的send()或WSASend()發送的數據是否確實傳送到目的地?確保發送()數據已發送

我正在寫一個應用程序與第三方服務器交談,這個服務器在工作一段時間後有時會關閉,並且需要確定發送到該服務器的消息是否已發送。問題是有時候調用send()完成沒有錯誤,即使服務器已經關閉,只有下一個send()完成時出現錯誤 - 所以我不知道以前的消息是否已經傳遞。我想在TCP層有信息,如果某些(或所有)發送的數據包是acked或不是,但它不是使用套接字接口(或我找不到方法)。

最糟糕的是,我無法更改服務器的代碼,所以我無法獲得任何傳送確認消息。

回答

0

對不起,但考慮到你要實現的目標,你應該認識到,即使TCP堆棧可以給你一個特定的字節集已被遠程TCP堆棧確認的指示,實際上並不意味着與你目前所知道的有任何不同。

問題是,除非您從遠程應用程序獲得應用程序級別的確認,只有在遠程應用程序已對您發送給它的數據執行操作後纔會發送確認,否則您將永遠無法確定是否已收到數據由遠程應用程序。

'但我可以假設它的足夠接近'

只是妄想。如果你的發送完成,你也可以做出這樣的假設,因爲它是有效的。

問題是,即使TCP堆棧可以告訴您遠程堆棧已經確認了數據(1)與接收數據(2)的遠程應用程序不同,但是不相同作爲遠程應用程序實際使用數據(3)。

鑑於遠程應用程序可能會在任何時候崩潰1,2或3,唯一有價值的數據已到達指示是遠程應用程序在將數據用於預期目的之後發送的指示。

其他一切都只是一廂情願的想法。

0

不是從返回發送()。所有的send()都表示數據被壓入發送緩衝區。連接的套接字流不保證發送所有數據,只是數據將按順序發送。所以你不能假設你的send()將在一個數據包中完成,或者由於網絡延遲或中斷而發生。

如果您需要完整的確認,您必須查看更高的應用程序級別(服務器發送格式化的確認消息,而不僅僅是數據包確認)。

+0

TCP協議有瑕疵,所以TCP層完全知道對方是否收到已發送消息的一部分 - 是否有任何獲取此信息的選項?我知道通過其他TCP堆棧來完成消息並不意味着讀取它並按應用程序進行處理,但我可以假設它足夠接近。作爲第三方服務器,我無法修改應用程序協議。 – miara 2011-01-27 07:04:05

+0

該信息不會傳播回API,正如您所說的那樣,並不意味着服務器將其從*它的緩衝區中讀出並處理。 – CoreyStup 2011-01-27 13:36:26