之前以为linux和windows下的socket都是符合posix标准的,在一个环境下能够正常使用在另外一个环境也没问题。但没想到两者还是有那么多不同。
1.最先发现的是在windows上需要调用那个WSAStartup进行初始化才能使用socket。
2.linux下关闭socket用close,而windows上用closesocket。
3.后来发现shutdown的参数名称不同,windows上用SD_BOTH,linux上是SHUT_RDWR。
4.在linux下如果不正常关闭socket会触发SIGPIPE异常,所以我使用signal( SIGPIPE, SIG_IGN );忽略之。
5.linux下可以使用read,write函数操作socket,也可以使用send,recv。windows上只能使用send,recv?(不考虑udp的sendfrom和recvfrom)
今天又发现一个很大的不同点了,造成了homeserver在短时间内生成了一个20GB的日志文件,用完了vps的硬盘空间。如果一个正在使用中的socket使用close来关闭之而不调用shutdown,则该socket还是处于连接中,只是在进程的文件描述符中移除了(right?)所以导致了使用那个socket的线程一直没有收到关闭信号,阻塞在socket的recv上无法被关闭。而在windows上调用closesocket就彻底地断开了连接了。
下面是网上提供的信息:
close—–关闭本进程的socket id,但链接还是开着的,用这个socket id的其它进程还能用这个链接,能读或写这个socket id
shutdown–则破坏了socket 链接,读的时候可能侦探到EOF结束符,写的时候可能会收到一个SIGPIPE信号,这个信号可能直到socket buffer被填充了才收到,shutdown还有一个关闭方式的参数,0 不能再读,1不能再写,2 读写都不能。
所以,以后关闭socket还是同时使用shutdown和close好。
补充一下(2010-06-13):
1、在linux下,shutdown会引起在recv和send中阻塞的线程返回-1。但是在windows下,除非closesocket,否则线程仍然阻塞。
2、windows的描述符是递增的,linux的描述符是重用的。也就是说你在linux下关闭了描述符0,然后打开一个文件,这个文件就是用了描述符0。