网络编程最佳实践
socket描述符的引用机制
socket描述符引用机制,当父进程生成一个socket描述符然后fork一个子进程后,那么这个socket描述符的引用计数就+1了此后子进程close socket描述符只是减少引用计数并没有真正关闭描述符。如果希望真正关闭描述符需要使用shutdown函数
最佳实践:fork子进程后父进程立即close掉socket描述符
connect背后机制
客户端发起connect系统调用内核就会帮助我们建立三次握手中的最后一步,首先内核发送了一个syn的同步报文,服务器端响应这个syn报文,发送syn+ack报文给客户端,客户端接收到这个syn+ack报文后connect系统调用返回了,此时内核负责发送最后一个ack报文给服务器端
最佳实践:connect系统调用返回的错误有很多中,如果你需要知道关于connect连接失败的更多细节可以查看man手册针对每种错误进行处理,否则我推荐你直接perror打印错误字符串即可。
Ctlr+c/exit/return做了啥?
在客户端使用ctrl+c关闭客户端程序,或者是客户端调用了exit,或者是从main函数return背后做了啥?服务器端能否感知这些客户端退出,怎么去感这些客户端退出了? 这些都是网络编程中需要考虑的事情,其实在客户端Ctrl+c/exit/return中内核帮我们发送了一个FIN报文给服务器端了,服务器端对此报文进行了ACK响应,此时服务器处于CLOSE_WAIT状态,客户端处于FIN_WAIT_2状态,那么服务器端如何感知这一变化呢? 服务器端此时读取这个socket会返回0,返还0就表示这个socket的对端已经关闭了。那么服务器端就需要对其进行处理,最简单的莫过于close掉这个描述符,此时服务器端内核就会发送最后的那个FIN报文此时服务端处于LAST_ACK状态客户端接收到这个FIN报文后(此时由内核处理,应用程序已经终止了),会响应一个ACK报文然后自己变成了TIME_WAIT状态了。其实服务器端还有另外一种方法可以感知客户端已经关闭了下文将会介绍
最佳实践: 服务器端要针对read/recv一类的一系统调用的返回结果=0的情况作出处理,通过返回结果=0就可以知道客户端关闭了socket,此时服务器端就需要做相应的处理
多个子进程exit,该怎么办?
在处理多个并发连接的时候最简单的方法莫过于使用多进程的形式,一个进程处理一个连接,连接关闭后子进程就exit,那么子进程exit后,服务器端要做些啥呢,做过linux应用编程的应该都清楚子进程exit后是需要进行状态回收的,否则就会变成僵尸