socket通信如何處理每次包長度不定問題
說起來,這是一個漫長的問題:
客戶端和服務(wù)器通信的結(jié)構(gòu)是:包頭+數(shù)據(jù)長度+數(shù)據(jù)
客戶端請求服務(wù)器發(fā)送200包數(shù)據(jù)。包頭=request;長度=4(一個int),數(shù)據(jù)=200;
服務(wù)器在收到客戶端的請求后,在while循環(huán)里面不停的send,直到夠200包:包頭=indicate 長度=XX,后面跟一大串?dāng)?shù)據(jù);發(fā)完以后,再發(fā)一個結(jié)束的包:包頭=end,長度-1,data=無效值。
在服務(wù)器端,在while循環(huán)里不停的recv:先recv包頭,在recv長度。如果判斷是數(shù)據(jù),然后recv數(shù)據(jù)。如果判斷是結(jié)束包,那么break出循環(huán)。
這個看似沒有問題的程序,實際存在一個問題:
在客戶端,recv包頭和長度后,recv數(shù)據(jù),可能出現(xiàn)數(shù)據(jù)并沒有全部傳過來的情況,比如recv長度后,得知后面的數(shù)據(jù)有15000字節(jié)。但是由于阻塞等原因,只傳過來了7000字節(jié)。那么按照原來程序的邏輯,就會在下一次recv包頭和長度時,將實際發(fā)送的剩下的8000字節(jié)當(dāng)做新一包的包頭,然后解包,這樣就出現(xiàn)了錯誤。
我的處理辦法是,如果recv數(shù)據(jù)時,實際收到的長度不等于發(fā)送數(shù)據(jù)長度,那么就搞一個小的while循環(huán),在循環(huán)中把這一包收滿(為了保證收滿,可以sleep(10)),然后跳出來,繼續(xù)收下一包,就解決了。
這個辦法是很土,但是由于每包的長度不定,所以暫時只能想到這個辦法解決。
浙公網(wǎng)安備 33010602011771號