_socket.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. """
  2. websocket - WebSocket client library for Python
  3. Copyright (C) 2010 Hiroki Ohtani(liris)
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1335 USA
  16. """
  17. import socket
  18. import six
  19. import sys
  20. from ._exceptions import *
  21. from ._ssl_compat import *
  22. from ._utils import *
  23. DEFAULT_SOCKET_OPTION = [(socket.SOL_TCP, socket.TCP_NODELAY, 1)]
  24. if hasattr(socket, "SO_KEEPALIVE"):
  25. DEFAULT_SOCKET_OPTION.append((socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1))
  26. if hasattr(socket, "TCP_KEEPIDLE"):
  27. DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPIDLE, 30))
  28. if hasattr(socket, "TCP_KEEPINTVL"):
  29. DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPINTVL, 10))
  30. if hasattr(socket, "TCP_KEEPCNT"):
  31. DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPCNT, 3))
  32. _default_timeout = None
  33. __all__ = ["DEFAULT_SOCKET_OPTION", "sock_opt", "setdefaulttimeout", "getdefaulttimeout",
  34. "recv", "recv_line", "send"]
  35. class sock_opt(object):
  36. def __init__(self, sockopt, sslopt):
  37. if sockopt is None:
  38. sockopt = []
  39. if sslopt is None:
  40. sslopt = {}
  41. self.sockopt = sockopt
  42. self.sslopt = sslopt
  43. self.timeout = None
  44. def setdefaulttimeout(timeout):
  45. """
  46. Set the global timeout setting to connect.
  47. timeout: default socket timeout time. This value is second.
  48. """
  49. global _default_timeout
  50. _default_timeout = timeout
  51. def getdefaulttimeout():
  52. """
  53. Return the global timeout setting(second) to connect.
  54. """
  55. return _default_timeout
  56. def recv(sock, bufsize):
  57. if not sock:
  58. raise WebSocketConnectionClosedException("socket is already closed.")
  59. try:
  60. bytes_ = sock.recv(bufsize)
  61. except socket.timeout as e:
  62. message = extract_err_message(e)
  63. raise WebSocketTimeoutException(message)
  64. except SSLError as e:
  65. message = extract_err_message(e)
  66. if isinstance(message, str) and 'timed out' in message:
  67. raise WebSocketTimeoutException(message)
  68. else:
  69. raise
  70. if not bytes_:
  71. raise WebSocketConnectionClosedException(
  72. "Connection is already closed.")
  73. return bytes_
  74. def recv_line(sock):
  75. line = []
  76. while True:
  77. c = recv(sock, 1)
  78. line.append(c)
  79. if c == six.b("\n"):
  80. break
  81. return six.b("").join(line)
  82. def send(sock, data):
  83. if isinstance(data, six.text_type):
  84. data = data.encode('utf-8')
  85. if not sock:
  86. raise WebSocketConnectionClosedException("socket is already closed.")
  87. try:
  88. return sock.send(data)
  89. except socket.timeout as e:
  90. message = extract_err_message(e)
  91. raise WebSocketTimeoutException(message)
  92. except Exception as e:
  93. message = extract_err_message(e)
  94. if isinstance(message, str) and "timed out" in message:
  95. raise WebSocketTimeoutException(message)
  96. else:
  97. raise