您好,登錄后才能下訂單哦!
在《socket數(shù)據(jù)的接納和發(fā)送》一節(jié)中講到,可以運(yùn)用 write()/send() 函數(shù)發(fā)送數(shù)據(jù),運(yùn)用 read()/recv() 函數(shù)接納數(shù)據(jù),本節(jié)就來(lái)看看數(shù)據(jù)是若何傳遞的。
每一個(gè) socket 被創(chuàng)立后,都邑分派兩個(gè)緩沖區(qū),輸出緩沖區(qū)和輸入緩沖區(qū)。
write()/send() 并不立刻向收集中傳輸數(shù)據(jù),而是先將數(shù)據(jù)寫(xiě)入緩沖區(qū)中,再由TCP協(xié)定將數(shù)據(jù)從緩沖區(qū)發(fā)送到目的機(jī)械。一旦將數(shù)據(jù)寫(xiě)入到緩沖區(qū),函數(shù)就可以勝利前往,不論它們有沒(méi)有抵達(dá)目的機(jī)械,也不論它們何時(shí)被發(fā)送到收集,這些多是TCP協(xié)定擔(dān)任的工作。
TCP協(xié)定自力于 write()/send() 函數(shù),數(shù)據(jù)有能夠剛被寫(xiě)入緩沖區(qū)就發(fā)送到收集,也能夠在緩沖區(qū)中不時(shí)積存,屢次寫(xiě)入的數(shù)據(jù)被一次性發(fā)送到收集,這取決于事先的收集狀況、以后線程能否閑暇等諸多要素,不由程序員掌握。
read()/recv() 函數(shù)也是如斯,也從輸出緩沖區(qū)中讀取數(shù)據(jù),而不是直接從收集中讀取。
圖:TCP套接字的I/O緩沖區(qū)表示圖
這些I/O緩沖區(qū)特征可整頓如下:
I/O緩沖區(qū)在每一個(gè)TCP套接字中獨(dú)自存在;
I/O緩沖區(qū)在創(chuàng)立套接字時(shí)主動(dòng)生成;
即便封閉套接字也會(huì)持續(xù)傳送輸入緩沖區(qū)中遺留的數(shù)據(jù);
封閉套接字將喪失輸出緩沖區(qū)中的數(shù)據(jù)。
輸出輸入緩沖區(qū)的默許巨細(xì)普通多是 8K,可以經(jīng)過(guò) getsockopt() 函數(shù)獲?。?/span>
unsigned optVal; int optLen = sizeof(int); getsockopt(servSock, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, &optLen); printf("Buffer length: %d\n", optVal);
運(yùn)轉(zhuǎn)后果:
Buffer length: 8192
這里僅給出示例,前面會(huì)具體解說(shuō)。
關(guān)于TCP套接字(默許狀況下),當(dāng)運(yùn)用 write()/send() 發(fā)送數(shù)據(jù)時(shí):
1) 起首會(huì)反省緩沖區(qū),假如緩沖區(qū)的可用空間長(zhǎng)度小于要發(fā)送的數(shù)據(jù),那么 write()/send() 會(huì)被壅塞(暫停履行),直到緩沖區(qū)中的數(shù)據(jù)被發(fā)送到目的機(jī)械,騰出足夠的空間,才叫醒 write()/send() 函數(shù)持續(xù)寫(xiě)入數(shù)據(jù)。
2) 假如TCP協(xié)定正在向收集發(fā)送數(shù)據(jù),那么輸入緩沖區(qū)會(huì)被鎖定,不許可寫(xiě)入,write()/send() 也會(huì)被壅塞,直到數(shù)據(jù)發(fā)送終了緩沖區(qū)解鎖,write()/send() 才會(huì)被叫醒。
3) 假如要寫(xiě)入的數(shù)據(jù)大于緩沖區(qū)的最大長(zhǎng)度,那么將分批寫(xiě)入。
4) 直到一切數(shù)據(jù)被寫(xiě)入緩沖區(qū) write()/send() 才干前往。
當(dāng)運(yùn)用 read()/recv() 讀取數(shù)據(jù)時(shí):
1) 起首會(huì)反省緩沖區(qū),假如緩沖區(qū)中無(wú)數(shù)據(jù),那么就讀取,不然函數(shù)會(huì)被壅塞,直到收集上無(wú)數(shù)據(jù)到來(lái)。
2) 假如要讀取的數(shù)據(jù)長(zhǎng)度小于緩沖區(qū)中的數(shù)據(jù)長(zhǎng)度,那么就不克不及一次性將緩沖區(qū)中的一切數(shù)據(jù)讀出,殘剩數(shù)據(jù)將不時(shí)積存,直到有 read()/recv() 函數(shù)再次讀取。
3) 直到讀取到數(shù)據(jù)后 read()/recv() 函數(shù)才會(huì)前往,不然就不斷被壅塞。
這就是TCP套接字的壅塞形式。所謂壅塞,就是上一步舉措沒(méi)有完成,下一步舉措將暫停,直到上一步舉措完成后才干持續(xù),以堅(jiān)持同步性。
TCP套接字默許狀況下是壅塞形式,也是最常用的。當(dāng)然你也可以更改為非壅塞形式,后續(xù)我們會(huì)解說(shuō)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。