No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

netipy.py 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #!/usr/bin/python3
  2. #-*- coding: utf-8 -*-
  3. #
  4. # A server that provide access to interactive python interpreter through network
  5. #
  6. # This is a demo implementation of a Lodel2 interface
  7. import socket
  8. import threading
  9. import subprocess
  10. import time
  11. import sys
  12. import signal
  13. PORT = 1337
  14. #BIND = None
  15. BIND = 'localhost'
  16. THREAD_COUNT = 10
  17. SOCK_TIMEOUT = 5
  18. servsock = None # Stores the server socket in order to close it when exception is raised
  19. # Thread function called when client connected
  20. def client_thread(sock, addr):
  21. # Starting interactive Lodel2 python in a subprocess
  22. sock.setblocking(True)
  23. sock_stdin = sock.makefile(mode='r', encoding='utf-8', newline="\n")
  24. sock_stdout = sock.makefile(mode='w', encoding='utf-8', newline="\n")
  25. ipy = subprocess.Popen(['python', 'netipy_loader.py', addr[0]], stdin=sock_stdin, stdout=sock_stdout, stderr=sock_stdout)
  26. ipy.wait()
  27. sock.close()
  28. return True
  29. # Main loop
  30. def main():
  31. servsock = socket.socket(family = socket.AF_INET, type=socket.SOCK_STREAM)
  32. servsock.settimeout(5)
  33. bind_addr = socket.gethostname() if BIND is None else BIND
  34. servsock.bind((bind_addr, PORT))
  35. servsock.listen(5)
  36. globals()['servsock'] = servsock
  37. threads = list()
  38. print("Server listening on %s:%s" % (bind_addr, PORT))
  39. while True:
  40. # Accept if rooms left in threads list
  41. if len(threads) < THREAD_COUNT:
  42. try:
  43. (clientsocket, addr) = servsock.accept()
  44. print("Client connected : %s" % addr[0])
  45. thread = threading.Thread(target = client_thread, kwargs = {'sock': clientsocket, 'addr': addr})
  46. threads.append(thread)
  47. thread.start()
  48. except socket.timeout:
  49. pass
  50. # Thread cleanup
  51. for i in range(len(threads)-1,-1,-1):
  52. thread = threads[i]
  53. thread.join(0.1) #useless ?
  54. if not thread.is_alive():
  55. print("Thread %d exited" % i)
  56. threads.pop(i)
  57. # Signal handler designed to close socket when SIGINT
  58. def sigint_sock_close(signal, frame):
  59. if globals()['servsock'] is not None:
  60. globals()['servsock'].close()
  61. print("\nCtrl+c pressed, exiting...")
  62. exit(0)
  63. if __name__ == '__main__':
  64. signal.signal(signal.SIGINT, sigint_sock_close)
  65. try:
  66. main()
  67. except Exception as e:
  68. if globals()['servsock'] is not None:
  69. globals()['servsock'].close()
  70. raise e