刚开始做项目时,要用到socket通信。那时为了弄清socket编程做了几个实验,主要是针对send和recv在几种特殊的情况下的返回值。

1.阻塞socket:

接收端和发送端正常频繁的接受和发送时,突然关闭接收端的socket(优雅的关闭,调用closesocket函数),此时的发送端的send函数返回-1,WSAGetLastError 的编码为10054.代表WSAECONNRESET:远端强制中止了虚电路。

 特殊情况(2):在接收端和发送端正常频繁的接受和发送时,突然关闭接收端的socket(粗鲁的关闭,直接关闭应用程序),此时的发送端的send函数返回-1,WSAGetLastError 的编码为10054.代表WSAECONNRESET:远端强制中止了虚电路。

特殊情况(3):在接收端和发送端正常频繁的接受和发送时,突然拔掉网线,这个时候由于拔了网线,双方都不知道连接已经断开,此时的send和recv都处于阻塞状态(连接认为没有断,但是数据发不出去了,导致send的缓冲区满了,而recv的缓冲区里没有数据准备好)。直到TCP底层机制(我怀疑是类似于心跳包的机制,一段时间收不到心跳包的恢复就认为连接已经断开)确认连接已经断开,这是send和recv都会返回-1,,WSAGetLastError 的编码为10054.代表WSAECONNRESET:远端强制中止了虚电路。

 特殊情况(4):在接收端和发送端正常频繁的接受和发送时,突然关闭发送端的socket(优雅的关闭,调用closesocket函数),此时的接收端的recv函数返回0,此时的recv函数是没有返回代表错误的SOCKET_ERROR.

特殊情况(5):在接收端和发送端正常频繁的接受和发送时,突然关闭发送端的socket(粗鲁的关闭,直接关闭应用程序),此时的接收端的recv函数返回-1,WSAGetLastError 的编码为10054.代表WSAECONNRESET:远端强制中止了虚电路。

特殊情况(6):在接收端和发送端正常频繁的接受和发送时,如果发送端一下子发送的数据太大,超出了缓冲区的大小,此时的发送端的send函数返回-1,WSAGetLastError 的编码为10055.代表WSAENOBUFS:没有缓冲区空间。由于系统缺少足够的缓冲区空间,请求的操作不能执行。(注意这里是一下子发送的数据很大,如果第一次发送成功了,以后即使多调用几次send使缓冲区满了的话,这样子只会阻塞send而不会返回-1和10055的错误代码)。可以把很大的数据量分多次发送,就可以避免特殊情况(6)的问题。

遗留问题(1):测试了很多情况,都没有得到send返回的字节数比传入的字节数少的情况。都是传入多少就发送多少,如果数据有点大,就阻塞知道数据全部发送完成。这个问题先留在这里,等以后看能不能碰到不同的情况。


这些都是做项目时碰到的一些特殊情况,最容易碰到的是优雅的关闭一方。但是有时候服务器和客户端的网络环境并不是很好,有时候会出现那样这样的状况而导致的粗鲁的关闭。这里提醒一下特别是(4)和(5)的区别。虽然这些都是基础,可是如果时间一长有时候自己也会弄混淆。以上结果都是在windows平台下测试得出的结果。要下班了,明天继续。