免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10344 | 回复: 10
打印 上一主题 下一主题

如何关闭处于socket监听状态的线程? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-05-27 15:14 |只看该作者 |倒序浏览
本帖最后由 Shaquile 于 2013-05-27 15:15 编辑

下面的程序只能等到下一个连接到来时,才能关闭线程。在怎么能当调用stop时,立刻关闭呢

  1. class ListenThread(threading.Thread):
  2.     def __init__(self, server):
  3.         threading.Thread.__init__(self)
  4.         self.server = server
  5.         self.event = threading.Event()
  6.         self.event.clear()
  7.         
  8.     def run(self):
  9.         while (not self.event.is_set()):
  10.             try:
  11.                 client, addr = self.server.accept()

  12.                 data = client.recv(1024)
  13.                 client.send('I GOT: %s' % data)

  14.                 client.close()
  15.             except:
  16.                 break

  17.     def stop(self):
  18.         self.event.set()                                            

复制代码

论坛徽章:
1
15-16赛季CBA联赛之新疆
日期:2017-03-09 12:33:45
2 [报告]
发表于 2013-05-27 16:05 |只看该作者
本帖最后由 jeppeter 于 2013-05-27 16:17 编辑

回复 1# Shaquile


    这个问题我遇到过,我的解决办法是用select,而不是直接accept,因为有一个时间设定(这个我一般设置为1 second),如果得到exception,就退出了,这个可以基本满足你的需求。
   下面给一个代码
  1. def SelAccept(sock):
  2.         try:
  3.                 while True:
  4.                         rlist = [sock]
  5.                         wlist = []
  6.                         xlist = []
  7.                         ret = select.select(rlist,wlist,xlist,1)
  8.                         if len(ret) > 0 and len(ret[0]) > 0:
  9.                                 rsock ,addr= sock.accept()
  10.                                 return rsock
  11.         except :
  12.                 return None
复制代码

论坛徽章:
0
3 [报告]
发表于 2013-05-27 16:54 |只看该作者
多谢,继续研究中。。。

论坛徽章:
0
4 [报告]
发表于 2013-05-27 19:35 |只看该作者
回复 1# Shaquile
stop里直接把连接close掉不完了

   

论坛徽章:
0
5 [报告]
发表于 2013-05-28 09:35 |只看该作者
不行呀。我也这么做过,虽然close没有报错,但是socket还是在accept的阻塞状态

论坛徽章:
0
6 [报告]
发表于 2013-05-29 10:18 |只看该作者
Shaquile 发表于 2013-05-28 09:35
不行呀。我也这么做过,虽然close没有报错,但是socket还是在accept的阻塞状态

会这样吗?

论坛徽章:
0
7 [报告]
发表于 2013-05-29 11:01 |只看该作者
回复 6# 106033177

要是不这样,我也就不在这提问了

你可以试试


   

论坛徽章:
0
8 [报告]
发表于 2013-05-29 11:38 |只看该作者
本帖最后由 106033177 于 2013-05-29 12:38 编辑

回复 7# Shaquile
我试的不会

  1. class ListenThread(threading.Thread):
  2.     def __init__(self, server):
  3.         ...
  4.         self.client = None
  5.         
  6.     def run(self):
  7.         while True:
  8.             try:               
  9.                 self.client,  = self.server.accept()               
  10.                 data = self.client.recv(1024)
  11.                 ....

  12.     def stop(self):
  13.         self.server.close()
  14.         if self.client:
  15.             self.client.close()
  16.               
复制代码

论坛徽章:
0
9 [报告]
发表于 2013-05-29 13:42 |只看该作者
这是我得全部代码,照着你的盖了,还是不行
点击"stop tcp server"后,依然可以接受一次请求
  1. #coding=utf-8
  2. from Tkinter import *
  3. import threading
  4. import socket
  5. import time


  6. class ListenThread(threading.Thread):
  7.     def __init__(self, listBox, server, port):
  8.         threading.Thread.__init__(self)
  9.         self.listBox = listBox
  10.         self.server = server
  11.         self.port = port
  12.         self.client = None
  13.         
  14.     def run(self):
  15.         while True:
  16.             try:
  17.                 self.client, addr = self.server.accept()
  18.                 self.listBox.insert(0, now() + 'Incomming connection: %s:%d\n'%addr)
  19.                
  20.                 data = self.client.recv(1024)
  21.                 self.listBox.insert(0, 'Receive data: %s\n' % data)
  22.                
  23.                 self.client.send('I GOT: %s' % data)
  24.                 self.client.close()
  25.                 self.listBox.insert(0, 'Close connection\n')
  26.             except Exception, msg:
  27.                 self.listBox.insert(0, 'Close connection error, code: ' + str(msg[0]))
  28.                 break
  29.         self.listBox.insert(0, '^^^^^^^^\n')
  30.     def stop(self):
  31.         self.server.close()
  32.         if self.client:
  33.             self.client.close()

  34.         
  35. class Control(threading.Thread):
  36.     def __init__(self, listBox, port):
  37.         threading.Thread.__init__(self)
  38.         self.listBox = listBox
  39.         self.port = port
  40.         self.event = threading.Event()
  41.         self.event.clear()
  42.         
  43.     def run(self):
  44.         server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   #Create Socket
  45.         server.bind(('', self.port))                                 #绑定本机1051端口
  46.         server.listen(5)                                             #开始监听
  47.         self.listBox.insert(0, 'Listening on ' + str(self.port) + '\n')
  48.         
  49.         self.lt = ListenThread(self.listBox, server, self.port)        
  50.         self.lt.setDaemon(True)
  51.         self.lt.start()                                              #执行监听
  52.         self.event.wait()                                            #进入等待

  53.         try:
  54.             self.lt.stop()
  55.             server.close()
  56.             self.listBox.insert(0, 'Close sever successfully\n')           
  57.         except Exception, msg:
  58.             self.listBox.insert(0, 'Close server error, code: ' + str(msg[0]))
  59.      
  60.     def stop(self):
  61.         self.event.set()                                             #结束控制进程
  62.         
  63.         
  64. class Window:
  65.     def __init__(self, root):
  66.         self.root = root
  67.         root.geometry("600x400")

  68.         self.labList = Label(root, text='Messages output:')
  69.         self.labList.place(x = 10, y = 10)

  70.         self.sbar = Scrollbar(root, orient = VERTICAL)
  71.         self.listBox = Listbox(root, width = 75, height = 10, yscrollcommand = self.sbar.set, selectmode=EXTENDED)

  72.         self.listBox.place(x = 10, y = 30)
  73.         self.sbar.place(x = 462, y = 30, height = 160)
  74.         self.sbar.configure(command = self.listBox.yview)
  75.         
  76.         self.butlisten = Button(root, text = 'Start TCP Server', command = self.Listen)
  77.         self.butlisten.place(x = 500, y = 60)
  78.         self.butclose = Button(root, text = 'Stop TCP Server', command = self.Close, state = 'disabled')
  79.         self.butclose.place(x = 500, y = 100)
  80.         self.butclear = Button(root, text = 'Clear messages', command = self.Clear)
  81.         self.butclear.place(x = 500, y = 140)
  82.         
  83.         self.labPort = Label(root, text='Listening port:')
  84.         self.labPort.place(x = 500, y = 10)
  85.         self.listenPort = IntVar()
  86.         self.listenPort.set(1288)
  87.         self.entPort = Entry(root, width = 10, textvariable = self.listenPort)
  88.         self.entPort.place(x = 500, y = 30)

  89.         
  90.         #self.edit = Text(root, width=60, height=20)
  91.         #self.edit.place(y = 100)

  92.     def Listen(self):
  93.         self.ctrl = Control(self.listBox, self.listenPort.get())
  94.         self.ctrl.setDaemon(True)
  95.         self.ctrl.start()                                           #执行控制线程
  96.         self.butlisten['state']='disabled'
  97.         self.butclose['state']='normal'
  98.         
  99.     def Close(self):
  100.         self.ctrl.stop()
  101.         self.butlisten['state']='normal'
  102.         self.butclose['state']='disabled'

  103.     def Clear(self):
  104.         self.listBox.delete(0, END)

  105. def now():
  106.     return time.strftime('%Y-%m-%d %H:%M:%S ',time.localtime(time.time()))
  107.         
  108. root = Tk()      
  109. window = Window(root)
  110. root.title('Socket server')
  111. root.mainloop()
复制代码

论坛徽章:
0
10 [报告]
发表于 2013-05-30 11:10 |只看该作者
Shaquile 发表于 2013-05-29 13:42
点击"stop tcp server"后,依然可以接受一次请求

我测试的不会这样。close之前shutdown一下试试.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP