亚洲精品久久久久久第一页-人妻少妇精彩视品一区二区三区-91国产自拍免费视频-免费一级a在线播放视频正片-少妇天天日天天射天天爽-国产大屁股喷水视频在线观看-操美女骚穴抽插性爱视频-亚洲 欧美 中文字幕 丝袜-成人免费无码片在线观看

淺析其原因及對應(yīng)解決措施 socket接收數(shù)據(jù)不完整


淺析其原因及對應(yīng)解決措施 socket接收數(shù)據(jù)不完整

文章插圖
在發(fā)送端,一次發(fā)送4092個(gè)字節(jié),
在接收端,一次接收4092個(gè)字節(jié),
但是在接收端,偶爾會出現(xiàn) socket.receive 接收不全的情況,
ret = sock.recv(bBuffer,iBufferLen,0); //也有可能無法收到全部數(shù)據(jù)!
必須要考慮0 < ret < iBufferLen的情況:繼續(xù)接收iBufferLen – ret字節(jié),然后合并
注意第recv函數(shù)的第四個(gè)參數(shù):
MSG_WAITALLThe receive request will complete only when one of the following events occurs:
The buffer supplied by the caller is completely full.The connection has been closed.The request has been canceled.Note that if the underlying transport does not support MSG_WAITALL, or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP. Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP. This flag is not supported on datagram sockets or message-oriented CO sockets.
Socket的Send,Recv的長度問題:
一個(gè)包沒有固定長度,以太網(wǎng)限制在46-1500字節(jié),1500就是以太網(wǎng)的MTU,超過這個(gè)量,TCP會為IP數(shù)據(jù)報(bào)設(shè)置偏移量進(jìn)行分片傳輸,現(xiàn)在一般可允許應(yīng)用層設(shè)置8k(NTFS系統(tǒng))的緩沖區(qū),8k的數(shù)據(jù)由底層分片,而應(yīng)用層看來只是一次發(fā)送 。
windows的緩沖區(qū)經(jīng)驗(yàn)值是4k 。
Socket本身分為兩種,流(TCP)和數(shù)據(jù)報(bào)(UDP),你的問題針對這兩種不同使用而結(jié)論不一樣 。甚至還和你是用阻塞、還是非阻塞Socket來編程有關(guān) 。
1、通信長度,這個(gè)是你自己決定的,沒有系統(tǒng)強(qiáng)迫你要發(fā)多大的包,實(shí)際應(yīng)該根據(jù)需求和網(wǎng)絡(luò)狀況來決定 。對于TCP,這個(gè)長度可以大點(diǎn),但要知道,Socket內(nèi)部默認(rèn)的收發(fā)緩沖區(qū)大小大概是8K,你可以用SetSockOpt來改變 。但對于UDP,就不要太大,一般在1024至10K 。注意一點(diǎn),你無論發(fā)多大的包,IP層和鏈路層都會把你的包進(jìn)行分片發(fā)送,一般局域網(wǎng)就是1500左右,廣域網(wǎng)就只有幾十字節(jié) 。分片后的包將經(jīng)過不同的路由到達(dá)接收方,對于UDP而言,要是其中一個(gè)分片丟失,那么接收方的IP層將把整個(gè)發(fā)送包丟棄,這就形成丟包 。顯然,要是一個(gè)UDP發(fā)包佷大,它被分片后,鏈路層丟失分片的幾率就佷大,你這個(gè)UDP包,就佷容易丟失,但是太小又影響效率 。最好可以配置這個(gè)值,以根據(jù)不同的環(huán)境來調(diào)整到最佳狀態(tài) 。
send()函數(shù)返回了實(shí)際發(fā)送的長度,在網(wǎng)絡(luò)不斷的情況下,它絕不會返回(發(fā)送失敗的)錯(cuò)誤,最多就是返回0 。對于TCP你可以寫一個(gè)循環(huán)發(fā)送 。當(dāng)send函數(shù)返回SOCKET_ERROR時(shí),才標(biāo)志著有錯(cuò)誤 。但對于UDP,你不要寫循環(huán)發(fā)送,否則將給你的接收帶來極大的麻煩 。所以UDP需要用SetSockOpt來改變Socket內(nèi)部Buffer的大小,以能容納你的發(fā)包 。明確一點(diǎn),TCP作為流,發(fā)包是不會整包到達(dá)的,而是源源不斷的到,那接收方就必須組包 。而UDP作為消息或數(shù)據(jù)報(bào),它一定是整包到達(dá)接收方 。
2、關(guān)于接收,一般的發(fā)包都有包邊界,首要的就是你這個(gè)包的長度要讓接收方知道,于是就有個(gè)包頭信息,對于TCP,接收方先收這個(gè)包頭信息,然后再收包數(shù)據(jù) 。一次收齊整個(gè)包也可以,可要對結(jié)果是否收齊進(jìn)行驗(yàn)證 。這也就完成了組包過程 。UDP,那你只能整包接收了 。要是你提供的接收Buffer過小,TCP將返回實(shí)際接收的長度,余下的還可以收,而UDP不同的是,余下的數(shù)據(jù)被丟棄并返回WSAEMSGSIZE錯(cuò)誤 。注意TCP,要是你提供的Buffer佷大,那么可能收到的就是多個(gè)發(fā)包,你必須分離它們,還有就是當(dāng)Buffer太小,而一次收不完Socket內(nèi)部的數(shù)據(jù),那么Socket接收事件(OnReceive),可能不會再觸發(fā),使用事件方式進(jìn)行接收時(shí),密切注意這點(diǎn) 。這些特性就是體現(xiàn)了流和數(shù)據(jù)包的區(qū)別 。


以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問題,請您及時(shí)就醫(yī)或請專業(yè)人士給予相關(guān)指導(dǎo)!

「愛刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對您有所幫助: