Я недавно начал изучать Python (здесь долгое время работал Java-программистом) и в настоящее время пишу несколько простых серверных программ. Проблема заключается в том, что для, казалось бы, похожего фрагмента кода, аналог Java должным образом реагирует на сигнал SIGINT
( Ctrl + C ), а Python - нет. Это видно, когда для порождения сервера используется отдельный поток. Код выглядит следующим образом:
// Java code
package pkg;
import java.io.*;
import java.net.*;
public class ServerTest {
public static void main(final String[] args) throws Exception {
final Thread t = new Server();
t.start();
}
}
class Server extends Thread {
@Override
public void run() {
try {
final ServerSocket sock = new ServerSocket(12345);
while(true) {
final Socket clientSock = sock.accept();
clientSock.close();
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
и код Python:
# Python code
import threading, sys, socket, signal
def startserver():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 12345))
s.listen(1)
while True:
csock, caddr = s.accept()
csock.sendall('Get off my lawn kids...\n')
csock.close()
if __name__ == '__main__':
try:
t = threading.Thread(target=startserver)
t.start()
except:
sys.exit(1)
В обоих приведенных выше фрагментах кода я создаю простой сервер, который прослушивает TCP-запросы для данного порта. Когда в случае кода Java нажимается Ctrl + C , JVM завершает работу, тогда как в случае кода Python все, что я получаю, это ^C
в оболочке. Единственный способ остановить сервер - это нажать Ctrl + Z и затем вручную завершить процесс.
Так что я придумаю план; почему бы не иметь sighandler, который слушает Ctrl + Z и выходит из приложения? Круто, вот я и придумала:
import threading, sys, socket, signal
def startserver():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 12345))
s.listen(1)
while True:
csock, caddr = s.accept()
csock.sendall('Get off my lawn kids...\n')
csock.close()
def ctrlz_handler(*args, **kwargs):
sys.exit(1)
if __name__ == '__main__':
try:
signal.signal(signal.SIGTSTP, ctrlz_handler)
t = threading.Thread(target=startserver)
t.start()
except:
sys.exit(1)
Но теперь, похоже, я еще больше усугубил ситуацию! Теперь нажатие Ctrl + C на оболочке создает '^ C', а нажатие Ctrl + Z на оболочке - ^ Z ' ,
Итак, мой вопрос: почему это странное поведение? Вероятно, у меня будет несколько серверных процессов, запущенных как отдельные потоки в одном и том же процессе, поэтому любой простой способ убить сервер, когда процесс получит SIGINT
? Кстати, используя Python 2.6.4 в Ubuntu.
ТИА
Sasuke