當前位置:首頁 » 文件管理 » socket緩存

socket緩存

發布時間: 2022-07-12 22:10:49

① socket緩沖區是什麼

socket緩沖區,是指你在進行socket通信的時候,收發命令時的一個中間存放命令的存儲空間,一般系統設置為8k,可以自己調整大小

② 怎麼清空socket 接收緩存

清空socket緩存區的數據的方法
由於socket是以數據流的形式發送數據,接收方不知道對方一次性發送了多少數據,也能保證對方一次性發送的數據能在同一刻接收到,所以Receive方法是這么工作的:
接受一個byye[]類型的參數作為緩沖區,在經過一定的時間後把接收到的數據填充到這個緩沖區裡面,並且返回實際接收到數據的長度,這個實際接收到的數據長度有可能為0(沒有接收到數據)、大於0小於緩沖區的長度(接收到數據,但是沒有我們預期的多)、等於緩沖區的長度(說明接收到的數據大於等於我們預期的長度)。
每次接收緩沖區都用同一個byte[] byteMessage,並且你沒有檢查接收到的數據長度,所以第一次你接收到的數據是123456,第二次你只接收到了8,但是緩沖區裡面還有23456,所以加起來就是823456了。
socket接收緩沖區的大小有講究,設置大了接收起來慢,因為它要等盡可能多的數據接收到了再返回;設置小了需要重復多次調用接收方法才能把數據接收完,socket有個屬性,標識了系統默認的接收緩沖區大小,可以參考這個!
還有就是用recv讀取,但是由於不知道緩存里有多少數據,如果是阻塞模式,到最後必然等到超時才知道數據已經讀取完畢,這是個問題。
另一個是用fgetc,通過返回判斷是否是feof:
whlie (1) { a=fgetc(f);if (feof(f)) break;//…
b=fgetc(f);if (feof(f)) break;//…}當然,我不知道讀取完畢後最後一次調用fgetc會不會堵塞,需要測試。

③ 如何清空Socket緩沖區

清空socket緩存區的數據的方法

  • 由於socket是以數據流的形式發送數據,接收方不知道對方一次性發送了多少數據,也能保證對方一次性發送的數據能在同一刻接收到,所以Receive方法是這么工作的:

  • 接受一個byye[]類型的參數作為緩沖區,在經過一定的時間後把接收到的數據填充到這個緩沖區裡面,並且返回實際接收到數據的長度,這個實際接收到的數據長度有可能為0(沒有接收到數據)、大於0小於緩沖區的長度(接收到數據,但是沒有我們預期的多)、等於緩沖區的長度(說明接收到的數據大於等於我們預期的長度)。

  • 每次接收緩沖區都用同一個byte[] byteMessage,並且你沒有檢查接收到的數據長度,所以第一次你接收到的數據是123456,第二次你只接收到了8,但是緩沖區裡面還有23456,所以加起來就是823456了。

  • socket接收緩沖區的大小有講究,設置大了接收起來慢,因為它要等盡可能多的數據接收到了再返回;設置小了需要重復多次調用接收方法才能把數據接收完,socket有個屬性,標識了系統默認的接收緩沖區大小,可以參考這個!

  • 還有就是用recv讀取,但是由於不知道緩存里有多少數據,如果是阻塞模式,到最後必然等到超時才知道數據已經讀取完畢,這是個問題。

  • 另一個是用fgetc,通過返回判斷是否是feof:

  • whlie (1) { a=fgetc(f);if (feof(f)) break;//…

  • b=fgetc(f);if (feof(f)) break;//…}當然,我不知道讀取完畢後最後一次調用fgetc會不會堵塞,需要測試。

  • 在非阻塞模式下,我們用recv就可以輕松搞定了,但是阻塞模式下,由於我們不知道緩沖區有多少數據,不能直接調用recv嘗試清除。

  • 使用一個小小的技巧,利用select函數,我們可以輕松搞定這個問題:

  • select函數用於監視一個文件描述符集合,如果集合中的描述符沒有變化,則一直阻塞在這里,直到超時時間到達;在超時時間內,一旦某個描述符觸發了你所關心的事件,select立即返回,通過檢索文件描述符集合處理相應事件;select函數出錯則返回小於零的值,如果有事件觸發,則返回觸發事件的描述符個數;如果超時,返回0,即沒有數據可讀。

  • 重點在於:我們可以用select的超時特性,將超時時間設置為0,通過檢測select的返回值,就可以判斷緩沖是否被清空。通過這個技巧,使一個阻塞的socket成了『非阻塞』socket.

  • 現在就可以得出解決方案了:使用select函數來監視要清空的socket描述符,並把超時時間設置為0,每次讀取一個位元組然後丟棄(或者按照業務需要進行處理,隨你便了),一旦select返回0,說明緩沖區沒數據了(「超時」了)。

  • struct timeval tmOut;tmOut.tv_sec = 0;tmOut.tv_usec = 0;fd_set fds;FD_ZEROS(&fds);FD_SET(skt, &fds);

  • int nRet;

  • char tmp[2];

  • memset(tmp, 0, sizeof(tmp));

  • while(1)

  • { nRet= select(FD_SETSIZE, &fds, NULL, NULL, &tmOut);if(nRet== 0) break;recv(skt, tmp, 1,0);}

  • 這種方式的好處是,不再需要用recv、recvfrom等阻塞函數直接去讀取,而是使用select,利用其超時特性檢測緩沖區是否為空來判斷是否有數據,有數據時才調用recv進行清除。

  • 有人說同樣可以用recv和超時設置去清空啊,這個沒錯,但是你需要直接對socket描述符設置超時時間,而為了清空數據而直接修改socket描述符的屬性,可能會影響到其他地方的使用,造成系統奇奇怪怪的問題,所以,不推薦使用。socket的

④ 請教一個socket緩沖區太小對性能影響的問題

會,每一次系統調運都要犧牲系統性能,緩存量太小,會導系統調運次數頻繁,進而影響性能。

可通過內核參數的調整來避免該問題:

⑤ 如何得知socket的緩存大小,這個緩存是否有上限,是否會溢出

一:如何得知socket的緩沖大小?
通過socket選項可以獲得socket的緩沖大小。(以下是python代碼,sock為socket對象)
sock.getsockopt(SOL_SOCKET,SO_RCVBUF):獲取接收緩沖區的大小
sock.getsockopt(SOL_SOCKET,SO_SNDBUF):獲得發送緩沖區的大小
註:UDP協議在內核實現中沒有發送緩沖區。

二:這個緩沖是否有上限?
緩沖區存在上限,沒一個socket對象的緩沖區有上限,系統中所有的socket緩沖區的總大小也存在上限。

三:是否會溢出?
TCP協議是可靠的有序的位元組流協議,其可靠性與接收端的滑動窗口機制有關,而滑動窗口和TCP的接收緩沖區有關。
TCP協議的緩沖區不會溢出,如果接收緩沖區已滿,則通告窗口為0,不能在接收發送端發過來的數據。如果發送緩沖區已滿(則可以說明對端的接收緩沖區一定已滿),應用層的send調用阻塞(採用阻塞式IO)。所以說TCP協議的緩沖區不會溢出。
UDP協議的緩沖區會溢出,UDP協議在實現上沒有發送緩沖區,接收緩沖區存在上限,當UDP的接收緩沖區達到上限時,以後接收到的數據報直接丟棄,這也是UDP協議不可靠的一個原因。
-----------------------------------------------------------------------------------------------------------
推薦你看一下陶輝的」高性能網路編程「系列,肯定會受益匪淺。

⑥ 如何清除掉socket發送緩存區中的數據

清空socket緩存區的數據的方法
由於socket是以數據流的形式發送數據,接收方不知道對方一次性發送了多少數據,也能保證對方一次性發送的數據能在同一刻接收到,所以Receive方法是這么工作的:
接受一個byye[]類型的參數作為緩沖區,在經過一定的時間後把接收到的數據填充到這個緩沖區裡面,並且返回實際接收到數據的長度,這個實際接收到的數據長度有可能為0(沒有接收到數據)、大於0小於緩沖區的長度(接收到數據,但是沒有我們預期的多)、等於緩沖區的長度(說明接收到的數據大於等於我們預期的長度)。
每次接收緩沖區都用同一個byte[] byteMessage,並且你沒有檢查接收到的數據長度,所以第一次你接收到的數據是123456,第二次你只接收到了8,但是緩沖區裡面還有23456,所以加起來就是823456了。
socket接收緩沖區的大小有講究,設置大了接收起來慢,因為它要等盡可能多的數據接收到了再返回;設置小了需要重復多次調用接收方法才能把數據接收完,socket有個屬性,標識了系統默認的接收緩沖區大小,可以參考這個!
還有就是用recv讀取,但是由於不知道緩存里有多少數據,如果是阻塞模式,到最後必然等到超時才知道數據已經讀取完畢,這是個問題。
另一個是用fgetc,通過返回判斷是否是feof:
whlie (1) { a=fgetc(f);if (feof(f)) break;//…
b=fgetc(f);if (feof(f)) break;//…}當然,我不知道讀取完畢後最後一次調用fgetc會不會堵塞,需要測試。
在非阻塞模式下,我們用recv就可以輕松搞定了,但是阻塞模式下,由於我們不知道緩沖區有多少數據,不能直接調用recv嘗試清除。
使用一個小小的技巧,利用select函數,我們可以輕松搞定這個問題:
select函數用於監視一個文件描述符集合,如果集合中的描述符沒有變化,則一直阻塞在這里,直到超時時間到達;在超時時間內,一旦某個描述符觸發了你所關心的事件,select立即返回,通過檢索文件描述符集合處理相應事件;select函數出錯則返回小於零的值,如果有事件觸發,則返回觸發事件的描述符個數;如果超時,返回0,即沒有數據可讀。
重點在於:我們可以用select的超時特性,將超時時間設置為0,通過檢測select的返回值,就可以判斷緩沖是否被清空。通過這個技巧,使一個阻塞的socket成了『非阻塞』socket.
現在就可以得出解決方案了:使用select函數來監視要清空的socket描述符,並把超時時間設置為0,每次讀取一個位元組然後丟棄(或者按照業務需要進行處理,隨你便了),一旦select返回0,說明緩沖區沒數據了(「超時」了)。
struct timeval tmOut;tmOut.tv_sec = 0;tmOut.tv_usec = 0;fd_set fds;FD_ZEROS(&fds);FD_SET(skt, &fds);
int nRet;
char tmp[2];
memset(tmp, 0, sizeof(tmp));
while(1)
{ nRet= select(FD_SETSIZE, &fds, NULL, NULL, &tmOut);if(nRet== 0) break;recv(skt, tmp, 1,0);}
這種方式的好處是,不再需要用recv、recvfrom等阻塞函數直接去讀取,而是使用select,利用其超時特性檢測緩沖區是否為空來判斷是否有數據,有數據時才調用recv進行清除。
有人說同樣可以用recv和超時設置去清空啊,這個沒錯,但是你需要直接對socket描述符設置超時時間,而為了清空數據而直接修改socket描述符的屬性,可能會影響到其他地方的使用,造成系統奇奇怪怪的問題,所以,不推薦使用。socket的

熱點內容
java單例實現 發布:2025-01-20 11:48:40 瀏覽:333
cad為什麼載入不了配置 發布:2025-01-20 11:37:45 瀏覽:16
伺服器記錄的手機ip 發布:2025-01-20 11:32:47 瀏覽:672
sparksql查詢 發布:2025-01-20 11:27:51 瀏覽:204
安卓奧特曼格鬥進化1怎麼發大招 發布:2025-01-20 11:17:03 瀏覽:605
試驗數據存儲 發布:2025-01-20 11:03:38 瀏覽:305
聯想如何將密碼退出 發布:2025-01-20 10:51:41 瀏覽:972
ftp傳輸文件連接失敗 發布:2025-01-20 10:49:39 瀏覽:723
xp共享訪問不了 發布:2025-01-20 10:40:05 瀏覽:946
基恩士plc編程手冊 發布:2025-01-20 10:11:30 瀏覽:910