在线文档教程
Ruby 2.4

Socket

Socket类

Parent:BasicSocket

Class Socket提供对底层操作系统套接字实现的访问。它可以用来提供比特定于协议的套接字类更多的操作系统特定的功能。

在Socket::Constants下定义的常量也在Socket下定义。例如,Socket::AF_INET可以使用以及Socket::Constants::AF_INET。请参阅Socket::Constants获取常量列表。

什么是套接字?

套接字是双向通信通道的端点。套接字可以在进程内,同一机器上的进程或不同机器之间进行通信。有很多类型的套接字:例如TCPSocket,UDPSocket或UNIXSocket。

套接字有自己的词汇:

域:协议族:

  • Socket::PF_INET

  • Socket::PF_INET6

  • Socket::PF_UNIX

  • etc.

键入:典型的两个端点之间的通信类型

  • Socket::SOCK_STREAM

  • Socket::SOCK_DGRAM.

协议:通常为零。这可以用来识别协议的变体。

主机名:网络接口的标识符:

  • 一个字符串(主机名,IPv4或IPv6地址或broadcast指定广播地址)

  • 一个指定INADDR_ANY的零长度字符串

  • 一个整数(按主机字节顺序解释为二进制地址)。

  • Zach Dennis

  • Sam Roberts

  • 从实用书架编程Ruby

本文档中的许多内容是经过The Pragmatic Bookshelf 编程Ruby的许可获得的。

常量

AF_APPLETALK

AppleTalk协议

AF_ATM

异步传输模式

AF_AX25

AX.25协议

AF_CCITT

CCITT(现在的ITU-T)协议

AF_CHAOS

MIT CHAOS协议

AF_CNT

计算机网络技术

AF_COIP

面向连接的IP

AF_DATAKIT

Datakit协议

AF_DEC

DECnet协议

AF_DLI

DEC直接数据链路接口协议

AF_E164

CCITT(ITU-T)E.164建议

AF_ECMA

欧洲电脑制造商协议

AF_HYLINK

NSC Hyperchannel协议

AF_IMPLINK

ARPANET IMP协议

AF_INET

IPv4协议

AF_INET6

IPv6协议

AF_IPX

IPX协议

AF_ISDN

综合业务数字网络

AF_ISO

ISO开放系统互连协议

AF_LAT

局域传输协议

AF_LINK

链路层接口

AF_LOCAL

主机内部协议

AF_MAX

此平台的最大地址族

AF_NATM

本地ATM访问

AF_NDRV

网络驱动程序原始访问

AF_NETBIOS

NetBIOS

AF_NETGRAPH

Netgraph套接字

AF_NS

XEROX NS协议

AF_OSI

ISO开放系统互连协议

AF_PACKET

直接链接层访问

AF_PPP

点对点协议

AF_PUP

PARC通用分组协议

AF_ROUTE

内部路由协议

AF_SIP

简单的Internet协议

AF_SNA

IBM SNA协议

AF_SYSTEM AF_UNIX

UNIX套接字

AF_UNSPEC

未指定协议,任何受支持的地址系列

AI_ADDRCONFIG

只有在分配了任何地址时才接受

AI_ALL

允许所有地址

AI_CANONNAME

填写规范名称

AI_DEFAULT

getaddrinfo的默认标志

AI_MASK

getaddrinfo的有效标志掩码(不适用于应用程序)

AI_NUMERICHOST

防止主机名称解析

AI_NUMERICSERV

防止服务名称解析

AI_PASSIVE

获取使用bind()的地址

AI_V4MAPPED

接受IPv4映射的IPv6地址

AI_V4MAPPED_CFG

如果内核支持它,则接受IPv4映射地址

EAI_ADDRFAMILY

不支持主机名的地址族

EAI_AGAIN

名称解析中的临时失败

EAI_BADFLAGS

无效的标志

EAI_BADHINTS

提示值无效

EAI_FAIL

不可恢复的名称解析失败

EAI_FAMILY

地址家族不受支持

EAI_MAX

来自getaddrinfo的最大错误代码

EAI_MEMORY

内存分配失败

EAI_NODATA

没有与主机名关联的地址

EAI_NONAME

主机名或服务名称,或未知

EAI_OVERFLOW

参数缓冲区溢出

EAI_PROTOCOL

解决的协议是未知的

EAI_SERVICE

套接字类型不支持Servname

EAI_SOCKTYPE

套接字类型不受支持

EAI_SYSTEM

errno:返回系统错误

IFF_802_1Q_VLAN

802.1Q VLAN设备

IFF_ALLMULTI

接收所有组播数据包

IFF_ALTPHYS

使用备用物理连接

IFF_AUTOMEDIA

自动媒体选择活动

IFF_BONDING

绑定主机或从机

IFF_BRIDGE_PORT

设备用作网桥端口

IFF_BROADCAST

广播地址有效

IFF_CANTCHANGE

标志不可更改

IFF_CANTCONFIG

使用ioctl(2)无法配置

IFF_DEBUG

打开调试

IFF_DISABLE_NETPOLL

在运行时禁用netpoll

IFF_DONT_BRIDGE

不允许桥接此以太网

IFF_DORMANT

使用者信号休眠

IFF_DRV_OACTIVE

tx硬件队列已满

IFF_DRV_RUNNING

资源分配

IFF_DYING

界面正在收敛

IFF_DYNAMIC

具有更改地址的拨号设备

IFF_EBRIDGE

以太网桥接设备

IFF_ECHO

回送发送数据包

IFF_ISATAP

ISATAP interface (RFC4214)

IFF_LINK0

每个链路层定义了位0

IFF_LINK1

每个链路层定义位1

IFF_LINK2

每个链路层定义位2

IFF_LIVE_ADDR_CHANGE

硬件地址在运行时发生变化

IFF_LOOPBACK

回环网

IFF_LOWER_UP

驱动器发出L1信号

IFF_MACVLAN_PORT

设备用作macvlan端口

IFF_MASTER

负载平衡器的主人

IFF_MASTER_8023AD

绑定主机,802.3ad。

IFF_MASTER_ALB

结合主人,平衡alb。

IFF_MASTER_ARPMON

绑定大师,ARP mon在使用中

IFF_MONITOR

用户请求的监视器模式

IFF_MULTICAST

支持多播式

IFF_NOARP

没有地址解析协议

IFF_NOTRAILERS

避免使用拖车设备

IFF_OACTIVE

传输正在进行中

IFF_OVS_DATAPATH

设备用作Open vSwitch数据路径端口

IFF_POINTOPOINT

点对点链接

IFF_PORTSEL

可以设置媒体类型

IFF_PPROMISC

用户请求的promisc模式

IFF_PROMISC

接收所有数据包

IFF_RENAMING

界面正在重命名

IFF_ROUTE

路由条目已安装

IFF_RUNNING

资源分配

IFF_SIMPLEX

无法接收自己的传输

IFF_SLAVE

负载均衡器的从属者

IFF_SLAVE_INACTIVE

bonding slave not the curr. active

IFF_SLAVE_NEEDARP

需要ARPs进行验证

IFF_SMART

接口管理自己的路由

IFF_STATICARP

静态ARP

IFF_SUPP_NOFCS

发送自定义的FCS

IFF_TEAM_PORT

用作团队端口

IFF_TX_SKB_SHARING

在传输上共享skbs

IFF_UNICAST_FLT

单播过滤

IFF_UP

界面已启动

IFF_VOLATILE

易失标志

IFF_WAN_HDLC

WAN HDLC设备

IFF_XMIT_DST_RELEASE

dev_hard_start_xmit()被允许释放skb-> dst

IFNAMSIZ

最大接口名称大小

IF_NAMESIZE

最大接口名称大小

INADDR_ALLHOSTS_GROUP

该子集上所有系统的多播组

INADDR_ANY

绑定到INADDR_ANY的套接字接收来自所有接口的数据包并从默认IP地址发送数据包

INADDR_BROADCAST

网络广播地址

INADDR_LOOPBACK

环回地址

INADDR_MAX_LOCAL_GROUP

最后一个本地网络多播组

INADDR_NONE

用于匹配无效IP地址的位掩码

INADDR_UNSPEC_GROUP

保留的多播组

INET6_ADDRSTRLEN

IPv6地址字符串的最大长度

INET_ADDRSTRLEN

IPv4地址字符串的最大长度

IPPORT_RESERVED

绑定或连接的默认最小地址

IPPORT_USERRESERVED

绑定或连接的默认最大地址

IPPROTO_AH

IP6身份验证标头

IPPROTO_BIP IPPROTO_DSTOPTS

IP6目标选项

IPPROTO_EGP

外部网关协议

IPPROTO_EON

ISO cnlp

IPPROTO_ESP

IP6封装的安全负载

IPPROTO_FRAGMENT

IP6分段头

IPPROTO_GGP

网关协议网关

IPPROTO_HELLO

“hello”路由协议

IPPROTO_HOPOPTS

IP6逐跳选项

IPPROTO_ICMP

控制消息协议

IPPROTO_ICMPV6

ICMP6

IPPROTO_IDP

XNS IDP

IPPROTO_IGMP

组管理协议

IPPROTO_IP

IP虚拟协议

IPPROTO_IPV6

IP6头部

IPPROTO_MAX

最大恒定IPPROTO

IPPROTO_ND

Sun网盘协议

IPPROTO_NONE

IP6没有下一个标题

IPPROTO_PUP

PARC通用分组协议

IPPROTO_RAW

原始IP数据包

IPPROTO_ROUTING

IP6路由头

IPPROTO_TCP

TCP

IPPROTO_TP

ISO传输协议类4

IPPROTO_UDP

UDP

IPPROTO_XTP

Xpress传输协议

IPV6_CHECKSUM

原始套接字的校验和偏移量

IPV6_DONTFRAG

不要分组数据包

IPV6_DSTOPTS

目的地选项

IPV6_HOPLIMIT

跳跃限制

IPV6_HOPOPTS

逐跳选项

IPV6_JOIN_GROUP

加入小组成员资格

IPV6_LEAVE_GROUP

留下组员资格

IPV6_MULTICAST_HOPS

IP6组播跳数

IPV6_MULTICAST_IF

IP6多播接口

IPV6_MULTICAST_LOOP

IP6组播环回

IPV6_NEXTHOP

下一跳地址

IPV6_PATHMTU

检索当前路径MTU

IPV6_PKTINFO

用数据报接收数据包信息

IPV6_RECVDSTOPTS

接收所有IP6选项以进行响应

IPV6_RECVHOPLIMIT

用数据报接收跳数限制

IPV6_RECVHOPOPTS

接收逐跳选项

IPV6_RECVPATHMTU

用数据报接收当前路径MTU

IPV6_RECVPKTINFO

接收目标IP地址和传入界面

IPV6_RECVRTHDR

接收路由头

IPV6_RECVTCLASS

接收流量类别

IPV6_RTHDR

允许删除粘性路由头

IPV6_RTHDRDSTOPTS

允许删除粘性目标选项标题

IPV6_RTHDR_TYPE_0

路由头部类型0

IPV6_TCLASS

指定流量类别

IPV6_UNICAST_HOPS

IP6单播跳数

IPV6_USE_MIN_MTU

使用最小的MTU大小

IPV6_V6ONLY

仅将IPv6绑定到通配符绑定

IPX_TYPE IP_ADD_MEMBERSHIP

添加多播组成员资格

IP_ADD_SOURCE_MEMBERSHIP

添加多播组成员资格

IP_BLOCK_SOURCE

阻止具有给定源地址的IPv4多播数据包

IP_DEFAULT_MULTICAST_LOOP

默认组播环回

IP_DEFAULT_MULTICAST_TTL

Default multicast TTL

IP_DONTFRAG

不要分组数据包

IP_DROP_MEMBERSHIP

删除多播组成员资格

IP_DROP_SOURCE_MEMBERSHIP

删除多播组成员资格

IP_FREEBIND

允许绑定到不存在的IP地址

IP_HDRINCL

标题包含在数据中

IP_IPSEC_POLICY

IPsec安全策略

IP_MAX_MEMBERSHIPS

套接字可以加入的最大组播组数量

IP_MINTTL

允许接收数据包的最小TTL

IP_MSFILTER

多播源过滤

IP_MTU

套接字的最大传输单位

IP_MTU_DISCOVER

MT路径发现

IP_MULTICAST_IF

IP组播接口

IP_MULTICAST_LOOP

IP组播环回

IP_MULTICAST_TTL

IP组播TTL

IP_ONESBCAST

强制传出的广播数据报具有无向广播地址

IP_OPTIONS

IP选项包含在数据包中

IP_PASSSEC

用数据报检索安全上下文

IP_PKTINFO

用数据报接收数据包信息

IP_PKTOPTIONS

用数据报接收数据包选项

IP_PMTUDISC_DO

始终发送DF帧

IP_PMTUDISC_DONT

永远不要发送DF帧

IP_PMTUDISC_WANT

使用每条路线提示

IP_PORTRANGE

为未指定端口号的套接字设置端口范围

IP_RECVDSTADDR

用数据报接收IP目标地址

IP_RECVERR

启用扩展可靠的错误消息传递

IP_RECVIF

用数据报接收接口信息

IP_RECVOPTS

用数据报接收所有IP选项

IP_RECVRETOPTS

接收所有IP选项以进行响应

IP_RECVSLLA

用数据报接收链路层地址

IP_RECVTOS

接收传入数据包的TOS

IP_RECVTTL

用数据报接收IP TTL

IP_RETOPTS

IP选项包含在数据报中

IP_ROUTER_ALERT

通知转接路由器更仔细地检查IP数据包的内容

IP_SENDSRCADDR

传出UDP数据报的源地址

IP_TOS

IP服务类型

IP_TRANSPARENT

透明代理

IP_TTL

IP生存时间

IP_UNBLOCK_SOURCE

使用给定源地址取消阻止IPv4组播数据包

IP_XFRM_POLICY LOCAL_CONNWAIT

连接块直到被接受

LOCAL_CREDS

将凭据传递给接收方

LOCAL_PEERCRED

检索对等证书

MCAST_BLOCK_SOURCE

阻止来自此源的多播数据包

MCAST_EXCLUDE

独有的组播源过滤器

MCAST_INCLUDE

包含多播源过滤器

MCAST_JOIN_GROUP

加入一个多播组

MCAST_JOIN_SOURCE_GROUP

加入一个组播源组

MCAST_LEAVE_GROUP

保留一个多播组

MCAST_LEAVE_SOURCE_GROUP

保留多播源组

MCAST_MSFILTER

多播源过滤

MCAST_UNBLOCK_SOURCE

取消阻止来自此源的组播数据包

MSG_COMPAT

记录结束

MSG_CONFIRM

确认路径有效性

MSG_CTRUNC

控制数据在交付之前丢失

MSG_DONTROUTE

发送时不使用路由表

MSG_DONTWAIT

该消息应该是非阻塞的

MSG_EOF

数据完成连接

MSG_EOR

数据完成记录

MSG_ERRQUEUE

从错误队列获取消息

MSG_FASTOPEN

减少握手过程的步骤

MSG_FIN MSG_FLUSH

开始保留序列。转储到so_temp

MSG_HAVEMORE

数据准备好被读取

MSG_HOLD

在so_temp中保存片段

MSG_MORE

发件人将发送更多

MSG_NOSIGNAL

不要生成SIGPIPE

MSG_OOB

处理带外数据

MSG_PEEK

查看收到的消息

MSG_PROXY

等待完整的请求

MSG_RCVMORE

数据保留在当前数据包中

MSG_RST MSG_SEND

在so_temp中发送数据包

MSG_SYN MSG_TRUNC

交货前丢弃数据

MSG_WAITALL

等待完整的请求或错误

NI_DGRAM

指定的服务是数据报服务(查找UDP端口)

NI_MAXHOST

主机名的最大长度

NI_MAXSERV

服务名称的最大长度

NI_NAMEREQD

名字是必需的

NI_NOFQDN

本地主机不需要FQDN,只返回本地部分

NI_NUMERICHOST

返回一个数字地址

NI_NUMERICSERV

将服务名称作为数字字符串返回

PF_APPLETALK

AppleTalk协议

PF_ATM

异步传输模式

PF_AX25

AX.25 protocol

PF_CCITT

CCITT(现在的ITU-T)协议

PF_CHAOS

MIT CHAOS协议

PF_CNT

计算机网络技术

PF_COIP

面向连接的IP

PF_DATAKIT

Datakit协议

PF_DEC

DECnet协议

PF_DLI

DEC直接数据链路接口协议

PF_ECMA

欧洲电脑制造商协议

PF_HYLINK

NSC Hyperchannel协议

PF_IMPLINK

ARPANET IMP协议

PF_INET

IPv4协议

PF_INET6

IPv6协议

PF_IPX

IPX协议

PF_ISDN

综合业务数字网络

PF_ISO

ISO开放系统互连协议

PF_KEY PF_LAT

局域传输协议

PF_LINK

链路层接口

PF_LOCAL

主机内部协议

PF_MAX

此平台的最大地址族

PF_NATM

本地ATM访问

PF_NDRV

网络驱动程序原始访问

PF_NETBIOS

NetBIOS

PF_NETGRAPH

Netgraph套接字

PF_NS

XEROX NS协议

PF_OSI

ISO开放系统互连协议

PF_PACKET

直接链接层访问

PF_PIP PF_PPP

点对点协议

PF_PUP

PARC通用分组协议

PF_ROUTE

内部路由协议

PF_RTIP PF_SIP

简单的Internet协议

PF_SNA

IBM SNA协议

PF_SYSTEM PF_UNIX

UNIX套接字

PF_UNSPEC

未指定协议,任何受支持的地址系列

PF_XTP

eXpress传输协议

SCM_BINTIME

时间戳(二进制时间)

SCM_CREDENTIALS

发件人的凭据

SCM_CREDS

流程凭证

SCM_RIGHTS

访问权

SCM_TIMESTAMP

时间戳(timeval)

SCM_TIMESTAMPING

时间戳(timespec list)(Linux 2.6.30)

SCM_TIMESTAMPNS

Timespec (timespec)

SCM_UCRED

用户凭据

SCM_WIFI_STATUS

Wifi status (Linux 3.3)

SHUT_RD

关闭套接字的读取侧

SHUT_RDWR

关闭套接字的两侧

SHUT_WR

关闭套接字的写入侧

SOCK_DGRAM

数据报套接字提供无连接,不可靠的消息

SOCK_PACKET

设备级数据包访问

SOCK_RAW

原始套接字为直接访问或实现网络协议提供低级访问

SOCK_RDM

可靠的数据报套接字提供可靠的消息传递

SOCK_SEQPACKET

顺序数据包套接字为数据报提供顺序,可靠的双向连接

SOCK_STREAM

流套接字为字节流提供有序的,可靠的双向连接

SOL_ATALK

AppleTalk套接字选项

SOL_AX25

AX.25插座选项

SOL_IP

IP套接字选项

SOL_IPX

IPX套接字选项

SOL_SOCKET

套接字级选项

SOL_TCP

TCP套接字选项

SOL_UDP

UDP套接字选项

SOMAXCONN

可能为套接字排队的最大连接请求

SOPRI_BACKGROUND

后台套接字优先

SOPRI_INTERACTIVE

交互式套接字优先

SOPRI_NORMAL

正常的套接字优先

SO_ACCEPTCONN

Socket已经调用了listen()

SO_ACCEPTFILTER

有一个接受过滤器

SO_ALLZONES

绕过区域边界

SO_ATTACH_FILTER

附加接受过滤器

SO_BINDTODEVICE

只从给定接口发送数据包

SO_BINTIME

接收数据报的时间戳(bintime)

SO_BPF_EXTENSIONS

支持查询的BPF扩展(Linux 3.14)

SO_BROADCAST

允许发送广播消息

SO_BUSY_POLL

为低延迟轮询设置阈值(微秒)(Linux 3.11)

SO_DEBUG

调试信息记录

SO_DETACH_FILTER

分离接受过滤器

SO_DOMAIN

给出的socket()(Linux 2.6.32)

SO_DONTROUTE

使用接口地址

SO_DONTTRUNC

保留未读数据

SO_ERROR

获取并清除错误状态

SO_GET_FILTER

获取由SO_ATTACH_FILTER设置的过滤器(Linux 3.8)

SO_KEEPALIVE

保持连接活着

SO_LINGER

如果数据存在,则关闭

SO_LOCK_FILTER

锁定连接到插座的过滤器(Linux 3.9)

SO_MAC_EXEMPT

未标记同行的强制访问控制豁免

SO_MARK

设置标记路由标记(Linux 2.6.25)

SO_MAX_PACING_RATE

限制传输层计算的速率。每秒字节数

SO_NKE

安装套接字级网络内核扩展

SO_NOFCS

设置套接字的netns(Linux 3.4)

SO_NOSIGPIPE

不要在EPIPE上SIGPIPE

SO_NO_CHECK

禁用校验和

SO_NREAD

获取第一个数据包字节数

SO_OOBINLINE

在线接收收到的带外数据

SO_PASSCRED

接收SCM_CREDENTIALS消息

SO_PASSSEC

切换安全上下文传递(Linux 2.6.18)

SO_PEEK_OFF

设置窥视偏移量(Linux 3.4)

SO_PEERCRED

连接到此套接字的外部进程的凭据

SO_PEERNAME

连接用户的名称

SO_PEERSEC

获取安全凭证(Linux 2.6.2)

SO_PRIORITY

此套接字上所有数据包的协议定义优先级

SO_PROTOCOL

给出的socket()(Linux 2.6.32)

SO_RCVBUF

接收缓冲区大小

SO_RCVBUFFORCE

接收缓冲区大小,无rmem_max限制(Linux 2.6.14)

SO_RCVLOWAT

接收低水位标志

SO_RCVTIMEO

接收超时

SO_RECVUCRED

用数据报接收用户证书

SO_REUSEADDR

允许本地地址重用

SO_REUSEPORT

允许本地地址和端口重用

SO_RXQ_OVFL

切换cmsg丢弃的数据包数量(Linux 2.6.33)

SO_SECURITY_AUTHENTICATION SO_SECURITY_ENCRYPTION_NETWORK SO_SECURITY_ENCRYPTION_TRANSPORT SO_SELECT_ERR_QUEUE

使用select选择()检测套接字错误队列(Linux 3.10)

SO_SNDBUF

发送缓冲区大小

SO_SNDBUFFORCE

发送无wmem_max限制的缓冲区大小(Linux 2.6.14)

SO_SNDLOWAT

发送低水位标志

SO_SNDTIMEO

发送超时

SO_TIMESTAMP

接收数据报的时间戳(timeval)

SO_TIMESTAMPING

传入和传出数据包的时间标记(Linux 2.6.30)

SO_TIMESTAMPNS

接收数据报的纳秒时间戳(timespec)

SO_TYPE

获取套接字类型

SO_USELOOPBACK

尽可能旁路硬件

SO_WANTMORE

在更多数据准备就绪时给出提示

SO_WANTOOBFLAG

在接收MSG_FLAG时需要OOB数据

SO_WIFI_STATUS

切换cmsg为wifi状态(Linux 3.3)

TCP_CONGESTION

TCP拥塞控制算法(Linux 2.6.13,glibc 2.6)

TCP_COOKIE_TRANSACTIONS

TCP Cookie事务(Linux 2.6.33,glibc 2.18)

TCP_CORK

不要发送部分帧(Linux 2.2,glibc 2.2)

TCP_DEFER_ACCEPT

数据准备就绪之前不要通知监听套接字(Linux 2.4,glibc 2.2)

TCP_FASTOPEN

减少握手过程的步骤(Linux 3.7,glibc 2.18)

TCP_INFO

检索有关此套接字的信息(Linux 2.4,glibc 2.2)

TCP_KEEPCNT

丢弃连接前允许的最大Keepalive探测数(Linux 2.4,glibc 2.2)

TCP_KEEPIDLE

Keepalive探测器发送前的空闲时间(Linux 2.4,glibc 2.2)

TCP_KEEPINTVL

Keepalive探测器之间的时间间隔(Linux 2.4,glibc 2.2)

TCP_LINGER2

孤儿FIN_WAIT2套接字的生命周期(Linux 2.4,glibc 2.2)

TCP_MAXSEG

设置最大片段大小

TCP_MD5SIG

使用MD5摘要(RFC2385,Linux 2.6.20,glibc 2.7)

TCP_NODELAY

不要延迟发送来合并数据包

TCP_NOOPT

不要使用TCP选项

TCP_NOPUSH

不要推最后一块写

TCP_QUEUE_SEQ

修复模式的队列顺序(Linux 3.5,glibc 2.18)

TCP_QUICKACK

启用quickack模式(Linux 2.4.4,glibc 2.3)

TCP_REPAIR

修复模式(Linux 3.5,glibc 2.18)

TCP_REPAIR_OPTIONS

修复模式选项(Linux 3.5,glibc 2.18)

TCP_REPAIR_QUEUE

队列修复模式(Linux 3.5,glibc 2.18)

TCP_SYNCNT

连接丢失前的SYN重传次数(Linux 2.4,glibc 2.2)

TCP_THIN_DUPACK

针对瘦流量少的重复确认处理(Linux 2.6.34,glibc 2.18)

TCP_THIN_LINEAR_TIMEOUTS

少流量的线性超时(Linux 2.6.34,glibc 2.18)

TCP_TIMESTAMP

TCP timestamp (Linux 3.9, glibc 2.18)

TCP_USER_TIMEOUT

TCP连接中断前的最大超时(Linux 2.6.37,glibc 2.18)

TCP_WINDOW_CLAMP

限制广告窗口的大小(Linux 2.4,glibc 2.2)

UDP_CORK

不要发送部分帧(Linux 2.5.44,glibc 2.11)

公共类方法

accept_loop(*sockets) { |socket, client_addrinfo| ... } Show source

为每个通过给定套接字接受的连接生成套接字和客户端地址。

参数是套接字列表。单个参数应该是套接字或套接字数组。

该方法依次生成块。这意味着下一个连接在块返回之前不被接受。因此,并发机制(例如线程)应该一次用于为多个客户端提供服务。

# File ext/socket/lib/socket.rb, line 784 def self.accept_loop(*sockets) # :yield: socket, client_addrinfo sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end

getaddrinfo(nodename, servname[, family[, socktype[, protocol[, flags, reverse_lookup]]]]) → array Show source

获取nodenameservname的地址信息。

家庭应该是一个地址族,例如:INET,:INET6等。

socktype应该是一个套接字类型,例如::STREAM,:DGRAM,:RAW等。

协议应该是家族中定义的协议,并且该家族默认为0。

标志应该是Socket :: AI_ *常量的按位或。

Socket.getaddrinfo("www.ruby-lang.org", "http", nil, :STREAM) #=> [["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68", 2, 1, 6]] # PF_INET/SOCK_STREAM/IPPROTO_TCP Socket.getaddrinfo("localhost", nil) #=> [["AF_INET", 0, "localhost", "127.0.0.1", 2, 1, 6], # PF_INET/SOCK_STREAM/IPPROTO_TCP # ["AF_INET", 0, "localhost", "127.0.0.1", 2, 2, 17], # PF_INET/SOCK_DGRAM/IPPROTO_UDP # ["AF_INET", 0, "localhost", "127.0.0.1", 2, 3, 0]] # PF_INET/SOCK_RAW/IPPROTO_IP

reverse_lookup指示第三个元素的形式,并且必须是下面的一个。如果省略reverse_lookup,则默认值为nil

+true+, +:hostname+: hostname is obtained from numeric address using reverse lookup, which may take a time. +false+, +:numeric+: hostname is same as numeric address. +nil+: obey to the current +do_not_reverse_lookup+ flag.

如果Addrinfo对象是首选的,请使用Addrinfo.getaddrinfo。

static VALUE sock_s_getaddrinfo(int argc, VALUE *argv) { VALUE host, port, family, socktype, protocol, flags, ret, revlookup; struct addrinfo hints; struct rb_addrinfo *res; int norevlookup; rb_scan_args(argc, argv, "25", &host, &port, &family, &socktype, &protocol, &flags, &revlookup MEMZERO(&hints, struct addrinfo, 1 hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family if (!NIL_P(socktype)) { hints.ai_socktype = rsock_socktype_arg(socktype } if (!NIL_P(protocol)) { hints.ai_protocol = NUM2INT(protocol } if (!NIL_P(flags)) { hints.ai_flags = NUM2INT(flags } if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) { norevlookup = rsock_do_not_reverse_lookup; } res = rsock_getaddrinfo(host, port, &hints, 0 ret = make_addrinfo(res, norevlookup rb_freeaddrinfo(res return ret; }

gethostbyaddr(address_string , address_family) → hostent Show source

获取地址的主机信息。

p Socket.gethostbyaddr([221,186,184,68].pack("CCCC")) #=> ["carbon.ruby-lang.org", [], 2, "\xDD\xBA\xB8D"]

static VALUE sock_s_gethostbyaddr(int argc, VALUE *argv) { VALUE addr, family; struct hostent *h; char **pch; VALUE ary, names; int t = AF_INET; rb_scan_args(argc, argv, "11", &addr, &family StringValue(addr if (!NIL_P(family)) { t = rsock_family_arg(family } #ifdef AF_INET6 else if (RSTRING_LEN(addr) == 16) { t = AF_INET6; } #endif h = gethostbyaddr(RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), t if (h == NULL) { #ifdef HAVE_HSTRERROR extern int h_errno; rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno) #else rb_raise(rb_eSocket, "host not found" #endif } ary = rb_ary_new( rb_ary_push(ary, rb_str_new2(h->h_name) names = rb_ary_new( rb_ary_push(ary, names if (h->h_aliases != NULL) { for (pch = h->h_aliases; *pch; pch++) { rb_ary_push(names, rb_str_new2(*pch) } } rb_ary_push(ary, INT2NUM(h->h_addrtype) #ifdef h_addr for (pch = h->h_addr_list; *pch; pch++) { rb_ary_push(ary, rb_str_new(*pch, h->h_length) } #else rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length) #endif return ary; }

gethostbyname(hostname) → official_hostname, alias_hostnames, address_family, *address_list()

获取主机的主机信息。

p Socket.gethostbyname("hal") #=> ["localhost", ["hal"], 2, "\x7F\x00\x00\x01"]

static VALUE sock_s_gethostbyname(VALUE obj, VALUE host) { struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME return rsock_make_hostent(host, res, sock_sockaddr }

gethostname → hostname Show source

返回主机名。

p Socket.gethostname #=> "hal"

请注意,不能保证能够使用gethostbyname,getaddrinfo等转换为IP地址。如果您需要本地IP地址,请使用:: ip_address_list。

static VALUE sock_gethostname(VALUE obj) { #if defined(NI_MAXHOST) # define RUBY_MAX_HOST_NAME_LEN NI_MAXHOST #elif defined(HOST_NAME_MAX) # define RUBY_MAX_HOST_NAME_LEN HOST_NAME_MAX #else # define RUBY_MAX_HOST_NAME_LEN 1024 #endif long len = RUBY_MAX_HOST_NAME_LEN; VALUE name; name = rb_str_new(0, len while (gethostname(RSTRING_PTR(name), len) < 0) { int e = errno; switch (e) { case ENAMETOOLONG: #ifdef __linux__ case EINVAL: /* glibc before version 2.1 uses EINVAL instead of ENAMETOOLONG */ #endif break; default: rb_syserr_fail(e, "gethostname(3)" } rb_str_modify_expand(name, len len += len; } rb_str_resize(name, strlen(RSTRING_PTR(name)) return name; }

getifaddrs → ifaddr1, ...()

返回一组接口地址。数组的一个元素是Socket :: Ifaddr的一个实例。

该方法可用于查找启用多播的接口:

pp Socket.getifaddrs.reject {|ifaddr| !ifaddr.addr.ip? || (ifaddr.flags & Socket::IFF_MULTICAST == 0) }.map {|ifaddr| [ifaddr.name, ifaddr.ifindex, ifaddr.addr] } #=> [["eth0", 2, #<Addrinfo: 221.186.184.67>], # ["eth0", 2, #<Addrinfo: fe80::216:3eff:fe95:88bb%eth0>]]

GNU / Linux上的示例结果:

pp Socket.getifaddrs #=> [#<Socket::Ifaddr lo UP,LOOPBACK,RUNNING,0x10000 PACKET[protocol=0 lo hatype=772 HOST hwaddr=00:00:00:00:00:00]>, # #<Socket::Ifaddr eth0 UP,BROADCAST,RUNNING,MULTICAST,0x10000 PACKET[protocol=0 eth0 hatype=1 HOST hwaddr=00:16:3e:95:88:bb] broadcast=PACKET[protocol=0 eth0 hatype=1 HOST hwaddr=ff:ff:ff:ff:ff:ff]>, # #<Socket::Ifaddr sit0 NOARP PACKET[protocol=0 sit0 hatype=776 HOST hwaddr=00:00:00:00]>, # #<Socket::Ifaddr lo UP,LOOPBACK,RUNNING,0x10000 127.0.0.1 netmask=255.0.0.0>, # #<Socket::Ifaddr eth0 UP,BROADCAST,RUNNING,MULTICAST,0x10000 221.186.184.67 netmask=255.255.255.240 broadcast=221.186.184.79>, # #<Socket::Ifaddr lo UP,LOOPBACK,RUNNING,0x10000 ::1 netmask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, # #<Socket::Ifaddr eth0 UP,BROADCAST,RUNNING,MULTICAST,0x10000 fe80::216:3eff:fe95:88bb%eth0 netmask=ffff:ffff:ffff:ffff::>]

FreeBSD上的示例结果:

pp Socket.getifaddrs #=> [#<Socket::Ifaddr usbus0 UP,0x10000 LINK[usbus0]>, # #<Socket::Ifaddr re0 UP,BROADCAST,RUNNING,MULTICAST,0x800 LINK[re0 3a:d0:40:9a:fe:e8]>, # #<Socket::Ifaddr re0 UP,BROADCAST,RUNNING,MULTICAST,0x800 10.250.10.18 netmask=255.255.255.? (7 bytes for 16 bytes sockaddr_in) broadcast=10.250.10.255>, # #<Socket::Ifaddr re0 UP,BROADCAST,RUNNING,MULTICAST,0x800 fe80:2::38d0:40ff:fe9a:fee8 netmask=ffff:ffff:ffff:ffff::>, # #<Socket::Ifaddr re0 UP,BROADCAST,RUNNING,MULTICAST,0x800 2001:2e8:408:10::12 netmask=UNSPEC>, # #<Socket::Ifaddr plip0 POINTOPOINT,MULTICAST,0x800 LINK[plip0]>, # #<Socket::Ifaddr lo0 UP,LOOPBACK,RUNNING,MULTICAST LINK[lo0]>, # #<Socket::Ifaddr lo0 UP,LOOPBACK,RUNNING,MULTICAST ::1 netmask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, # #<Socket::Ifaddr lo0 UP,LOOPBACK,RUNNING,MULTICAST fe80:4::1 netmask=ffff:ffff:ffff:ffff::>, # #<Socket::Ifaddr lo0 UP,LOOPBACK,RUNNING,MULTICAST 127.0.0.1 netmask=255.?.?.? (5 bytes for 16 bytes sockaddr_in)>]

static VALUE socket_s_getifaddrs(VALUE self) { return rsock_getifaddrs( }

getnameinfo(sockaddr , flags) → hostname, servicename()

获取sockaddr的名称信息。

sockaddr应该是以下之一。

  • 打包的sockaddr字符串,例如:: sockaddr_in(80,“127.0.0.1”)

  • 3-elements array such as “AF_INET”, 80, “127.0.0.1”

  • 4个元素的数组,例如[“AF_INET”,80,忽略,“127.0.0.1”]

  • #accept

# File ext/socket/lib/socket.rb, line 577 def accept_nonblock(exception: true) __accept_nonblock(exception) end

bind(local_sockaddr)→0

绑定到给定的本地地址。

参数

  • local_sockaddr-struct包含在字符串或Addrinfo对象中的sockaddr

  • Errno :: EACCES - 指定的sockaddr受保护,当前用户无权绑定它

  • Errno :: EADDRINUSE - 指定的sockaddr已被使用

  • Errno :: EADDRNOTAVAIL - 指定的sockaddr不可从本地机器获得

  • Errno :: EAFNOSUPPORT - 指定的sockaddr不是调用系列的有效地址socket

  • Errno :: EBADF - 指定的sockaddr不是有效的文件描述符

  • Errno :: EFAULT - 不能访问sockaddr参数

  • Errno :: EINVAL - socket已经绑定到一个地址,协议不支持绑定到新的sockaddrsocket已关闭。

  • Errno :: EINVAL - 地址长度不是地址系列的有效长度

  • Errno :: ENAMETOOLONG - 解析的路径名长度超过了PATH_MAX

  • Errno :: ENOBUFS - 没有可用的缓冲空间

  • Errno :: ENOSR - 没有足够的STREAMS资源可用于完成操作

  • Errno :: ENOTSOCK - socket不涉及套接字

  • Errno :: EOPNOTSUPP - socket不支持绑定到地址的套接字类型

如果调用的地址族socket是Socket :: AF_UNIX,那么在基于unix的系统上,如果绑定调用失败,则可能会引发以下异常:

  • 错误号:: EACCES -搜索权限被拒绝的前缀路径的组件或写访问socket被拒绝

  • Errno :: EDESTADDRREQ - sockaddr参数是一个空指针

  • Errno :: EISDIR - 与Errno :: EDESTADDRREQ相同

  • Errno :: EIO - 发生I / O错误

  • Errno :: ELOOP - 在翻译sockaddr中的路径名时遇到太多符号链接

  • Errno :: ENAMETOOLLONG - 路径名的一个组件超过了NAME_MAX个字符,或者整个路径名超过了PATH_MAX个字符

  • Errno :: ENOENT - 路径名的一个组件不会命名现有文件,或路径名是空字符串

  • Errno :: ENOTDIR - sockaddr中路径名的路径前缀的组件不是目录

  • Errno :: EROFS - 名称将驻留在只读文件系统上Windows例外在Windows系统中,如果调用绑定失败,则可能会引发以下系统异常:

  • Errno :: ENETDOWN-网络已关闭

  • Errno :: EACCES - 尝试将数据报套接字连接到广播地址失败

  • Errno :: EADDRINUSE - 套接字的本地地址已被使用

  • Errno :: EADDRNOTAVAIL - 指定的地址不是此计算机的有效地址

  • Errno :: EFAULT - 套接字的内部地址或地址长度参数太小或者不是用户空间的有效部分

  • Errno :: EINVAL - socket已经绑定到一个地址

  • Errno :: ENOBUFS - 没有可用的缓冲空间

  • Errno :: ENOTSOCK - 该socket参数并不涉及socket

  • 绑定基于Unix系统的手册页

  • 连接函数在微软的Winsock函数参考中

  • remote_sockaddr- struct包含在字符串或Addrinfo对象中的sockaddr

例:

# Pull down Google's web page require 'socket' include Socket::Constants socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' ) socket.connect( sockaddr ) socket.write( "GET / HTTP/1.0\r\n\r\n" ) results = socket.read

基于Unix的例外

在基于Unix系统的系统上,如果连接呼叫失败,可能会引发以下系统异常:

  • 错误号:: EACCES -搜索权限被拒绝的前缀路径的组件或写访问socket被拒绝

  • Errno :: EADDRINUSE - sockaddr已在使用中

  • Errno :: EADDRNOTAVAIL - 指定的sockaddr不可从本地机器获得

  • Errno :: EAFNOSUPPORT - 指定的sockaddr不是指定地址族的有效地址socket

  • Errno :: EALREADY - 指定套接字的连接已在进行中

  • Errno :: EBADF - 这socket不是有效的文件描述符

  • Errno :: ECONNREFUSED - 目标sockaddr没有监听连接拒绝连接请求

  • Errno :: ECONNRESET - 远程主机重置连接请求

  • Errno :: EFAULT - 无法访问sockaddr

  • Errno :: EHOSTUNREACH - 目标主机无法访问(可能是因为主机关闭或远程路由器无法访问它)

  • Errno :: EINPROGRESS - O_NONBLOCK被设置为socket并且连接不能立即建立; 连接将异步建立

  • Errno :: EINTR--试图建立连接被传递被捕获的信号中断; 连接将异步建立

  • Errno :: EISCONN - 指定socket的已连接

  • Errno :: EINVAL - 用于sockaddr的地址长度不是地址族的有效长度,或者sockaddr中存在无效的族

  • Errno :: ENAMETOOLONG - 解析的路径名长度超过了PATH_MAX

  • Errno :: ENETDOWN - 用于到达目的地的本地接口已关闭

  • Errno :: ENETUNREACH - 没有路由到网络

  • Errno :: ENOBUFS - 没有可用的缓冲空间

  • Errno :: ENOSR - 没有足够的STREAMS资源可用于完成操作

  • Errno :: ENOTSOCK - socket参数没有引用套接字

  • Errno :: EOPNOTSUPP - 呼叫socket正在收听,无法连接

  • Errno :: EPROTOTYPE - sockaddr具有与绑定到指定对等地址的套接字不同的类型

  • Errno :: ETIMEDOUT - 在建立连接之前尝试连接超时。如果调用的地址族socket为AF_UNIX,则在基于unix的系统中,如果调用连接失败,可能会引发以下异常:

  • Errno :: EIO - 从文件系统读取或写入文件系统时发生I / O错误

  • Errno :: ELOOP - 在翻译sockaddr中的路径名时遇到太多符号链接

  • Errno :: ENAMETOOLLONG - 路径名的一个组件超过了NAME_MAX个字符,或者整个路径名超过了PATH_MAX个字符

  • Errno :: ENOENT - 路径名的一个组件不会命名现有文件,或路径名是空字符串

  • Errno :: ENOTDIR - sockaddr中路径名的路径前缀的组件不是目录

Windows例外

在Windows系统上,如果连接呼叫失败,可能会引发以下系统异常:

  • Errno :: ENETDOWN - 网络已关闭

  • Errno :: EADDRINUSE - 套接字的本地地址已被使用

  • Errno :: EINTR - 套接字被取消

  • Errno :: EINPROGRESS - 阻塞套接字正在进行中,或者服务提供者仍在处理回调函数。或者正在进行非阻塞连接呼叫socket

  • Errno::EALREADY - see Errno::EINVAL

  • Errno :: EADDRNOTAVAIL - 远程地址不是有效地址,例如ADDR_ANY TODO检查ADDRANY TO INADDR_ANY

  • Errno :: EAFNOSUPPORT - 指定系列中的地址不能与此一起使用 socket

  • Errno :: ECONNREFUSED - 目标sockaddr没有监听连接拒绝连接请求

  • Errno :: EFAULT - 套接字的内部地址或地址长度参数太小或者不是用户空间地址的有效部分

  • Errno :: EINVAL - 这socket是一个监听套接字

  • Errno :: EISCONN - socket已连接

  • Errno :: ENETUNREACH - 此时无法从此主机访问网络

  • Errno :: EHOSTUNREACH - 没有路由到网络

  • Errno :: ENOBUFS - 没有可用的缓冲空间

  • Errno :: ENOTSOCK - socket参数没有引用套接字

  • Errno :: ETIMEDOUT - 在建立连接之前尝试连接超时。

  • Errno :: EWOULDBLOCK - 套接字被标记为非阻塞,并且连接无法立即完成

  • Errno :: EACCES - 尝试将数据报套接字连接到广播地址失败

看到

  • 在基于Unix的系统上连接手册页

  • 连接函数在微软的Winsock函数参考中

static VALUE sock_connect(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; int fd, n; SockAddrStringValueWithAddrinfo(addr, rai addr = rb_str_new4(addr GetOpenFile(sock, fptr fd = fptr->fd; n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0 if (n < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai } return INT2FIX(n }

connect_nonblock(remote_sockaddr,options)→0显示源文件

remote_sockaddr为基础文件描述符设置O_NONBLOCK之后,请求在给定的连接上进行连接。如果成功则返回0,否则引发异常。

参数

# +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object

例:

# Pull down Google's web page require 'socket' include Socket::Constants socket = Socket.new(AF_INET, SOCK_STREAM, 0) sockaddr = Socket.sockaddr_in(80, 'www.google.com') begin # emulate blocking connect socket.connect_nonblock(sockaddr) rescue IO::WaitWritable IO.select(nil, [socket]) # wait 3-way handshake completion begin socket.connect_nonblock(sockaddr) # check connection failure rescue Errno::EISCONN end end socket.write("GET / HTTP/1.0\r\n\r\n") results = socket.read

如果对connect_nonblock的调用失败,请参阅#connect以了解可能会抛出的异常。

#connect_nonblock可能引发与连接(2)失败相对应的任何错误,包括Errno :: EINPROGRESS。

如果异常是Errno :: EINPROGRESS,则由IO :: WaitWritable进行扩展。所以IO :: WaitWritable可以用来解救重试connect_nonblock的异常。

通过指定关键字参数异常false,你可以指出#connect_nonblock应该不会引发IO :: WaitWritable异常,但返回的符号:wait_writable来代替。

看到

# Socket#connect

# File ext/socket/lib/socket.rb, line 1196 def connect_nonblock(addr, exception: true) __connect_nonblock(addr, exception) end

ipv6only!()显示源文件

如果IPV6_V6ONLY可用,请启用套接字选项IPV6_V6ONLY。

# File ext/socket/lib/socket.rb, line 448 def ipv6only! if defined? Socket::IPV6_V6ONLY self.setsockopt(:IPV6, :V6ONLY, 1) end end

listen(int)→0

监听连接,使用指定int的积压。只有在类型为SOCK_STREAM或SOCK_SEQPACKET 的情况下才会调用侦听socket

参数

  • backlog - 等待连接队列的最大长度。

  • Errno :: EBADF - 套接字参数不是有效的文件描述符

  • Errno :: EDESTADDRREQ - 套接字未绑定到本地地址,且协议不支持侦听未绑定的套接字

  • Errno :: EINVAL - 套接字已经连接

  • Errno :: ENOTSOCK - 套接字参数不引用套接字

  • Errno :: EOPNOTSUPP - 套接字协议不支持listen

  • Errno :: EACCES - 调用过程没有适当的权限

  • Errno :: EINVAL - 套接字已关闭

  • Errno :: ENOBUFS - 系统中可用资源不足以完成callWindows异常在Windows系统中,如果侦听呼叫失败,则可能会引发以下系统异常:

  • Errno :: ENETDOWN - 网络已关闭

  • Errno :: EADDRINUSE - 套接字的本地地址已被使用。这通常发生在绑定执行过程中,但如果绑定调用是部分通配符地址(涉及ADDR_ANY),并且在调用收听时需要提交特定地址

  • Errno :: EINPROGRESS - 正在进行Windows套接字1.1调用,或者服务提供者仍在处理回调函数

  • Errno :: EINVAL - socket尚未绑定调用绑定

  • Errno :: EISCONN - socket已连接

  • Errno :: EMFILE - 不再有套接字描述符可用

  • Errno :: ENOBUFS - 没有可用的缓冲空间

  • Errno :: ENOTSOC - socket不是套接字

  • Errno :: EOPNOTSUPP - 引用socket不是支持listen方法的类型

看到

  • 在基于Unix的系统上收听手册页面

  • 在Microsoft的Winsock函数参考中监听函数

VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; backlog = NUM2INT(log GetOpenFile(sock, fptr if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)" return INT2FIX(0 }

recvfrom(maxlen) → mesg, sender_addrinfo()

recvfrom(maxlen, flags) → mesg, sender_addrinfo

最多可接收来自maxlen字节socket标志是零个或多个MSG_选项。结果的第一个元素mesg是收到的数据。第二个元素sender_addrinfo包含发件人的特定于协议的地址信息。

参数

  • maxlen - 从套接字接收的最大字节数

  • flags- 零个或多个MSG_选项

# In one file, start this first require 'socket' include Socket::Constants socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) socket.bind( sockaddr ) socket.listen( 5 ) client, client_addrinfo = socket.accept data = client.recvfrom( 20 )[0].chomp puts "I only received 20 bytes '#{data}'" sleep 1 socket.close # In another file, start this second require 'socket' include Socket::Constants socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) socket.connect( sockaddr ) socket.puts "Watch this get cut short!" socket.close

基于Unix的例外

在基于unix的系统上,如果对recvfrom的调用失败,则可能会引发以下系统异常:

  • Errno :: EAGAIN - socket文件描述符被标记为O_NONBLOCK,并且没有数据等待接收; 或者MSG_OOB被设置,并且没有带外数据可用,并且socket文件描述符被标记为O_NONBLOCK,或者socket不支持阻塞来等待带外数据

  • Errno :: EWOULDBLOCK - 参见Errno :: EAGAIN

  • Errno :: EBADF - 这socket不是有效的文件描述符

  • Errno :: ECONNRESET - 一个连接被同伴强行关闭

  • Errno :: EFAULT - 无法访问或写入套接字的内部缓冲区,地址或地址长度

  • Errno :: EINTR - 在任何数据可用之前信号中断recvfrom

  • Errno :: EINVAL - MSG_OOB标志被设置,并且没有带外数据可用

  • Errno :: EIO - 从文件系统读取或写入文件系统时发生I / O错误

  • Errno :: ENOBUFS - 系统中没有足够的资源来执行操作

  • Errno :: ENOMEM - 内存不足以满足请求

  • Errno :: ENOSR - 没有足够的STREAMS资源可用于完成操作

  • Errno :: ENOTCONN - 在未连接的连接模式套接字上尝试接收数据

  • Errno :: ENOTSOCK - socket不涉及套接字

  • Errno :: EOPNOTSUPP - 此套接字类型不支持指定的标志

  • Errno :: ETIMEDOUT - 在连接建立期间连接超时或由于活动连接上的传输超时Windows异常在Windows系统中,如果对recvfrom的调用失败,可能会引发以下系统异常:

  • Errno :: ENETDOWN - 网络已关闭

  • Errno :: EFAULT - 内部缓冲区和from参数socket不是用户地址空间的一部分,或者内部的fromlen参数太小而不能容纳对等地址

  • Errno :: EINTR - (阻塞)调用被内部调用WinSock函数WSACancelBlockingCall取消

  • Errno :: EINPROGRESS - 阻塞的Windows套接字1.1调用正在进行中,或者服务提供者仍在处理回调函数

  • Errno :: EINVAL - socket尚未绑定调用绑定或指定了未知标志,或者已为启用了SO_OOBINLINE的套接字指定了MSG_OOB,或者(对于仅字节流式套接字),on上的内部len参数socket为零或否定的

  • Errno :: EISCONN - socket已连接。对于面向连接或无连接的套接字,连接的套接字不允许对recvfrom的调用。

  • Errno :: ENETRESET - 由于保持活动状态活动在操作正在进行时检测到故障,连接已中断。

  • Errno :: EOPNOTSUPP - MSG_OOB已指定,但socket不是流式,如类型SOCK_STREAM。OOB数据在与之相关的通信域中不受支持socket,或者socket是单向的,并且仅支持发送操作

  • Errno :: ESHUTDOWN - socket已关闭。在调用shutdown之后,无法在套接字上调用recvfrom

  • Errno :: EWOULDBLOCK - socket被标记为非阻塞,并且会阻止对recvfrom的调用。

  • Errno :: EMSGSIZE - 消息太大而无法放入指定的缓冲区并被截断。

  • Errno :: ETIMEDOUT - 由于网络故障或另一端的系统不通知而连接断开

  • Errno :: ECONNRESET - 虚拟电路由远程端执行硬性或异常关闭而重置。应用程序应关闭套接字; 它不再可用。在UDP数据报套接字上,此错误指示先前的发送操作导致ICMP端口不可到达消息。

static VALUE sock_recvfrom(int argc, VALUE *argv, VALUE sock) { return rsock_s_recvfrom(sock, argc, argv, RECV_SOCKET }

recvfrom_nonblock(maxlen [,flags [,outbuf,opts]])→mesg,sender_addrinfo()

在为基础文件描述符设置了O_NONBLOCK后,接收使用recvfrom(2)时的maxlen字节socket标志是零个或多个MSG_选项。结果的第一个元素mesg是收到的数据。第二个元素sender_addrinfo包含发件人的特定于协议的地址信息。

当recvfrom(2)返回0时,#recvfrom_nonblock返回一个空字符串作为数据。含义取决于套接字:TCP上的EOF,UDP上的空数据包等。

参数

  • maxlen - 从套接字接收的最大字节数

  • flags- 零个或多个MSG_选项

  • outbuf - 目标字符串缓冲区

  • opts - 关键字散列,支持 exception: false

# In one file, start this first require 'socket' include Socket::Constants socket = Socket.new(AF_INET, SOCK_STREAM, 0) sockaddr = Socket.sockaddr_in(2200, 'localhost') socket.bind(sockaddr) socket.listen(5) client, client_addrinfo = socket.accept begin # emulate blocking recvfrom pair = client.recvfrom_nonblock(20) rescue IO::WaitReadable IO.select([client]) retry end data = pair[0].chomp puts "I only received 20 bytes '#{data}'" sleep 1 socket.close # In another file, start this second require 'socket' include Socket::Constants socket = Socket.new(AF_INET, SOCK_STREAM, 0) sockaddr = Socket.sockaddr_in(2200, 'localhost') socket.connect(sockaddr) socket.puts "Watch this get cut short!" socket.close

如果对recvfrom_nonblock的调用失败,请参阅#recvfrom了解可能会抛出的异常。

#recvfrom_nonblock可能引发对应于recvfrom(2)失败的错误,包括Errno :: EWOULDBLOCK。

如果该异常是Errno :: EWOULDBLOCK或Errno :: EAGAIN,则它由IO :: WaitReadable扩展。所以IO :: WaitReadable可以用来解救重试recvfrom_nonblock的异常。

通过指定关键字参数异常false,你可以指出#recvfrom_nonblock应该不会引发IO :: WaitReadable异常,但返回的符号:wait_readable来代替。

参见

  • #recvfrom#

  • #accept

static VALUE sock_sysaccept(VALUE sock) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr sock2 = rsock_s_accept(0,fptr->fd,&buf.addr,&len return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len) }