Socket-Programing-FAQ

Posted Linux内核之旅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Socket-Programing-FAQ相关的知识,希望对你有一定的参考价值。

引言

Socket编程FAQ,由Vic Metcalfs创建,这是一系列关于socket编程相关的常问的问题。这些问题整理自comp.unix.programmer新闻组,我省略了其中一些比较基本的socket编程问题,有的问题的解答已经过时,因此我更新了部分回答。

How can I tell when a socket is closed on the end?

如果对端调用close或者exit退出,并且没有设置SO_LINGER选项,那么本端调用read会返回0,无论调用多少次都返回0第一次调用write后立即返回0,其实在内核层面会收到对端响应的RST报文,此时如果再次调用write会导致EPIPE错误,这个错误会引起SIGPIPE信号的产生,而这个信号的默认处理方式就是关闭程序。

注:更详细的分析详见

What’s with the second parameter in bind()?

How do I get the port number for a given service?

使用getservbyname,这个函数会返回一个指向struct servent结构体的指针,其中有一个字段s_port就是对应服务的端口号了(网络字节序)。 
下面是一个小的例子:


if bind() fails,what should I do with the socket descriptor?

如果你选择exit,那么系统会负责将socket描述符关闭,如果你不exit,那么可以手动去调用close来关闭套接字描述符

When should I use shutdown()?

shutdown一个典型的应用场景就是向对端发送结束请求(内核负责发送FIN报文),表明请求结束了。close也具备这样的功效,那么close和shutdown的区别和联系是什么呢,close本质上只是减少套接字描述符的引用计数,当引用计数变为0,才会导致TCP/IP的四次挥手过程。因此在多进程场景下,close并不会导致请求结束(也就是导致内核发生四次挥手过程),只是会较少套接字描述符的引用计数。而shutdown则不一样,shutdown会导致内核发起四次挥手过程中的前半部分,也就是半关闭。因为socket是一个类似于pipe的机制,不过socket是双向的,pipe是单向的。通过shutdown可以进行半关闭。也就是关闭了写端,但是仍然可以从socket中读取对端发送过来的数据。

Please explain the TIME_WAIT state

TCP/IP协议就是这样设计的,是不可避免的。主要有两个原因:

  • 可靠地实现TCP全双工连接的终止

TCP协议在关闭连接的四次握手过程中,最终的ACK是由主动关闭连接的一端(后面统称A端)发出的,如果这个ACK丢失,对方(后面统称B端)将重发出最终的FIN,因此A端必须维护状态信息(TIME_WAIT)允许它重发最终的ACK。如果A端不维持TIME_WAIT状态,而是处于CLOSED 状态,那么A端将响应RST分节,B端收到后将此分节解释成一个错误(在

以上是关于Socket-Programing-FAQ的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数