socket - Linux 套接字
总览
#include <sys/socket.h>
mysocket =
socket(int socket_family, int socket_type, int
protocol);
描述
本手册页介绍了 Linux 套接字的用户接口. 这个 BSD 兼容套接字是介于用户进程与内核网络协议栈之间的统一接口,
各协议模块属于不同的 协议族 ,如 PF_INET, PF_IPX, PF_PACKET 和
套接字类型 ,如 字节流(SOCK_STREAM) 或 数据报(SOCK_DGRAM). 关于协议族和套接字类型请参考
socket(2).
套接层函数
用户通过这些套接字函数发送和接收包, 以及其他套接字操作. 详细说明参看他们各自的手册页.
socket(2) 创建套接字,
connect(2) 与远程套接字地址建立连接
bind(2) 把套接字和一个本地套接字地址绑定在一起(为套接字分配一个本地协议地址)
listen(2) 通知套接字接受新的连接
accept(2) 为新的已完成连接获得新的描述字
socketpair(2) 返回两个连接的匿名套接字(仅在某些本地族中才有实现,如 PF_UNIX)
send(2),
sendto(2), 和 sendmsg(2) 通过套接字发送数据,而 recv(2),
recvfrom(2), recvmsg(2) 从套接字接收数据. poll(2) 和
select(2) 等待数据到来或准备好接收数据. 除此之外, 标准 I/O 操作如 write(2),
writev(2), sendfile(2), read(2), 和
readv(2) 也可用来读入(接收)和写出(发送)数据.
getsockname(2) 用于获得本地套接字地址
getpeername(2) 用于获得远端套接字地址. getsockopt(2) 和
setsockopt(2) 用于设置或取得套接字或协议选项. ioctl(2) 也可以用来设置或读取一些其他选项.
close(2) 关闭套接字. shutdown(2) 关闭全双工套接字连接的一部分.
套接字不支持搜索,也不支持调用 pread(2) 或 pwrite(2) 进行非 0 位置的操作. 可以用
fcntl(2). 设置 O_NONBLOCK 标志来实现对套接字的非阻塞 I/O 操作 O_NONBLOCK
是从 accept 继承来的,然后原来所有会阻塞的操作会返回 EAGAIN. connect(2) 在此情况下返回
EINPROGRESS 错误. 用户可以通过 poll(2) 或者 select(2) 等待各种事件.
I/O 事件 | ||
事件 | 轮询标志 | 发生事件 |
读 | POLLIN | 新数据到达. |
读 | POLLIN | (对面向连接的套接字)建立连接成功 |
读 | POLLHUP | 另一端套接字发出断开连接请求. |
读 | POLLHUP | (仅对面向连接协议)套接字写的时候连接断开. 同时发送 SIGPIPE. |
写 | POLLOUT | 套接字有充足的发送缓冲区用于写入新数据. |
读/写 | POLLIN| POLLOUT |
发出的 connect(2) 结束. |
读/写 | POLLERR | 产生一个异步错误. |
读/写 | POLLHUP | 对方已经单向关闭连接. |
例外 | POLLPRI | 紧急数据到达.然后发送 SIGURG. |
另外一个的 poll/select 方法是让内核用 SIGIO 信号来通知应用程序. 要这么用的话你必须用
fcntl(2) 设置套接字文件描述符的 FASYNC 标志,并用 sigaction(2). 给
SIGIO 信号设置一个的有效信号处理句柄.参看下面的 SIGNALS 的讨论.
套接字选项
套接字选项可以用 setsockopt(2) 来设置,用 getsockopt(2)
读取所有套接字级别设为 SOL_SOCKET 的套接字的套接字选项:
- SO_KEEPALIVE
- 允许在面向连接的套接字上发送 keep-alive 消息的功能.是一个布尔整数.
- SO_OOBINLINE
- 如果打开这个选项,带外(Out-of-Band)数据可以直接放入接收数据流。否则,只有接收时打开 MSG_OOB 标志, 才接收带外数据.
- SO_RCVLOWAT 和 SO_SNDLOWAT
- 声明在开始向协议 (SO_SNDLOWAT) 或正在接收数据的用户 (SO_RCVLOWAT).
传递数据之前缓冲区内的最小字节数. 在 Linux 中这两个值是不可改变的, 固定为 1 字节. 可以用 getsockopt 用来读取它们的值;
setsockopt 总是返回 ENOPROTOOPT. - SO_RCVTIMEO 和 SO_SNDTIMEO
- 发送和接收时的超时设定, 并在超时时报错. 在 Linux 中由协议指定, 不能被读写. 它们的功能可用 alarm(2) 或者
setitimer(2). 来模拟. - SO_BSDCOMPAT
- 允许 BSD 的 bug-to-bug 兼容. 这一项只能在 UDP 协议模块中使用而且今后将要取消. 如果允许的话, UDP 套接字接收到的 ICMP
错误将不会被传送至用户程序. Linux 2.0 中对于原始套接字也允许 BSD bug-to-bug 兼容(报头随机改变,省略广播标识),但在 Linux
2.2 中取消了这一项. 修改用户程序的方式比较好. - SO_PASSCRED
- 允许或关闭 SCM_CREDENTIALS 控制消息的接收. 更多信息参见 unix(7).
- SO_PEERCRED
- 返回连接至此套接字的外部进程的身份验证. 只在 PF_UNIX 套接字中有用.参见 unix(7). 参数为
ucred 结构.只在 getsockopt. 中有效. - SO_BINDTODEVICE
- 将此套接字绑定到一个特定的设备上, 如lqeth0rq, 做为指定的接口名字传递. 如果名称是空字符串或此项长度为 0, 则套接字设备绑定被取消.
过去的选项是一个变长的空零结尾的接口名称的字符串, 其最大长度为 IFNAMSIZ. 如果一个套接字被绑定至一接口,
只有由这个特定接口接收的信息包可以由此套接字处理. - SO_DEBUG
- 允许套接字调试.只对有 CAP_NET_ADMIN 功能或有效用户标识为 0 的进程有效.
- SO_REUSEADDR
- 表示在一个 bind(2) 调用中对提供给它的地址使用的确认规则应该允许重复使用本地地址. 对于 PF_INET
套接字, 这表示该套接字可以绑定, 除非已有一个活跃的侦听套接口绑定到此地址上. 如果这个侦听套接字和一个指定端口绑定为 INADDR_ANY
时, 它就不能再绑定到任何本地地址的此端口. - SO_TYPE
- 按整数返回套接字类型(如 SOCK_STREAM) 只能通过 getsockopt 读取.
- SO_DONTROUTE
- 不通过网关发送, 只能发送给直接连接的主机.可以通过在套接字的 send(2) 操作上设置
MSG_DONTROUTE 标志来实现相同的效果. 其值为布尔型整数的标识. - SO_BROADCAST
- 设置或获取广播标识. 当选择此选项时, 数据报套接字接收向广播地址发送的数据包, 并且可以向广播地址发送数据包. 这一选项对于面向流的套接字无效.
- SO_SNDBUF
- 设置或得到套接字发送缓冲区的最大字节数. 其默认值由 wmem_default sysctl 设置,最大允许值由
wmem_max sysctl 设置. - SO_RCVBUF
- 设置或得到套接字接收缓冲区的最大字节数。其默认值由 rmem_default sysctl设置,最大允许值由
rmem_max sysctl 设置. - SO_LINGER
- 设置或获取 SO_LINGER 选项的值. 其参数为 linger 结构.
-
struct linger {
int l_onoff; /* 延时状态(打开/关闭) */
int l_linger; /* 延时多长时间 */
};
- 如果选择此选项, close(2) 或 shutdown(2) 将等到所有套接字里排队的消息成功发送或到达延迟时间后才会返回. 否则, 调用将立即返回. 而 closing 操作将在后台进行. 如果套接字是 exit(2), 的一部分关闭时, 它总是在后台延迟进行的.
- SO_PRIORITY
- 设置在此套接字发送的所有包的协议定义优先权. Linux 通过这一值来排列网络队列: 根据所选设备排队规则, 具有更高优先权的包可以先被处理.对于 ip(7), 同时也设置了输出包的 IP 服务类型(TOS)的域.
- SO_ERROR
- 取得并清除未解决的套接字错误. 只有在 getsockopt. 时有效. 是一个整数值.
SIGNALS
当向一个已关闭(被本地或远程终端)的面向联接的套接字写入时, 将向该写入进程发送 SIGPIPE 信号,并返回 EPIPE 如果写入命令声明了 MSG_NOSIGNAL 标识时, 不会发出此信号.
如果与 FIOCSETOWN fcntl 或 SIOCSPGRP ioctl 一起请求,那么当发生 I/O 事件时发出 SIGIO 这样我们就可以在信号句柄里使用 poll(2) 或 select(2) 找出发生事件的套接字. 另一种选择(在 Linux 2.2 中)是用 F_SETSIG fcntl 设置一个实时信号: 实时信号的处理程序被调用时还会收到它的 siginfo_t 的 si_fd 区域中的文件描述符. 更多信息参见 fcntl(2)
在某些环境中(例如:多个进程访问单个套接字), 引发 SIGIO 的东西在进程对信号作出反应时可能已经消失了. 如果这样的话, 进程应该再次等待, 因为 Linux 稍后会重发此信号.
SYSCTLS
可以通过目录 /proc/sys/net/core/* 下的文件或者用 sysctl(2) 系统调用来访问内核套接字的网络系统控制(sysctl)信息.
- rmem_default
- 指明套接字接收缓冲区的默认字节数.
- rmem_max
- 指明套接字接收缓冲区的最大字节数, 用户可以通过使用 SO_RCVBUF 套接字选项来设置此值.
- wmem_default
- 指明套接字发送缓冲区的默认字节数.
- wmem_max
- 指明发送缓冲区的最大字节数,用户可以通过使用套接字的 SO_SNDBUF 选项来设置它的值.
- message_cost 和 message_burst
- 设定记号存储桶过滤器, 在存储桶中保存一定数量的外部网络事件导致的警告消息.
- netdev_max_backlog
- 在全局输入队列中包的最大数目.
- optmem_max
- 每个套接字的象 iovecs 这样的辅助数据和用户控制数据的最大长度.
IOCTLS
以上的 IO 控制值可以通过 ioctl(2) 来访问:
-
error = ioctl(ip_socket, ioctl_type, &value_result);
- SIOCGSTAMP
- 返回 timeval 类型的结构,其中包括有发送给用户的最后一个包接收时的时间戳。被用来测量精确的 RTT (round trip time) 时间. struct timeval. 结构说明请参考 setitimer(2)
- SIOCSPGRP
- 在异步 IO 操作结束或者接收到紧急数据时,用来设置进程或进程组,向它(它们)发送 SIGIO 或者 SIGURG 信号, 参数为指向 pid_t. 类型的指针。如果参数为正,则发送信号到相应的进程。如果参数为负,则发送信号到此参数绝对值 id 所属的进程组的所有进程。如果它没有 CAP_KILL 功能或者它的有效 UID 不是 0, 进程只能选择它自己或自己的进程组来接收信号.
- FIOASYNC
- 改变 O_ASYNC 标志来打开或者关闭套接字的异步 IO 模式。异步IO模式指的是:当新的 I/O 事件发生时,将发出 SIGIO 信号或者用 F_SETSIG 设置的信号.
- 参数为整形布尔量.
- SIOCGPGRP
- 获得当前接收 SIGIO 或者 SIGURG 信号的进程或者进程组, 如果两个信号都没有设置, 则为 0.
有效的 fcntl:
- FIOCGETOWN
- 与 IO 控制中的 SIOCGPGRP 相同.
- FIOCSETOWN
- 与 IO 控制中的 SIOCSPGRP 相同.
注意
Linux 假设有一半的发送/接收缓冲区是用来处理内核结构, 因此, 系统控制的缓冲区是网络可访问的缓冲区的两倍.
缺陷
CONFIG_FILTER 没有介绍 SO_ATTACH_FILTER 和 SO_DETACH_FILTER 套接字选项. 在 libpcap 库有此接口的说明
socket - Linux 套接字的更多相关文章
- Linux套接字编程
网络中的进程是如何通信的? 在网络中进程之间进行通信的时候,那么每个通信的进程必须知道它要和哪个计算机上的哪个进程通信.否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行 ...
- iOS - Socket 网络套接字
1.Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 Socket.Socket 又称 "套接字",应用程序通常通过 "套接字& ...
- linux 套接字编程入门--Hello World
下述代码是linux套接字编程的入门代码.分为服务端和客户端源码. 服务端代码的主要流程是绑定ip地址和端口号建立套接字,等待客户端发起访问.接受客户端请求之后,向客户端发送字符串"hell ...
- Linux 套接字编程中的 5 个隐患(转)
本文转自IBM博文Linux 套接字编程中的 5 个隐患. “在异构环境中开发可靠的网络应用程序”. Socket API 是网络应用程序开发中实际应用的标准 API.尽管该 API 简单,但是开发新 ...
- 【 Linux 】Linux套接字简要说明
Linux套接字 源IP地址和目的IP地址以及源端口和目标端口号的组合称为套接字.其作用于标识客户端请求的服务器和服务. 套接字,支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间 ...
- Socket称"套接字"
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 二.利用Socket建立网络连接的步骤 建立Socket连接至少需要一对 ...
- Win2 Socket(套接字)相关 API
Socket(套接字) 作者信息 肖进 单位:南京中萃食品有限公司 资讯部 邮箱:xiaoj@njb.swirebev.com 电话:025-58642091 与socket有关的一些函数介绍 1.读 ...
- python 全栈开发,Day33(tcp协议和udp协议,互联网协议与osi模型,socket概念,套接字(socket)初使用)
先来回顾一下昨天的内容 网络编程开发架构 B/S C/S架构网卡 mac地址网段 ip地址 : 表示了一台电脑在网络中的位置 子网掩码 : ip和子网掩码按位与得到网段 网关ip : 内置在路由器中的 ...
- socket概念 套接字
理解socket soxket因为TCP是面向流的,你发的信息如果很多很快,TCP这样就会形成黏包 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socke ...
随机推荐
- JAVA四种引用方式
JAVA四种引用方式: java.lang.ref: 强引用(直接变量赋值) 软引用(SoftReference): 只有在要发生OOM错误之前才会回收掉老的软引用对象,应用场景主要防止内存溢出.(缓 ...
- 【串线篇】spring boot外部配置加载顺序
SpringBoot也可以从以下位置加载配置: 原则仍然是优先级从高到低:高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置 1.命令行参数 所有的配置都可以在命令行上进行指定 java -j ...
- 对webpack的初步研究4
Mode string module.exports = { mode: 'production' }; webpack --mode=production The following string ...
- python网络编程之验证客户端链接的合法性
六.socket的更多方法介绍 服务端套接字函数s.bind() 绑定(主机,端口号)到套接字s.listen() 开始TCP监听s.accept() b被动接收TCP客户的连接,(阻塞式)等待连接的 ...
- Leetcode_395. Longest Substring with At Least K Repeating Characters_[Devide and Conquer]
题目链接 对一个字符串,找出一个最长的子串长度,这个子串中所有字符出现的次数至少为k. 1.滑动窗口 一开始把题目看成了,子串中每个字符至多出现k次.如果是这样,那么是一道典型的滑动窗口的题目. 然而 ...
- MapGIS IGServer for java
但是安装完之后,服务里面没有找到igserver服务 IGServer SManager cxf 怎么会找不到类呢?是服务映射出了问题,所以目录找不到.所以怎么配置目录呢?是在xml还是环境变量,还是 ...
- Java继承基础版
继承是软件开发中实现代码复用的有效手段,如果一个类A继承了类B那么类B中的public.protected及默认修饰符修饰的实例成员或静态成员将被类A继承,也可以说类B的成员就是类A的成员而类A在此基 ...
- 20180805-Java DataInputStream类
DataInputStream dis = DataInputStream(InputStream in); 下面的例子演示了DataInputStream和DataOutputStream的使用,该 ...
- 2019ICPC上海网络赛A 边分治+线段树
题目: 给定一棵树, 带边权. 现在有2种操作: 1.修改第i条边的权值. 2.询问u到其他一个任意点的最大距离是多少. 解法:边分治+线段树 首先我们将所有的点修改和边修改都存在对应的边里面. 然后 ...
- Oulipo (poj3461
Oulipo Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29759 Accepted: 11986 Descript ...