|
|
|
|
 如何关闭线程中的Socket? - JerryKingKing [ 2005-07-14 16:50 | 1,826 byte(s)]
 Re: 如何关闭线程中的Socket? - passworld [ 2005-07-14 21:06 | 93 byte(s)]
 Re: 如何关闭线程中的Socket? - JerryKingKing [ 2005-07-15 10:11 | 266 byte(s)]
 Re: 如何关闭线程中的Socket? - passworld [ 2005-07-15 13:05 | 193 byte(s)]
 Re: 如何关闭线程中的Socket? - JerryKingKing [ 2005-07-15 13:30 | 84 byte(s)]
 Re: 如何关闭线程中的Socket? - passworld [ 2005-07-15 15:49 | 1,173 byte(s)]
 Re: 如何关闭线程中的Socket? - passworld [ 2005-07-15 16:04 | 162 byte(s)]
 Re: 如何关闭线程中的Socket? - JerryKingKing [ 2005-07-15 16:52 | 226 byte(s)]
 Re: 如何关闭线程中的Socket? - passworld [ 2005-07-15 19:45 | 700 byte(s)]
 Re: 如何关闭线程中的Socket? - passworld [ 2005-07-15 19:51 | 137 byte(s)]
 Re: 如何关闭线程中的Socket? - JerryKingKing [ 2005-07-18 10:31 | 65 byte(s)]
 Re: 如何关闭线程中的Socket? - ygzx [ 2006-10-09 13:44 | 38 byte(s)]
 Re: 如何关闭线程中的Socket? - JerryKingKing [ 2006-10-09 14:02 | 75 byte(s)]
 Re: 如何关闭线程中的Socket? - ygzx [ 2006-10-09 18:21 | 110 byte(s)]
 Re: 如何关闭线程中的Socket? - limodou [ 2005-07-15 13:54 | 149 byte(s)]
|
|
|
|
[Original]
[Print]
[Top]
|
使用socket模块开启一个Tcp server后开线程监听多个客户端的连接。要求服务器断开后,客户端自动断连。或者服务器断开后,可以立即再启动。可是我断开服务器socket后,客户端仍然联接,再启动服务器报端口占用,问各位高手,如何解决这个问题!还有就是在联接当中出现客户端断连等事件,如何知道?
代码如下:
import socket
#import threading
import thread
import sys
class TcpServer():
self.clients_num=0
self.clients=[]
def start(self):
self.socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind(('localhost', 8801))
self.socket.listen(5)
#threading.Thread(target=self.__accept, args=()).start()
thread.start_new_thread(self.__accept, ())
def __accept(self):
while self.socket:
try:
client_socket, address=self.socket.accept()
sys.stdout.write('recieve client connect from port '+repr(address[1])+'
')
self.clients_num+=1
。。。处理联接事件
self.clients.append(client)
except:
sys.stdout.write('error,create client failure
')
break
else:
for client in self.clients:
client.close()
thread.exit()
def stop(self):
for client in self.clients:
client.close()
socket=self.socket
self.socket=None
socket.close()
print 'stop listen'
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
设定 SO_REUSEADDR就可以了吗?后面两句是叫我查询Unix帮助吗?我没有用Unix,希望大侠直言相告!服务器端能够重用,但这样能解决关闭时客户端自动断连的问题吗?python文档提出socket.close()后,当数据全部flush到目的地后自动释放资源。是不是关不掉socket与这个原因有关?
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
不用Unix可你自己系统的编程手册 socket 部分。这个是 socket 编程的概念问题,也可以去 c/c++ 地方问。
我对让程序员看手册有特别偏好,因为我也是看手册看过来的。
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
passworld是建议你先了解关于端口重用的使用说明,然后你就可以去python的socket模块中查找有没有端口重用的设置函数。
不知道是不是这样。
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied in a
bind(2) call should allow reuse of local addresses. For PF_INET
sockets this means that a socket may bind, except when there is an
active listening socket bound to the address. When the listening
socket is bound to INADDR_ANY with a specific port then it is not
possible to bind to this port for any local address.
对方断线,如果没有互相交换数据,基本上这边是无法知道的,想象一下网络连线就知道,不论是tcp 还是 udp 并不是真的有什么管道建立起来,让一个连线专用的。
一般设一个超时限制 timeout ,当你要求数据时超过这个时间没反应,那就当对方断了。有数据交换,读写数据,也会返回错误,这时候也需要处理一下错误信息。读数据返回 0 ,也说明对方关了。
基本的 socket 概念跟任何程序语言没有关系,所以你看看网络编程的文件,范例,把这些弄懂后,再看怎么用 python 实现。python 手册里似乎也是建议去看 socket 本身的文件的,python 本身只提供使用接口。
|
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
有时候为了避免 timeout 出现,我们会周期性的传一个 keepalive 的数据,它的唯一目的就是告诉对方,虽然半天没发数据了,可我还没死,别把我的线关了。
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
|
首先谢谢两位,其实最主要的问题是小弟不明白,当不开线程操作时,单一服务器和客户端联接,当服务器端关闭时,客户端也能自动断连。但是一开线程,服务器就关不了,执行socket.close()后没有用。客户端还是能正常收发信息。这个问题如何解决?
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
不知道你的 Server 是怎么处理客户端的,每个客户端自己一个线程?
你的程序的明显问题是 for client in clients: client.close() 了两次,不知道为什么。
当然你的client也在 stop() 里 close 了,按理应该也完蛋了,但为什么客户端还能跟它联系,就不知道了。除非是系统缓冲的延时,否则就是你程序其他部分的逻辑错误。
可能因为 client.close() 在 self.socket=None 以前,在 client.close() 之后,又有新的client 产生。可能你的 while ... else ... 是针对这些新的 client 把,如果 while 里面没有产生新的线程,当然是处理完了然后在下一个测验里才跳到 else 段的,如果是有新线程,在 else 里 client.close() 之前新线程里继续工作也很正常。
|
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
而且由于thread 不同步,self.socket=None后,另外一个accpet线程还可能在 while 里等 accept,所以可能最少再接受一个连接,才能退出。
|
|
----
|
|
[Original]
[Print]
[Top]
|
|
|