一。int socket(int domain, int type, int protocol)
1.domain -- 指定使用何种的地址类型
PF_INET, AF_INET: Ipv4网络协议
PF_INET6, AF_INET6: Ipv6网络协议
AF = Address Family
PF = Protocol Family
2.type -- 设置通信的协议类型
SOCK_STREAM: 提供面向连接的稳定数据传输,即TCP协议。
OOB: 在所有数据传送前必须使用connect()来建立连接状态。
SOCK_DGRAM: 使用不连续不可靠的数据包连接。
SOCK_SEQPACKET: 提供连续可靠的数据包连接。
SOCK_RAW: 提供原始网络协议存取。
SOCK_RDM: 提供可靠的数据包连接。
SOCK_PACKET: 与网络驱动程序直接通信。
3.protocol -- 指定socket所使用的传输协议编号
这一参数通常不具体设置,一般设置为0即可
二。socket.setsockopt(level, optname, value)
在套接字级别上(SOL_SOCKET),option_name可以有以下取值:
SO_DEBUG,打开或关闭调试信息。
SO_REUSEADDR,打开或关闭地址复用功能。
SO_DONTROUTE,打开或关闭路由查找功能。
SO_BROADCAST,允许或禁止发送广播数据。
SO_SNDBUF,设置发送缓冲区的大小。其上限为256 * (sizeof(struct sk_buff) + 256),下限为2048字节。
SO_RCVBUF,设置接收缓冲区的大小。上下限分别是:256 * (sizeof(struct sk_buff) + 256)和256字节。
SO_KEEPALIVE,套接字保活。
SO_OOBINLINE,紧急数据放入普通数据流。
SO_NO_CHECK,打开或关闭校验和。
SO_PRIORITY,设置在套接字发送的所有包的协议定义优先权。
SO_LINGER,如果选择此选项, close或 shutdown将等到所有套接字里排队的消息成功发送或到达延迟时间后才会返回. 否则, 调用将立即返回。
SO_PASSCRED,允许或禁止SCM_CREDENTIALS 控制消息的接收。
SO_TIMESTAMP,打开或关闭数据报中的时间戳接收。
SO_RCVLOWAT,设置接收数据前的缓冲区内的最小字节数。
SO_RCVTIMEO,设置接收超时时间。
SO_SNDTIMEO,设置发送超时时间。
SO_BINDTODEVICE,将套接字绑定到一个特定的设备上。
SO_ATTACH_FILTER和SO_DETACH_FILTER。
三。TCP可靠,UDP不可靠的原因--SO_RCVBUF 、SO_SNDBUF
每个TCP socket在内核中都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式以及TCP的滑动窗口便是依赖于这两个独立的buffer以及此
buffer的填充状态。接收缓冲区把数据缓存入内核,应用进程一直没有调用read进行读取的话,此数据会一直缓存在相应socket的接收缓冲区内。
再啰嗦一点,不管进程是否读取socket,对端发来的数据都会经由内核接收并且缓存到socket的内核接收缓冲区之中。read所做的工作,就是把内核缓
冲区中的数据拷贝到应用层用户的buffer里面,仅此而已。
进程调用send发送的数据的时候,将数据拷贝进入socket的内核发送缓冲区之中,然后send便会在上层返回。换句话说,send返回之时,数据不一定
会发送到对端去,send仅仅是把应用层buffer的数据拷贝进socket的内核发送buffer中。
每个UDP socket都有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发,不管对方是否可以正确接收
对于TCP,如果应用进程一直没有读取,buffer满了之后,发生的动作是:通知对端TCP协议中的窗口关闭。这个便是滑动窗口的实现。保证TCP套接口
接收缓冲区不会溢出,从而保证了TCP是可靠传输。因为对方不允许发出超过所通告窗口大小的数据。 这就是TCP的流量控制,如果对方无视窗口大小
而发出了超过窗口大小的数据,则接收方TCP将丢弃它。 对于UDP,当套接口接收缓冲区满时,新来的数据报无法进入接收缓冲区,此数据报就被丢弃。