關於完成端口,WSASend的問題 |
答題得分者是:aftcast
|
mistakee
一般會員 發表:1 回覆:1 積分:0 註冊:2015-02-16 發送簡訊給我 |
各位前輩好
請教關於重疊I/O,WSASend的問題 小第將待發送的資料寫入TMemoryStream,假設寫入資料為1~5000 再連續WSASend 5次,每次資料長度1000 本來想說,接收到的資料也會是5次,每次1000筆 但實際上卻"不一定",有時會接收6次,但接收到的資料總長度是對的 例如某次僅接收200筆,下一次接收到的起始值,會從201筆開始,最後會多接收一次800筆補足 設定每筆傳送長度1000,也沒超過MSS,為什麼會將我的包裹拆開來傳送 而且之後每次接收都會被平移 但若稍微延遲一下每次WSASend的時間,比如說每WSASend一次,在Memo上印幾個字母 這樣接收到就不會出錯,即接收5次,每次1000筆 想請教前輩,這是怎樣的情形,謝謝各位 ----------------------------------------------------------------------------------------------------------------------------------------- 舉例 傳送端: 依序傳送 Send1 Send2 Send3 Send4 Send5 傳送筆數 1000 1000 1000 1000 1000 傳送資料 1~1000 1001~2000 2001~3000 3001~4000 4001~5000 ------------------------------------------------------------------------------------------------------------------------------------------- 預期接收端: Recv1 Recv2 Recv3 Recv4 Recv5 接收筆數 1000 1000 1000 1000 1000 接收資料 1~1000 1001~2000 2001~3000 3001~4000 4001~5000 ------------------------------------------------------------------------------------------------------------------------------------------- 實際接收端: Recv1 Recv2 Recv3 Recv4 Recv5 Recv6 接收筆數 1000 1000 200 1000 1000 800 接收資料 1~1000 1001~2000 2001~2200 2201~3200 3201~4200 4201~5000 [code cpp] bool TIOCP::PostSend(CIOCPContext *pContext, CIOCPBuffer *pBuffer) { pBuffer->nOperation=OP_WRITE; DWORD dwBytes; DWORD dwFlags=0; WSABUF buf; buf.buf=pBuffer->buff; buf.len=pBuffer->nLen; if(::WSASend(pContext->s,&buf,1,&dwBytes,dwFlags,&pBuffer->ol,NULL)!=NO_ERROR) { if(::WSAGetLastError()!=WSA_IO_PENDING) return false; } ::EnterCriticalSection(&pContext->Lock); pContext->nOutstandingSend ; ::LeaveCriticalSection(&pContext->Lock); return true; } [/code] |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
不錯喔,使用iocp來寫socket,題外話,未來看是否有機會可以合作看看。我需要人才,哈哈。
關於 tcp 之 socket 有一個最易被忽略但極重要的概念 : tcp 是streaming base的通訊協定! 這意味著什麼? 就是 tcp 本身的封包是以stream的方式被處理。這樣的特性導致tcp的lib並不知道(也無法知道,也不想知道) 如何是完整的訊息。所謂的完整的訊息可能由數個封包組成,但到底是幾個? tcp lib 是不管的。於是更進一步的來說,即使你分5次來送封包,接收端也沒一定要用5次來接收完成,原因是既然tcp的規範是streaming based的,封包的"組裝"就該是更上層的通訊要處理,比如http會處理。但你個人以tcp為基準來收資料時,你就要自己去組裝。 簡言之,你所觀察到的是tcp socket的正常特性。當然,若你故意把send的離散一點送,"原則上"會比較如你預期,送5收5。但這不實際且穩健。「永遠不能依賴 tcp 收到的次數等於送出的」! 接著你該怎麼做? 自訂你自己的frame的規格,一般來說有二類,一類是header帶長度,表接下來該是幾個bytes。第二類是frame本身有頭有尾,意味著收到某尾端的bytes時表示完整訊息達成。以上是通訊程式要學的進階課程,書上少寫,因為這是「江湖一點訣,說破不值錢」。 觸類旁通的補充 : udp 是 message based。
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
mistakee
一般會員 發表:1 回覆:1 積分:0 註冊:2015-02-16 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |