NAME
socket —— Linux套接字接口
SYNOPSIS
#include
sockfd = socket(int socket_family, int socket_type, int protocol);
DESCRIPTION
此手册描述Linux网络套接层用户接口。BSD兼容的通用接口位于用户矜持和内核的网络协议栈之间。协议模块以协议族和套接字类型分组,协议族如AF_INET,AF_IPX,AF_PACKET;套接字类型如SOCK_STREAM或SOCK_DGRAM。参见socket(2)以获取更多有关协议族和类型的信息。
套接字层函数
这些函数被用户进程用来发送或接受包以及其它套接字操作。参见它们各自的手册页以了解更多信息。
socket创建一个套接字,connect将一个套接字链接到远程套接字地址,bind将一个套接字绑定到本地套接字地址,listen告诉套接字准备接受连接请求,accept用于获取一个接入连接的套接字。socketpair返回两个互连的匿名套接字(只有少数几个本地协议族的实现像AF_UNIX)。
send,sendto和sendmsg在一个套接字上发送数据,recv,recvfrom和recvmsg从一个套接字接收数据。poll和select等待数据到达或数据发送准备就绪。此外,标准I/O操作像write,writev,sendfile,read,readv可以用于读写数据。
getsockname返回本地套接字地址,getpeername返回远程套接字地址。getsockopt和setsockopt用于设置/获得套接层或相关协议的选项。ioctl可以用于设置或读取一些相关选项。
close用于关闭套接字,shutdown关闭全双工套接字的部分连接。
不支持在套接字上寻址或以非0的偏移位置为之调用pread/pwrite。
使用fcntl为文件描述符设置O_NONBLOCK标记可以使套接字以非阻塞模式I/O。这意味着所有可能阻塞的操作都将出错返回EAGAIN(操作可以在稍后重试);connect则将返回EINPROGRESS错误。用户可以可以通过poll或select等待各种的事件。
I/O事件表
|
事件
|
轮询标记
|
描述
|
Read
|
POLLIN
|
新数据到达
|
Read
|
POLLIN
|
连接已经完成(针对面向连接的套接字)
|
Read
|
POLLHUP
|
对方请求断开连接
|
Read
|
POLLHUP
|
连接被断开(针对面向连接的套接字)如果在套接字上写将收到SIGPIPE信号
|
Write
|
POLLOUT
|
套接字已经有充足的发送缓冲区空间用于发送新数据
|
Read/Write
|
POLLIN|POLLOUT
|
一个外出套接字已经完成
|
Read/Write
|
POLLERR
|
出现了异步错误
|
Read/Write
|
POLLHUP
|
对方关闭了发送端
|
Read/Write
|
POLLPRI
|
紧急数据到达,SIGURG随后发送
|
poll和select的替代方案是让内核通过信号SIGIO通知进程。为此,必须通过fcntl为套接字描述符设置O_ASYNC标记,且通过sigaction为SIGIO安装一个有效的信号处理函数。参见下面有关信号的讨论。
套接字选项
可以以level值为SOL_SOCKET调用setsockopt/getsockopt设置/读取套接字选项:
SO_ACCEPTCONN
返回一个值,表明是否调用了listen以标记套接字可以接受接入连接。0代表套接字不是监听套接字,1则代表是。只能用于getsockopt。
SO_BINDTODEVICE
将套接字绑定到一个特定设备,通过接口名称诸如“eth0”指定。如果名称是一个空字符串或长度为0,则移除设备。传递的选项是一个可变长度的,空字符结尾的本地接口名称字符串,最大长度是IFNAMSIZ。如果一个套接字绑定到一个接口,则它只能处理特定接口上接收的包。注意,只能在几种套接字类型上工作,特定于AF_INET。它不支持包套接字(这类通常用bind(8))。
SO_BROADCAST
设置或获取广播标记。当启用是,数据报套接字接收从广播地址发送的包,也允许它向广播地址发送包。此选项对面向流的套接字无效。
SO_BSDCOMPAT
启用BSD bug-to-bug兼容模式。Linux 2.0和2.2中用于UDP协议模块。如果启用,在UDP套接字上收到的ICMP错误将不会传递给用户进程。后来的内核版本中,此选项的支持已被淘汰:Linux 2.4简单忽略它,而Linux 2.6发现进程使用此选项将生成内核警告。Linux 2.0可以对raw套接字启用BSD bug-to-bug兼容模式选项,但是在Linux 2.2中被移除。
SO_DEBUG
启用套接字调试。只允许具备CAP_NET_ADMIN权限或有效进程ID为0的进程使用。
SO_ERROR
获取并清除未决的套接字错误。只读选项,返回一个整数值。
SO_DONTROUTE
不通过网关转发,直接发送给直接连接的主机。在一个套接字上以MSG_DONTROUTE标记调用send操作效果是一样的。期望一个整数布尔标记。
SO_KEEPALIVE
在面向连接的套接字上启用keep-alive消息发送。期望一个整数布尔标记。
SO_LINGER
设置或获取SO_LINGER选项。此参数是一个linger结构。
struct linger { int l_onoff; /* linger active */ int l_linger; /* how many seconds to linger for */ };
如果启用,close或shutdown调用将阻塞直到所有排队的消息被成功发送或者超时;否则,它们立即返回,关闭将在后台完成。当套接字在exit中关闭时,它总是在后台完成的。 SO_OOBINLINE
如果此选项启用,带外数据直接放置在数据流中;否则,带外数据只能以MSG_OOB调用recv传递。
SO_PASSCRED
启用或禁用接收SCM_CREDENTIALS控制消息。参见unix(7)了解更多信息。
SO_PEERCRED
返回连接到此套接字的进程的凭据。这只可能在已连接的AF_UNIX流套接字或socketpair创建的流或数据报套接字上使用;参见unix(7)。返回的凭据效用截至该进程调用connect或socketpair时。参数是一个ucred结构。只读选项。
SO_PRIORITY
为此套接字发出的所有包设置协议定义的优先级。Linux使用此值排序网络队列:根据选择的设备排队规律,高优先级的包可能被优先处理。对于IP协议,这将连带设置外出IP报头的TOS字段。设置0~6级别的优先级需要CAP_NET_ADMIN权限。
SO_RCVBUF
设置或获取最大套接字接收缓冲区字节数。setsockopt时内核将此值加倍(缓冲轮换),在getsockopt时就返回加倍值。默认值在/proc/sys/net/core/rmem_default修改,最大允许值在/proc/sys/net/core/rmem_max修改。最小值(已经加倍的)是256。
SO_RCVBUFFORCE (since Linux 2.6.14)
使用这个套接字选项,特权(CAP_NET_ADMIN)进程可以执行SO_RCVBUF一样的任务,但可以重写rmem_max限制。
SO_RCVLOWAT and SO_SNDLOWAT
指定套接层传递数据到协议(SO_SNDLOWAT)或用户接收(SO_RCVLOWAT)时,缓冲区至少应该有多少字节数。两个值都初始化为1.SO_SNDLOWAT在Linux下是不可修改的(setsockopt以错误ENOPROTOOPT失败)。SO_RCVLOWAT从Linux 2.4开始可以修改。现行的select和poll系统调用并不理会Linux上的SO_RCVLOWAT设置,哪怕只有1字节可用也会标记套接字可读,接着的读取会被阻塞,直到SO_RCVLOWAT字节数可用。
SO_RCVTIMEO and SO_SNDTIMEO
指定接收或发送报告错误之前的超时值。参数是一个timeval结构。如果一个输入或输出函数在这段时间内阻塞,数据也已经被发送或接收,则其返回值将是传输的数据量;如果没有传输任何数据而超时,则其返回-1并设置EAGAIN或EWOULDBLOCK,就好像套接字是非阻塞的一样。如果超时值设置为0,则操作将一直阻塞。超时只是针对执行套接字I/O的系统调用如read,recvmsg,send,sendmsg有效,对select,poll,epoll_wait等则无效。
SO_REUSEADDR
指定提供给bind调用的本地地址是否允许被重用。对于AF_INET套接字,这意味着,除了当前活跃的监听套接字地址之外,它可以绑定任意的地址。当监听套接字绑定到INADDR_ANY和一个特定的端口,则无法将任意地址绑定到该端口。参数是一个整数布尔标记。
SO_SNDBUF
设置或获取最大套接字缓冲区字节数。在setsockopt时内核将此值加倍,调用getsockopt是就返回加倍值。默认值可以在/proc/sys/net/core/wmem_default修改,最大允许值可以在/proc/sys/net/core/wmem_max修改。此选项传递的最小(加倍过的)值是2048。
SO_SNDBUFFORCE (since Linux 2.6.14)
使用套接字选项,特权(CAP_NET_ADMIN)进程可以执行与SO_SNDBUF一样的任务,但wmem_max限制可以被重写。
SO_TIMESTAMP
启用或禁用接收SO_TIMESTAMP控制消息。时间戳控制消息以level值SOL_SOCKET发送,cmsg_data字段放置一个timeval结构,说明用户在套接字上最后发送包的时间。参见cmsg(3)了解控制消息的细节。
SO_TYPE
获取套接字类型(诸如SOCK_STREAM)。只读选项。
信号
当向一个已经关闭(被本地或远程端)的连接套接字写时,SIGPIPE会被递送到写进程,且调用返回EPIPE。如果写调用指定了MSG_NOSIGNAL标记则不发送信号。
当事先用fcntl设置了FIOSETOWN或用ioctl设置了SIOCSPGRP时,每当发生I/O事件都会被递送SIGIO信号。可以在信号处理程序中调用poll或select以了解是那个套接字触发了信号。一个替代方案(in Linux 2.2)是调用fcntl以F_SETSIG设置实时信号;文件描述符将通过siginfo_t的si_fd字段传递给信号处理程序。参见fcntl(2)了解更多。
在某些情况下(例如,多个进程访问单个套接字),引起SIGIO的条件也许在进程相应信号时已经消失。如果出现这种情况,进程应该再次等待,因为Linux会重发信号。
/proc接口
内核网络参数可以通过目录/proc/sys/net/core/下的文件访问。
rmem_default
包含套接字接收缓冲区字节数的默认设置。
rmem_max
包含套接字用户可以用SO_RCVBUF选项设置的上限值。
wmem_default
包含套接字发送缓冲区字节数的默认设置。
wmem_max
包含套接字用户可以用SO_SNDBUF选项设置的上限值。
message_cost and message_burst
configure the token bucket filter used to load limit warning messages caused by external network events.
netdev_max_backlog
全局输入队列中包的最大数目。
optmem_max
每个套接字允许传递的辅助数据或用户控制数据像iovecs的最大长度。
Ioctls
以下操作可以被如下访问:
error = ioctl(ip_socket, ioctl_type, &value_result);
SIOCGSTAMP
返回一个timeval结构,表示用户最后一次接到包时间戳。这是非常准确的往返时间测量。参见setitimer了解timeval的详细信息。如果套接字选项SO_TIMESTAMP没有被设置,ioctl是唯一可用的。如果SO_TIMESTAMP没有设置,它返回最后一个包的时间戳,或者如果没有收到这样的一个包而失败(亦即,ioctl以错误ENOENT返回-1)。
SIOCSPGRP
设置进程或进程组发送SIGIO或SIGURG信号,当一个异步I/O操作完成或紧急数据可用。参数是一个pid_t的指针。如果参数是正数,发送信号到进程,如果参数是负数,发送信号到进程组。进程只能选择自己或它拥有的进程组接收信号,除非它具有CAP_KILL特权或有效UID为0。
FIOASYNC
改变O_ASYNC标记以启用或禁用异步I/O模式。异步I/O模式意味着SIGIO信号或以F_SETSIG设置的信号将在新的I/O事件发生时提交。
参数是一个整数布尔标记。(此操作与fcntl设置O_ASYNC标记相同)
SIOCGPGRP
获取当前接收SIGIO或SIGURG信号的进程或进程组,如果未设置则返回0。
有效的fcntl操作:
FIOGETOWN
与ioctl调用SIOCGPGRP相同。
FIOSETOWN
与ioctl调用SIOCSPGRP相同。
VERSIONS
SO_BINDTODEVICE在Linux 2.0.30中介绍。SO_PASSCRED在Linux 2.2介绍。/proc接口在Linux 2.2中介绍。SO_RCVTIMEO和SO_SNDTIMEO从Linux 2.3.41开始支持。更早的超时是特定协议的固定值,无法修改。
NOTES
Linux假设发送/接收缓冲区的一半是用于内核内部结构,因此/proc文件上观察的值是使用值的两倍。
Linux只允许之前的某个程序执行bind调用了SO_REUSEADDR的情况下,当前进程也希望重用端口时重用端口。这不同于其它一些实现(如FreeBSD)那样只要求后面的程序设置SO_REUSEADDR选项。实际上这种不同是透明的,因为所有服务器程序被设计为总是启用此选项。
BUGS
The CONFIG_FILTER socket options SO_ATTACH_FILTER and SO_DETACH_FILTER
are not documented. The suggested interface to use them is via the
libpcap library.
SEE ALSO
getsockopt(2), setsockopt(2), socket(2), capabilities(7), ddp(7),
ip(7), packet(7), tcp(7), udp(7), unix(7)
COLOPHON
This page is part of release 3.23 of the Linux man-pages project. A
description of the project, and information about reporting bugs, can
be found at
转载自:http://www.cnblogs.com/huyc/archive/2011/10/15/2212947.html