• gethostbyname_r支持多线程情况下的可重入访问。示例代码如下:

        int herrno=0;
        struct hostent hostbuf;
        struct hostent* result;
        char buffer[8192];
        gethostbyname_r( argv[1], &hostbuf, buffer, sizeof(buffer),  &result, &herrno );
        char str[256];    
        for (char** pptr = result->h_addr_list; *pptr != 0; pptr++)   
        {   
           inet_ntop(result->h_addrtype, (u_int32_t*)(*pptr), str, sizeof(str));   
           std::cout << str << std::endl;   
        }   
        return 0;

  • 这两天碰到一个TCP read buffer 满,而发送Zero window message 给Server, Server 在收到多次这样的message后断开该缓慢连接的问题。想到了几个问题,查证后特记录如下:

    1. TCP Zero Window message 与 RST ACK:Zero Window message 通常在本地recieve buffer 满时发出,向server通知"已经不能再向我发数据了,已经处理不过来了",server收到这样的notify则会暂停向该client发数据。长此以往,有些防火墙的规则会发RST message将这些慢连接干掉。

    2. TCP MSS 与 MTU 分段:MSS叫Maxitum Segment Size ,通常的实现就是按照MTU来的,因此MSS一般来说大小为1500-20-20=1460。如果应用层数据太大,大于一个MSS,则TCP将作分段处理。MTU基于物理层而言,ethnet的MTU为1500,PPPoe为1492,上层的message大小如果大于MTU,则将在IP层被分片。有的TCP报文为保证顺序要求,设置了Dont fragment 位,指示IP层不要分片,如果这段网络上的MTU < MSS + headers 的大小,则将丢弃该报文。

    3. 阻塞和非阻塞套接字,阻塞套接字会将所有的data拷贝到发送缓冲区后才返回,也就是如果窗口为16K,要发送32k的数据返回时,至少有16K的数据已经到达对端,还有部分数据在本地缓冲区内。如果为非阻塞模式,发送32K数据将马上返回,返回的nbyte小于32K,需要通过循环将所有数据发完。

     

  • How many of you have notice that no matter you have a 100 Mb line you
    only get near 2 Mbps, well that is
    because the TCP window size is only of 32 kB or 64 kB on Linux (depends
    on distribution) and 8 kB on M$ Windows.

    The TCP window size is the amount of data that will be send on a
    connection before a host stops and waits
    for an acknowledgment. This is used by TCP to prevent congestion.
    Ideally it should be:

            Window size = Bandwidth x round trip time


    @@WARNING@@
    *    If your window size is too small, you won't use the network to it's
    full capacity
    *    If your window size is too big, you risk overloading the network
    and creating congestion and packet loss
    *    On a WAN, setting the TCP window size correctly plays a big part in
    getting good performance
            (it can easily double performance or more)


    The peak bandwidth of the link is typically expressed in Mbit/s. The
    round-trip delay for a link can be measured with traceroute, and for
    high-speed WAN
    links is typically between 10 msec and 100 msec. For a 60 msec, 120 Mbps
    path, the bandwidth*delay product would be 7200 kbit, or 900 kByte (kB).

    ...so here is how to change the
    TCP Window size on Linux in order to achieve higher bandwidth.

    #cd /proc/sys/net/core
    #ls
    message_burst    netdev_max_backlog    rmem_default    wmem_default
    message_cost    optmem_max    rmem_max    wmem_max
    -------
    (The secret are on these files)
    /proc/sys/net/core/rmem_default   - default receive window
    /proc/sys/net/core/rmem_max       - maximum receive window
    /proc/sys/net/core/wmem_default  - default send window
    /proc/sys/net/core/wmem_max      - maximum send window
    --------
    # cat    wmem_default    wmem_max    rmem_default    rmem_max
    65535
    65535
    65535
    65535
    #
    (If you change these numbers you are changing the TCP window)

    The theorical values are 65535 on all of them because asume bandwidth of
    100
    Mbits/s and the round trip time was 5 msec, the TCP window should be

    (100x10^6) bytes/sec *  (5x10^-3) sec = 65000 bytes or 65 kilobytes

    or

    500x10^3 bits (65 kilobytes)


    But imagine right now we (the UPR) have a DS3 (45Mbit/sec) with Sprint
    and the average
    round trip is 115 ms (do ping to anywhere outside and you will get
    higher numbers)

    So the computation will be:

    45 Mbit/sec * 115 ms
        = 45e6 * 115e-3
        = 5,175,000 bits / 8 / 1024
        = 631 KBytes

    That means that our ideal TCP Window is 631 KBytes.
    # cat 646875 > /proc/sys/net/core/wmem_max
    # cat 646875 > /proc/sys/net/core/wmem_default
    # cat 646875 > /proc/sys/net/core/rmem_max
    # cat 646875 > /proc/sys/net/core/rmem_default


    Well, hope this works for you. Note that this is not using the Internet2
    link yet. Probably will
    require a much smaller TCP Window. Please let me know if you find any
    difference on performance.

    DISCLAIMER: These are teorical numbers and are not guaranty to work for
    everyone in the same way.


    For M$ Windows 9x  users please refer to:
        http://moat.nlanr.net/Software/TCPtune/


    REFERENCES:
    http://dast.nlanr.net/Articles/GettingStarted/TCP_window_size.html
    http://ncne.nlanr.net/research/tcp/testrig/
    A very useful presentation:
        http://ncne.nlanr.net/training/techs/1998/980128/talks/welch

    General Info:
    http://www.ncsa.uiuc.edu/People/vwelch/net_perf/tcp_windows.html
    http://www.psc.edu/networking/perf_tune.html  (outdated 1999 but useful)

    http://www.ncsa.uiuc.edu/People/vwelch/net_perf_tools.htm
  •  Google Map 提供了一组好用的API给webpage使用,使用者必须先行申请一个Key,
    若然使用不匹配Key的网址访问Map api,将返回错误。示例代码如下:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
        <title>Google Maps JavaScript API Example</title>
        <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;
    key=ABQIAAAAxSh3HZr5L3SQVTAvXWPflh
    QHLZ7lO5Zz1btN0zldwOKXsG_5SRR2F7_teadLOObymE0DFyOybeauqg" type="text/javascript"></script> <script type="text/javascript">
    //<![CDATA[
    function load() { if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map")); map.setCenter(new GLatLng(37.4419, -122.1419), 13); } }
    //]]> </script> </head> <body onload="load()" onunload="GUnload()"> <div id="map" style="width: 500px; height: 300px"></div> </body> </html>