TCP/IP Problem Collector

Connect: Cannot assign requested address

出現原因:客戶端機器沒有空閒端口可以使用了,可能是客戶端建立的大量的連接佔用了所有可用的端口,或者是客戶端主動close連接後的TIME_WAIT狀態,導致一些端口還沒被回收。(TCP/IP中port爲16bit,範圍是0~65535。)

查詢、修改文件描述符限制:

# ulimit -n
1024            // 最多打開1024個文件描述符
# ulimit -n 1024000     // 增加可以打開的文件描述符

查詢、修改可用端口:

# sysctl -a | grep port_range
net.ipv4.ip_local_port_range = 32768 60999 //端口可用範圍是32768~60999

# vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 10000  65000 //意味着10000~65000端口可用

# sysctl -p  //使參數生效,不需要reboot

調低time_wait狀態端口等待時間:

1. 調低端口釋放後的等待時間,默認爲60s,修改爲15~30s
sysctl -w net.ipv4.tcp_fin_timeout=30
2. 修改tcp/ip協議配置, 通過配置/proc/sys/net/ipv4/tcp_tw_resue, 默認爲0,修改爲1,釋放TIME_WAIT端口給新連接使用
sysctl -w net.ipv4.tcp_timestamps=1
3. 修改tcp/ip協議配置,快速回收socket資源,默認爲0,修改爲1
sysctl -w net.ipv4.tcp_tw_recycle=1

TIME_WAIT

http://blog.csdn.net/hguisu/article/details/10241519#t2

tcp_mem

http://www.aikaiyuan.com/10872.html

$ sysctl -A | grep tcp.*mem

tcp_mem(3個INTEGER變量, 其單位是頁,1頁等於4096字節):low, pressure, high

  • low:當TCP使用了低於該值的內存頁面數時,TCP不會考慮釋放內存。
  • pressure:當TCP使用了超過該值的內存頁面數量時,TCP試圖穩定其內存使用,進入pressure模式,當內存消耗低於low值時則退出pressure狀態。
  • high:允許所有tcp sockets用於排隊緩衝數據報的頁面量,當內存佔用超過此值,系統拒絕分配socket,後臺日誌輸出“TCP: too many of orphaned sockets”。

recv buffer size

https://stackoverflow.com/questions/2862071/how-large-should-my-recv-buffer-be-when-calling-recv-in-the-socket-library

The answers to these questions vary depending on whether you are using a stream socket (SOCK_STREAM) or a datagram socket (SOCK_DGRAM) - within TCP/IP, the former corresponds to TCP and the latter to UDP.

How do you know how big to make the buffer passed to recv()?

SOCK_STREAM: It doesn’t really matter too much. If your protocol is a transactional / interactive one just pick a size that can hold the largest individual message / command you would reasonably expect (3000 is likely fine). If your protocol is transferring bulk data, then larger buffers can be more efficient - a good rule of thumb is around the same as the kernel receive buffer size of the socket (often something around 256kB).

SOCK_DGRAM: Use a buffer large enough to hold the biggest packet that your application-level protocol ever sends. If you’re using UDP, then in general your application-level protocol shouldn’t be sending packets larger than about 1400 bytes, because they’ll certainly need to be fragmented and reassembled.

What happens if recv gets a packet larger than the buffer?

SOCK_STREAM: The question doesn’t really make sense as put, because stream sockets don’t have a concept of packets - they’re just a continuous stream of bytes. If there’s more bytes available to read than your buffer has room for, then they’ll be queued by the OS and available for your next call to recv.

SOCK_DGRAM: The excess bytes are discarded.

How can I know if I have received the entire message?

SOCK_STREAM: You need to build some way of determining the end-of-message into your application-level protocol. Commonly this is either a length prefix (starting each message with the length of the message) or an end-of-message delimiter (which might just be a newline in a text-based protocol, for example). A third, lesser-used, option is to mandate a fixed size for each message. Combinations of these options are also possible - for example, a fixed-size header that includes a length value.

SOCK_DGRAM: An single recv call always returns a single datagram.

Is there a way I can make a buffer not have a fixed amount of space, so that I can keep adding to it without fear of running out of space?

No. However, you can try to resize the buffer using realloc() (if it was originally allocated with malloc() or calloc(), that is).

發佈了195 篇原創文章 · 獲贊 64 · 訪問量 50萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章