这里主要总结一下这段时间对Socket编程的总结
1.如何正确的接收数据和如何正确的关闭连接
接收数据要配合正确的关闭连接来使用,关闭连接的时候要先Shutdown本地套接字,这样远程套接字就会Receive一个0字节,远程主机可以根据这个判断是否关闭连接,如果我们直接Close一个套接字,那么远程套接字会直接抛出一个SocketException终止了一个已建立的连接,如果我们可以避免异常的产生尽量不使用异常。
clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close();
bufLen = s.Receive(buffer); if (bufLen == 0) { break; }
2.关闭了本地套接字,远程套接字也要及时关闭
针对一的问题,我们关闭了本地套接字,但是远程的套接字其实还是打开的状态,所以要及时关闭。break出循环程序的时候,我们在下面关闭连接,当然关闭的做法和一中的一样Shutdown->Close
3.如何避免一个封锁操作被对 WSACancelBlockingCall异常产生
先解释一下这个异常是怎么产生的,我们先主动Close掉本地套接字的时候,由于本地套接字也在Receive状态中,这是一个阻塞的状态,所以取消一次正在进行中的阻塞调用异常就会抛出来。这个异常本身并不会造成任何危害,因为你套接字已经关闭了,正处于阻塞状态的Recieve方法调用肯定失去了意义,运行时帮我们取消了这次调用,但是如果你觉得这个异常“别扭”,注意我这里加了引号,也是可以解决的,那就是我们在关闭一个套接字之前,先把Recieve的当前线程终止掉,线程终止了,Recieve调用自然不存在了,你再关闭连接的时候自然不会报了,但是这种做法也是那异常换异常,因为强制终止一个异常,套接字正处在一个阻塞状态,所以会产生一个ThreadAbort异常
clientThread.Abort(); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close();
所以接下来我来介绍一下到底该怎样正确的关闭连接,避免异常产生,以上所有异常的产生归根结底是Close的时机不对造成的,如果我们手动关闭一个套接字,正确的做法是只要Shutdown就可以了,后面不要紧跟着Close方法
当Shutdown的时候,这时候无论是本地套接字还是远程套接字都会空接退出循环,我们可以把Close放在循环体外面,分别关闭它们。