Skip to content

Socket

  • tcp和udp都通过socket进行创建,不同的是tcp是SOCK_STREAM,udp是SOCK_DGRAM。且除了tcp和udp的setsockopt共性可以设置的属性(SO_REUSEADDR, SO_REUSEPORT, O_NONBLOCK, SO_SNDBUF, SO_RCVBUF, SO_LINGER, FD_CLOEXEC)等,tcp还有TCP_NODELAY, SO_KEEPALIVE`等设置不延迟发送、保活等属性。
  • SO_PRIORITY:可用于设置socket的优先级,0~6, 6优先级最高
  • SO_LINGER:其中的l_onoff为非0时表示打开,此时l_linger表示延时的时间。用于close/shutdown后等到socket队列里的消息发送成功后/到达延时时间 后才返回,否则l_onoff为0时表示立即返回
  • IP_TOS:setsockopt(fd, IPPROTO_IP, IP_TOS, &opt_value, (socklen_t)(sizeof(opt_value)));,用于在网络上区分包的优先级

    1. IPTOS_LOWDELAY 用来为交互式通信最小化延迟时间
    2. IPTOS_THROUGHPUT 用来优化吞吐量
    3. IPTOS_RELIABILITY 用来作可靠性优化
    4. IPTOS_MINCOST 应该被用作"填充数据"

这些TOS值最多只能声明一个。缺省时优先发送IPTOS_LOWDELAY数据报。在voip中可以用于提高rtp数据包的优先级,通过对某个socket上设置ip_tos

网络监听

  • 如果监听地址是127.0.0.1:port,表示仅监听环回接口的数据,即本机发送给本机port端口的数据,其他主机发送过来的数据无法接收到。
  • 如果监听地址是0.0.0.0:port,表示监听所有网络接口的数据,包括环回接口和其他网络接口,所有本机和其他主机发送的数据都可以接收到。
  • 如果监听地址是本机ip:port,表示仅监听本机ip对应的网络接口。仅接收目的地址是本机ip的数据。(对本机发送给本机这种情况,如果目的主机地址是127.0.0.1则,收不到,仅当目的主机地址是本机ip时能够收到)。

recv报错解决

返回值

recv返回值小于0且,errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN时认为连接是正常的,可以继续接收。

EAGAIN||EINVAL

返回值为EINVAL,表示无效参数,提供的参数非法。有时也与socket当前状态相关,如一个socket并没有进入listening状态,此时调用accept就会产生EINVAL错误。

recv可能返回值等于0,但errno是EAGAIN即Resource temporarily unavailable(也可能返回EINVAL,无效参数),这应该是recv接收不到数据导致 超时了,以为socket连接断开了。(比如需要协议交互才能进行下去的情况:

wfd投屏里source端发送的m2回复REPLY后紧跟着一个GET_PARAMETER,然后只有sink端 回复了这个GET_PARAMETER,source才会发送消息过去,如果m2的response与m3的request粘包了,就会导致数据一下子被读完,如果sink端没做粘包处理 就会导致只解析了前面的Response,而后面的获取参数的request被忽略掉。

connect报错解决

EINPROGRESS

意思是Operation now in progress,这是因为连接流程可能是

Bash
1
2
3
1. 建立socket
2. setsockopt设置非阻塞
3. connect连接

由于connect接口返回EINPROGRESS可能是The socket is nonblocking and the connection cannot be completed immediately。因此将 设置非阻塞放在连接之后可以解决该问题,修复后的流程

Bash
1
2
3
1. 建立socket
2. connect连接
3. setsockopt设置非阻塞

返回值等于零,一般是在等接协议接收数据时网络中断。