2013-03-03 2 views
0

Я играю с сокетами на питоне, только для того, чтобы узнать о них. Однако я очень раздражен со следующей проблемой:Python socket принимает в основном потоке, предотвращает выход

import socket 
soc = socket.socket(socket.AF_INET) 
soc.bind(('localhost',8000)) 
soc.listen(0) 
client = soc.accept() 

Хотя сокет ожидает подключения, нажав Ctrl-C не выйти из приложения.

Как я могу выйти из приложения?

Аналогичный вопрос был рассмотрен в thesetwo вопросов, но метод accept был вызван из отдельной нити и проблема заключалась в том, чтобы сделать Ctrl-C убить эту нить. Здесь метод accept вызывается из основного потока.

Редактировать: Я запускаю python 3.3.0 на Win7 64 бит.

+0

У меня никогда не было этой проблемы. Какая среда это? – cnicutar

+0

Отредактировано для добавления окружения – Joe

+0

Как вы его запускаете, из cmd? Если вы создаете скрипт, содержащий ** строго то, что вы разместили **, работает 'ctrl-c'? – cnicutar

ответ

3

я не мог найти способ, чтобы убить приложение с помощью ctrl-c или любым другим способом за убийство его через диспетчер задач, за исключением, поэтому я написал обходной путь:

import socket,os 
from threading import Thread 

class socketListener(Thread): 
    def run(self): 
     soc = socket.socket(socket.AF_INET) 
     soc.bind(('localhost',8000)) 
     soc.listen(0) 
     client = soc.accept() 

pid = os.getpid() 
sl = socketListener() 
sl.start() 
input('Socket is listening, press any key to abort...') 
os.kill(pid,9) 

Это запускает скрипт в отдельный нить, ожидая нажатия клавиши в основном потоке. Когда пользователь нажимает клавишу, все приложение уничтожается.

+0

Нет ли лучшего способа? – Nirri

3

Вы должны использовать CTRL + Перерыв. Это должно убить его.

+0

У меня нет «break» на моей клавиатуре ноутбука, но я только что обнаружил, что 'ctrl-F6' работает в режиме простоя python. Он перезапускает оболочку, которая убивает приложение в порядке, но имеет недостаток в сбросе всех переменных. С помощью 'ctrl-c' есть возможность проверять значения разных переменных и помогает при отладке. – Joe

+0

Исправление: перезагрузка оболочки делает ** не ** убить приложение. Он работает в фоновом режиме, и мне нужно убить его через диспетчер задач. – Joe

0

После того, как я столкнулся с той же проблемой, нашел немного обходной путь, это может быть не самым чистым способом, но по крайней мере это работает для меня:

import socket 
from select import select 

#create an INET, STREAMing socket 
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

#bind the socket to localhost 
serversocket.bind(('localhost', 8000)) 
While 1: 
    serversocket.listen(5) 
    ready, _, _ = select([serversocket], [], [], 1) #Timeout set to 1 seconds 
    if ready: 
     (clientsocket, address) = serversocket.accept() 
     #Do something with client 
    else: 
     #Do nothing, just loop again 

С помощью select вы будете ждать изменения на сокете fd до конца таймаута. Как я уже сказал, это может быть не самый чистый путь, но Ctrl-c будет улавливаться в конце таймаута.

Предупреждение о переносимости: В Unix select работает как с сокетами, так и с файлами. В Windows select работает только с сокетами.