WinSocket API —— 关闭closesocket后收发数据

WinSocket API —— 收发数据

然后是进行数据的传输,发送数据send:

建立连接后,服务器端的sockConn与客户端的sockClient就连接起来并且可以互相传输数据了,

int send(

SOCKET s,                    //连接socket,非监听socket

const char FAR *buf,     //要发送数据buf的地址

int len,                         //buf的长度

int flags                        //一般设置为0即可。

); 

接收数据使用recv函数

int recv(

SOCKET s,              

char FAR *buf,         //要发送数据buf的地址。

int len,                     //要接收数据buf的长度

int flags                    //一般设置为0即可。

);

  

    

使用closesocket函数关闭其中一端socket后,连接断开发生的各种情况:

关闭socketA之后:

对socketA使用recv函数接收数据,和使用send函数发送数据,都会马上返回SOCKET_ERROR。

之后另一端socketB:

1.socketB第一次send函数能成功返回发送数据的大小,并不会返回SOCKET_ERROR 。但socketA是无法接收到的。之后socketB使用send函数返回的都是SOCKET_ERROR 。

2.socketB使用recv函数接收数据。如果socketB之前没有使用send函数,那么recv函数的返回值总是0。直到socketB调用过send函数之后,recv函数的返回值总是SOCKET_ERROR。

因此要考虑A端和B端如何协调关闭连接。socketA想要关闭连接,除了closesocket(socketA)之外,还要另外通知socketB,不然socketB还在那里傻傻的接收/发送数据。

如果不想显式的通知,socketB就要自己判断,如果socketB多次调用send函数总是返回SOCKET_ERROR或者socketB多次调用recv函数总是返回0或SOCKET_ERROR,那就要意识到连接很可能已经断开了。

 

数据的流向是单向的:

例如说数据只从socketA流向socketB(类似文件传输就是这样),那么socketA只会调用send函数,而socketB只会调用recv函数,这时候如果其中一方要停止数据的传输,就会有两种情况出现:

1.如果socketA的计算机不想发送数据而closesocket(socketA),由于socketB从来不调用send函数,因此socketB的recv函数总是返回0,那么socketB的计算机就要意识到socketA很可能已经关闭了,让socketB的计算机closesocket(socketB)。

2.如果socketB的计算机不想接收数据而closesocket(socketA),这时socketA继续调用send函数发送数据,第一次send还是成功的,但从第二次send开始就总会返回SOCKET_ERROR,但是socketA的计算机无法判断send函数返回SOCKET_ERROR是由socketB关闭造成的还是Asocket关闭造成的(因为socketA关闭后socketA调用send函数也是返回SOCKET_ERROR),因此socketA的计算机无法判断socketA关闭了没有,简单的解决方法是如果socketB的计算机不想接收数据,先不要关闭socketB,而是发通知给Asocket的计算机告诉它我不想收数据了,socketA的计算机收到通知后关闭socketA,这样情形就回到上面情况1去了,而且也知道socketA调用send函数返回SOCKET_ERROR肯定是由于socketA关闭造成的而不是由socketB关闭造成的。

你可能感兴趣的:(WinSocket API —— 关闭closesocket后收发数据)