tcp/ip高效编程总结

1.客户端-服务器结构

    客户端-服务器结构的物理部署分为三类:

    (1)在同一台机器上:理想环境,只要压力不大,分组不会丢失、延迟和乱序,是理想的测试环境,可以用作评估客户端和服务器端程序的原始性能;

    (2)在同一局域网内:接近理想环境,分组很少丢失、乱序,但是有延迟;

    (3)在广域网内:分组丢失、重传、重复、乱序比较常见。

2.基本套接字API

    (1) sys/socket.h、winsock2.h:SOCKET socket(int domain, int type, int protocol)

        成功时返回套接字,失败时返回-1(linux),INVALID_SOCKET(windows)

        domain:通信域,AF_INET为互联网,AF_LOCAL或AF_UNIX为统一台机器上进程间通信;
        type:套接字类型,

                 SOCK_STREAM为可靠、全双工、面向连接的字节流,对应于tcp;

                 SOCK_DGRAM为不可靠、尽力而为的数据报服务,对应于udp;

                 SOCK_RAW对ip层某些数据访问;

        protocol:对tcpip来说,这个字段通常由套接字类型隐含说明,参数默认被设置为0。

    (2) sys/socket.h、winsock2.h:int bind(SOCKET s, const struct sockaddr* local, int local_len)

        成功时返回套接字,成功时返回0,失败时返回-1(linux),SOCKET_ERROR(windows)

        s:套接字描述符,由socket函数返回;
        local:绑定的地址和端口,对AF_INET来说,对应的是struct sockadd_in;

        local_len:peer结构体大小;

    (3) sys/socket.h、winsock2.h:int listen(SOCKET s, int backlog)

        成功时返回套接字,成功时返回0,失败时返回-1(linux),SOCKET_ERROR(windows)

        s:套接字描述符,由socket函数返回;
        backlog:排队等待应用程序接受的连接最大数量

    (4) sys/socket.h、winsock2.h:int accept(SOCKET s, struct sockaddr* peer, int* peer_len)

        成功时返回套接字,成功时返回0,失败时返回-1(linux),INVALID_SOCKET(windows)

        s:套接字描述符,由socket函数返回;
        peer:对等实体地址和其他一些信息,对AF_INET来说,对应的是struct sockadd_in;

        peer_len:peer结构体大小;

    (5) sys/socket.h、winsock2.h:int connect(SOCKET s, const struct sockaddr* peer, int peer_len)

        成功时返回套接字,成功时返回0,失败时返回-1(linux),非0(windows)

        s:套接字描述符,由socket函数返回;
        peer:对等实体地址和其他一些信息,对AF_INET来说,对应的是struct sockadd_in;

        peer_len:peer结构体大小;

    (6) sys/socket.h:int read(SOCKET s,          void* buf, size_t len, int flags)
                              int write(SOCKET s, const void* buf, size_t len, int flags)
         winsock2.h:   int recv(SOCKET s,           void* buf, size_t len, int flags)
                               int send(SOCKET s, const void* buf, size_t len, int flags)

        成功时返回字节数,失败时返回-1(linux),-1(windows)

        s:套接字描述符,由socket函数返回;
        buf:发送数据存储;

        len:发送字节数;

        flags:与系统有关,linux和windows都支持MSG_OOB、MSG_PEEK、MSG_DONTROUTE

    (7) sys/socket.h、winsock2.h:int recvfrom(SOCKET s,          void* buf, size_t len, int flags,struct sockaddr* from, int from_len)
                                                int sendto   (SOCKET s, const void* buf, size_t len, int flags,struct sockaddr* to, int to_len)

        成功时返回字节数,失败时返回-1(linux),-1(windows)

        s:套接字描述符,由socket函数返回;
        buf:发送数据存储;

        len:发送字节数;

3.面向连接和无连接协议

    面向连接和无连接指的是协议,不是物理介质。指的是协议的分组寻址是否独立寻址,协议是否需要维护分组之间的状态。这里的分组是协议分组,不是指应用程序要传输的数据大小。

    UDP通过只向IP层增加两项功能:增加可选的校验和来检测数据的损坏情况;添加端口区分上层应用;

    TCP通过向IP层增加三项功能实现了可靠性:增加可选的校验和来抵抗数据损坏;为每字节增加序列号抵抗乱序;增加确认——重传机制抵抗丢失。

4.子网与CIDR

    传统上将ip地址分为5类,称为分类编址:

    A类:7bit网络24bit主机        0.0.0.1——127.255.255.255
    B类:14bit网络16bit主机   128.0.0.1——191.255.255.255
    C类:21bit网络8bit主机     192.0.0.1——223.255.255.255
    D类:多播1110开头
    E类:保留4bit1开头

    为了使用较小路由表,使单个网络ID的Ip地址空间得到有效利用,而且享有每个网段具有独立网络ID时路由的便捷性,我们需要从外部主机看是单个网络,从内部主机看是多个网络。实现这种功能的机制就是子网划分。

5. tcp是一种流协议

    对tcp应用程序来说,没有分组的概念,应用程序需要自己确定包的大小和边界。有三种方式确定包大小:

    固定包大小,所有分组的包大小相同;

    使用记录结束标志,这需要在发送端对报文主题中的结束标志进行转义,接收端扫描整个报文;

    使用报文头来指定报文大小,这种方式必须小心编译器本身对数据封装的填充、42.  1。

 6. UDP的使用注意实现

    对于简单的请求、应答程序来说,UDP的性能会显著优于TCP。因此可以考虑使用UDP协议作为基于事务的应用程序的支撑协议。

    健壮的UDP程序必须提供:合理时间内没有收到应答则重传;应答和请求的正确匹配;流量控制;拥塞控制。这里合理的时间要靠RTO定时器来计时,但是大小就是需要根据网络条件来调整了。应答和请求的正确匹配可以使用序列号的方式来保证。TCP的滑动窗口是实现流量控制的常见方式。·

    应该避免为了使用UDP而在用户层实现TCP的可靠性,这可能不会导致性能比TCP好,而且也可能会出错。如果既想拥有TCP的可靠性,又想使用UDP差不多的事务性能,可以使用T/TCP。

7.TCP的可靠性

    TCP是一个端到端协议,保证的是对等实体间的可靠性,也就是tcp层到tcp层间的可靠性。只要两个对等的tcp之间是连接的,tcp就能保证将数据可靠(按序、无损)的传送。这里的受损是指在因特网校验和的条件下未受损。对等应用程序间的可靠性需要应用程序自己来保证。即,从应用程序A通过tcp发送到应用程序B,凡是A的tcp层收到ACK的都表示已经可靠的传输到B的tcp层;凡是B的应用程序收到的数据都是按序且未受损的。

    连接中断的三种情况:   

    (1) 永久或临时的网络中断:;
    (2) 对等的应用程序崩溃:;
    (3) 对等的应用程序所在主机崩溃:;

8. 

posted @ 2013-12-14 13:08  blockcipher  阅读(510)  评论(0编辑  收藏  举报