/python3/05/blocks.py

https://bitbucket.org/brandon/foundations-of-python-network-programming/ · Python · 56 lines · 45 code · 8 blank · 3 comment · 9 complexity · 72f2211ed96dbd7fe0e401e21e5baf79 MD5 · raw file

  1. #!/usr/bin/env python
  2. # Foundations of Python Network Programming - Chapter 5 - blocks.py
  3. # Sending data one block at a time.
  4. import socket, struct, sys
  5. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  6. HOST = sys.argv.pop() if len(sys.argv) == 3 else '127.0.0.1'
  7. PORT = 1060
  8. format = struct.Struct('!I') # for messages up to 2**32 - 1 in length
  9. def recvall(sock, length):
  10. data = b''
  11. while len(data) < length:
  12. more = sock.recv(length - len(data))
  13. if not more:
  14. raise EOFError('socket closed %d bytes into a %d-byte message'
  15. % (len(data), length))
  16. data += more
  17. return data
  18. def get(sock):
  19. lendata = recvall(sock, format.size)
  20. (length,) = format.unpack(lendata)
  21. return recvall(sock, length)
  22. def put(sock, message):
  23. sock.send(format.pack(len(message)) + message)
  24. if sys.argv[1:] == ['server']:
  25. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  26. s.bind((HOST, PORT))
  27. s.listen(1)
  28. print('Listening at', s.getsockname())
  29. sc, sockname = s.accept()
  30. print('Accepted connection from', sockname)
  31. sc.shutdown(socket.SHUT_WR)
  32. while True:
  33. message = get(sc)
  34. if not message:
  35. break
  36. print('Message says:', repr(message))
  37. sc.close()
  38. s.close()
  39. elif sys.argv[1:] == ['client']:
  40. s.connect((HOST, PORT))
  41. s.shutdown(socket.SHUT_RD)
  42. put(s, b'Beautiful is better than ugly.')
  43. put(s, b'Explicit is better than implicit.')
  44. put(s, b'Simple is better than complex.')
  45. put(s, b'')
  46. s.close()
  47. else:
  48. print('usage: streamer.py server|client [host]', file=sys.stderr)