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