Python中Socket的Close方法假关闭Socket连接的问题
来源:互联网 发布:淘宝棒球服外套女 编辑:程序博客网 时间:2024/05/23 14:45
最近用python的Socket写了一个传输通讯测试工具,但是发现在Server端调用close方法后,如果循环没有break的话,此连接还可以继续用来发送和接收数据。所以,我就觉得很是奇怪,难道close方法关闭的连接没有起作用吗?经过试验后,确实如此,以下是我的事例代码,
Server端代码:
from socket import *import threading,os,timeclass Server(): def __init__(self,host='127.0.0.1',port=9990): try: addr=(host,port) self.tcpSerSock=socket(AF_INET,SOCK_STREAM) self.tcpSerSock.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) self.tcpSerSock.bind(addr) self.tcpSerSock.listen(5) except Exception,e : print 'ip or port error :',str(e) self.tcpSerSock.close() def main(self): while 1 : try : print 'wait for connecting ...' tcpCliSock,addr = self.tcpSerSock.accept() addrStr = addr[0]+':'+str(addr[1]) print 'connect from',addrStr except KeyboardInterrupt: self.close=True tcpCliSock.close() self.tcpSerSock.close() print 'KeyboardInterrupt' break ct = ClientThread(tcpCliSock,addrStr) ct.start() class ClientThread(threading.Thread): def __init__(self,tcpClient,addr): super(ClientThread,self).__init__() self.tcpClient = tcpClient self.addr = addr self.timeout = 60 tcpClient.settimeout(self.timeout) self.cf = tcpClient.makefile('rw',0) def run(self): while 1: try: data = self.cf.readline().strip() if data: if data.find("set time")>=0: self.timeout = int(data.replace("set time ","")) self.tcpClient.settimeout(self.timeout) print self.addr,"client say:",data self.cf.write(str(self.addr)+" recevied ok!"+"\n") else: break except Exception,e: self.tcpClient.close() self.cf.write("time out !"+"\n") print self.addr,"send message error,",str(e)#此处将break注释掉# breakif __name__ == "__main__" : ser = Server() ser.main()
Client端代码:
from socket import *class Client(): def __init__(self): pass def main(self): tcpCliSock=socket(AF_INET,SOCK_STREAM) tcpCliSock.connect(('127.0.0.1',9990)) print 'connect server 9999 successfully !' cf = tcpCliSock.makefile('rw', 0) while 1: data=raw_input('>') try: if data: cf.write(data+"\n") data = cf.readline().strip() if data: print "server say:",data else: break else: break except Exception,e: print "send error,",str(e)if __name__ == "__main__": cl = Client() cl.main()
在代码中可以看出,如果timeout后,except肯定能够捕获到timeout异常,这样就会进入到except代码中,在上面我们故意将break注释掉,也就是不让其跳出循环,经过试验,可以得知,虽然在server端已经将连接close掉了,但是client端仍然可以顺利的接收到消息,而且,如果client端发送数据的间隔小于超时时间的话,此连接可以顺利的一直使用,这样,我们close貌似就一点儿效果都没有了,经过在百度搜索,一直米有找到解决办法,最后还是硬着头皮去看鸟语文档,下面是官方解释:
close()releases the resource associated with a connection but does not necessarily close the connection immediately. If you want to close the connection in a timely fashion, callshutdown() beforeclose().
大体意思是:close方法可以释放一个连接的资源,但是不是立即释放,如果想立即释放,那么请在close之前使用shutdown方法,可是shutdown方法是干什么的呢?
还得继续看鸟语,官方解释如下:
Shut down one or both halves of the connection. If how is SHUT_RD, further receives are disallowed. If how isSHUT_WR, further sends are disallowed. Ifhow isSHUT_RDWR, further sends and receives are disallowed. Depending on the platform, shutting down one half of the connection can also close the opposite half (e.g. on Mac OS X,shutdown(SHUT_WR) does not allow further reads on the other end of the connection).
大体意思是:shutdown方法是用来实现通信模式的,模式分三种,SHUT_RD 关闭接收消息通道,SHUT_WR 关闭发送消息通道,SHUT_RDWR 两个通道都关闭
也就是说,想要关闭一个连接,首先把通道全部关闭,然后在release连接,以上三个静态变量分别对应数字常量:0,1,2
所以,要实现我们的功能,只需要改变server端的代码,也就是
except Exception,e: self.tcpClient.close() self.cf.write("time out !"+"\n") print self.addr,"send message error,",str(e)#此处将break注释掉# break
改为:
except Exception,e:self.tcpClient.shutdown(2) self.tcpClient.close() self.cf.write("time out !"+"\n") print self.addr,"send message error,",str(e) break
这样的话,在close后,再调用 self.cf.write("time out !"+"\n"),应该就会报异常,此时client再使用此连接向server发数据,就会出错,然后就会顺理成章的走except的代码了。
当然,上面的代码,self.cf.write("time out !"+"\n")代码可以注释掉,我只是想用它来测试是否会出异常而已。
- Python中Socket的Close方法假关闭Socket连接的问题
- socket中close的问题
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭close和shutdown的区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭的close和shutdown区别
- socket关闭: close()和shutdown()的差异
- Linux socket关闭连接shutdown与close
- Linux socket关闭连接shutdown与close
- socket链接的关闭close和shutdown的区别
- 软件工程-软件重用
- 分支定界算法(Branch and Bound)
- C++ 重载 覆盖 隐藏
- linux exec函数家族
- 【android】5.listview组件的使用(重要!)
- Python中Socket的Close方法假关闭Socket连接的问题
- 【android,6】6.android在web下的应用-在客户端获取服务端的信息
- 【android,7】7.android在web下的应用-将客户端信息提交到服务端
- PHP里的opcode(2)
- POI 单元格格式化 - 数据格式化
- mysql数据导入导出
- Leetcode: Unique Binary Search Trees
- c语言冒泡排序
- Blocks Capturing Objects