關於socket的發送緩衝區網上有諸多的討論,這裡個人小結一下,希望對以後有些協助。首先,看下面一段代碼,
//設定socket參數
#define dfUdpRcvCacheSize 256*1024 //256//接收緩衝區大小(位元組)
int optval,optlen = sizeof(int);
optval=dfUdpRcvCacheSize; //設定讀緩衝區
err=setsockopt(iSock,SOL_SOCKET,SO_RCVBUF,(char*)&optval,optlen);
optval=dfUdpSndCacheSize; //設定讀緩衝區
err=setsockopt(iSock,SOL_SOCKET,SO_SNDBUF,(char*)&optval,optlen);
上面的代碼無需解釋,很多人應該都知道是在win32下面用來設定SOCKET接收發送緩衝區的,先不討論上面的代碼有沒問題。既然提供了這樣的API可以對緩衝區進行設定,那麼究竟對緩衝區的設定是否有一個最大值的限制呢?先來看下網上各大技術論壇對該問題的討論:
”只要是IP包就是65535位元組, 也就是64K
這是由IP資料報的結構決定的
IP首部有個表示IP資料報總長度的16位位元組, 其最大值表示為FFFF
因此最大值為65535
此數值不是純粹的資料淨負荷,而是包含了IP首部資訊
而IP首部是20位元組, UDP首部是8位元組
因此UDP資料部分是65535-20-8=65507 ”
顯然,該段評論的論據本身是沒錯的,本人也專門翻了TCP/IP詳解第一卷第3章的IP協議,看到了IP首部表示資料包總長度的欄位是16個位元組,最長表示65535,當然還要去掉首部。論據本身是對的,但該論據並不能證明我最開始提出的論點,因為我們的論點是socket發送以及讀取緩衝區設定的最大長度,顯然,這並不等於1個IP資料包的最大長度,甚至可以說其實兩者毫無關係。原因在此,何謂發送緩衝區,其實無非是大並發量時期,socket本身都會在本身維護一個緩衝池,然後分段(注意:此次的分段,很明顯,大家都知道這才是不能超過1個IP包的最大長度)往目的地址發送資料。 說到這裡,應該明白不少了吧:) ,遺憾的是,本人最終還是沒有查到win32對於socket接收緩衝區大小的最大限制,而在實際大並發量通訊的項目中,目前我是設定了256k,暫時沒發現任何問題。
既然說到了IP包的最大長度,那麼隨帶提一下,一切理論都要結合實踐。在公網網路通訊中,無論你如何七十二變,你最終都要經過中國複雜而又混亂的互連網絡,那麼在實際的UDP通訊中,是否每次都可以組成一個最大的IP包往外仍呢,答案自然是否定的,拋開MTU傳輸單元最大值本身不說,通常為1.5K左右,也就是說傳輸層要發送的資料超過了1.5K那麼IP層會自動進行資料分區,至於怎樣分區以及組包,對於傳輸層UDP/TCP都是透明的),問題是目前實際公網的路由器,對於大於1k左右的UDP包,都會自動做丟棄處理(經過測試是這樣的),所以,通常我們自己必須做的切割包大小為1k,就是超過這個大小的包都必須先在源地址進行切割,再分傳送出去)OK,今天先總結到此,裡面應該還有很多錯誤或者遺漏的地方,等有時間再過來修改。