PageRenderTime 71ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/Lib/socket.py

https://bitbucket.org/noghriw/jython
Python | 1786 lines | 1605 code | 119 blank | 62 comment | 117 complexity | 22937717251157039b8738c1aef347f4 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. """
  2. This is an updated socket module for use on JVMs >= 1.5; it is derived from the old jython socket module.
  3. It is documented, along with known issues and workarounds, on the jython wiki.
  4. http://wiki.python.org/jython/NewSocketModule
  5. """
  6. _defaulttimeout = None
  7. import errno
  8. import jarray
  9. import string
  10. import struct
  11. import sys
  12. import threading
  13. import time
  14. import types
  15. # Java.io classes
  16. import java.io.BufferedInputStream
  17. import java.io.BufferedOutputStream
  18. # Java.io exceptions
  19. import java.io.InterruptedIOException
  20. import java.io.IOException
  21. # Java.lang classes
  22. import java.lang.String
  23. # Java.lang exceptions
  24. import java.lang.Exception
  25. # Java.net classes
  26. import java.net.DatagramPacket
  27. import java.net.InetAddress
  28. import java.net.InetSocketAddress
  29. import java.net.Socket
  30. # Java.net exceptions
  31. import java.net.BindException
  32. import java.net.ConnectException
  33. import java.net.NoRouteToHostException
  34. import java.net.PortUnreachableException
  35. import java.net.ProtocolException
  36. import java.net.SocketException
  37. import java.net.SocketTimeoutException
  38. import java.net.UnknownHostException
  39. # Java.nio classes
  40. import java.nio.ByteBuffer
  41. import java.nio.channels.DatagramChannel
  42. import java.nio.channels.ServerSocketChannel
  43. import java.nio.channels.SocketChannel
  44. # Java.nio exceptions
  45. import java.nio.channels.AlreadyConnectedException
  46. import java.nio.channels.AsynchronousCloseException
  47. import java.nio.channels.CancelledKeyException
  48. import java.nio.channels.ClosedByInterruptException
  49. import java.nio.channels.ClosedChannelException
  50. import java.nio.channels.ClosedSelectorException
  51. import java.nio.channels.ConnectionPendingException
  52. import java.nio.channels.IllegalBlockingModeException
  53. import java.nio.channels.IllegalSelectorException
  54. import java.nio.channels.NoConnectionPendingException
  55. import java.nio.channels.NonReadableChannelException
  56. import java.nio.channels.NonWritableChannelException
  57. import java.nio.channels.NotYetBoundException
  58. import java.nio.channels.NotYetConnectedException
  59. import java.nio.channels.UnresolvedAddressException
  60. import java.nio.channels.UnsupportedAddressTypeException
  61. # Javax.net.ssl classes
  62. import javax.net.ssl.SSLSocketFactory
  63. # Javax.net.ssl exceptions
  64. javax.net.ssl.SSLException
  65. javax.net.ssl.SSLHandshakeException
  66. javax.net.ssl.SSLKeyException
  67. javax.net.ssl.SSLPeerUnverifiedException
  68. javax.net.ssl.SSLProtocolException
  69. import org.python.core.io.DatagramSocketIO
  70. import org.python.core.io.ServerSocketIO
  71. import org.python.core.io.SocketIO
  72. from org.python.core.Py import newString as asPyString
  73. class error(IOError): pass
  74. class herror(error): pass
  75. class gaierror(error): pass
  76. class timeout(error): pass
  77. class sslerror(error): pass
  78. def _add_exception_attrs(exc):
  79. setattr(exc, 'errno', exc[0])
  80. setattr(exc, 'strerror', exc[1])
  81. return exc
  82. def _unmapped_exception(exc):
  83. return _add_exception_attrs(error(-1, 'Unmapped exception: %s' % exc))
  84. def java_net_socketexception_handler(exc):
  85. if exc.message.startswith("Address family not supported by protocol family"):
  86. return _add_exception_attrs(error(errno.EAFNOSUPPORT,
  87. 'Address family not supported by protocol family: See http://wiki.python.org/jython/NewSocketModule#IPV6addresssupport'))
  88. return _unmapped_exception(exc)
  89. def would_block_error(exc=None):
  90. return _add_exception_attrs(error(errno.EWOULDBLOCK, 'The socket operation could not complete without blocking'))
  91. ALL = None
  92. _ssl_message = ": Differences between the SSL socket behaviour of cpython vs. jython are explained on the wiki: http://wiki.python.org/jython/NewSocketModule#SSL_Support"
  93. _exception_map = {
  94. # (<javaexception>, <circumstance>) : callable that raises the python equivalent exception, or None to stub out as unmapped
  95. (java.io.IOException, ALL) : lambda x: error(errno.ECONNRESET, 'Software caused connection abort'),
  96. (java.io.InterruptedIOException, ALL) : lambda x: timeout(None, 'timed out'),
  97. (java.net.BindException, ALL) : lambda x: error(errno.EADDRINUSE, 'Address already in use'),
  98. (java.net.ConnectException, ALL) : lambda x: error(errno.ECONNREFUSED, 'Connection refused'),
  99. (java.net.NoRouteToHostException, ALL) : None,
  100. (java.net.PortUnreachableException, ALL) : None,
  101. (java.net.ProtocolException, ALL) : None,
  102. (java.net.SocketException, ALL) : java_net_socketexception_handler,
  103. (java.net.SocketTimeoutException, ALL) : lambda x: timeout(None, 'timed out'),
  104. (java.net.UnknownHostException, ALL) : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'),
  105. (java.nio.channels.AlreadyConnectedException, ALL) : lambda x: error(errno.EISCONN, 'Socket is already connected'),
  106. (java.nio.channels.AsynchronousCloseException, ALL) : None,
  107. (java.nio.channels.CancelledKeyException, ALL) : None,
  108. (java.nio.channels.ClosedByInterruptException, ALL) : None,
  109. (java.nio.channels.ClosedChannelException, ALL) : lambda x: error(errno.EPIPE, 'Socket closed'),
  110. (java.nio.channels.ClosedSelectorException, ALL) : None,
  111. (java.nio.channels.ConnectionPendingException, ALL) : None,
  112. (java.nio.channels.IllegalBlockingModeException, ALL) : None,
  113. (java.nio.channels.IllegalSelectorException, ALL) : None,
  114. (java.nio.channels.NoConnectionPendingException, ALL) : None,
  115. (java.nio.channels.NonReadableChannelException, ALL) : None,
  116. (java.nio.channels.NonWritableChannelException, ALL) : None,
  117. (java.nio.channels.NotYetBoundException, ALL) : None,
  118. (java.nio.channels.NotYetConnectedException, ALL) : None,
  119. (java.nio.channels.UnresolvedAddressException, ALL) : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'),
  120. (java.nio.channels.UnsupportedAddressTypeException, ALL) : None,
  121. # These error codes are currently wrong: getting them correct is going to require
  122. # some investigation. Cpython 2.6 introduced extensive SSL support.
  123. (javax.net.ssl.SSLException, ALL) : lambda x: sslerror(-1, 'SSL exception'+_ssl_message),
  124. (javax.net.ssl.SSLHandshakeException, ALL) : lambda x: sslerror(-1, 'SSL handshake exception'+_ssl_message),
  125. (javax.net.ssl.SSLKeyException, ALL) : lambda x: sslerror(-1, 'SSL key exception'+_ssl_message),
  126. (javax.net.ssl.SSLPeerUnverifiedException, ALL) : lambda x: sslerror(-1, 'SSL peer unverified exception'+_ssl_message),
  127. (javax.net.ssl.SSLProtocolException, ALL) : lambda x: sslerror(-1, 'SSL protocol exception'+_ssl_message),
  128. }
  129. def _map_exception(java_exception, circumstance=ALL):
  130. mapped_exception = _exception_map.get((java_exception.__class__, circumstance))
  131. if mapped_exception:
  132. py_exception = mapped_exception(java_exception)
  133. else:
  134. py_exception = error(-1, 'Unmapped exception: %s' % java_exception)
  135. setattr(py_exception, 'java_exception', java_exception)
  136. return _add_exception_attrs(py_exception)
  137. _feature_support_map = {
  138. 'ipv6': True,
  139. 'idna': False,
  140. 'tipc': False,
  141. }
  142. def supports(feature, *args):
  143. if len(args) == 1:
  144. _feature_support_map[feature] = args[0]
  145. return _feature_support_map.get(feature, False)
  146. MODE_BLOCKING = 'block'
  147. MODE_NONBLOCKING = 'nonblock'
  148. MODE_TIMEOUT = 'timeout'
  149. _permitted_modes = (MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT)
  150. SHUT_RD = 0
  151. SHUT_WR = 1
  152. SHUT_RDWR = 2
  153. AF_UNSPEC = 0
  154. AF_INET = 2
  155. AF_INET6 = 23
  156. AI_PASSIVE = 1
  157. AI_CANONNAME = 2
  158. AI_NUMERICHOST = 4
  159. AI_V4MAPPED = 8
  160. AI_ALL = 16
  161. AI_ADDRCONFIG = 32
  162. AI_NUMERICSERV = 1024
  163. EAI_NONAME = -2
  164. EAI_SERVICE = -8
  165. EAI_ADDRFAMILY = -9
  166. NI_NUMERICHOST = 1
  167. NI_NUMERICSERV = 2
  168. NI_NOFQDN = 4
  169. NI_NAMEREQD = 8
  170. NI_DGRAM = 16
  171. NI_MAXSERV = 32
  172. NI_IDN = 64
  173. NI_IDN_ALLOW_UNASSIGNED = 128
  174. NI_IDN_USE_STD3_ASCII_RULES = 256
  175. NI_MAXHOST = 1025
  176. # For some reason, probably historical, SOCK_DGRAM and SOCK_STREAM are opposite values of what they are on cpython.
  177. # I.E. The following is the way they are on cpython
  178. # SOCK_STREAM = 1
  179. # SOCK_DGRAM = 2
  180. # At some point, we should probably switch them around, which *should* not affect anybody
  181. SOCK_DGRAM = 1
  182. SOCK_STREAM = 2
  183. SOCK_RAW = 3 # not supported
  184. SOCK_RDM = 4 # not supported
  185. SOCK_SEQPACKET = 5 # not supported
  186. SOL_SOCKET = 0xFFFF
  187. IPPROTO_TCP = 6
  188. IPPROTO_UDP = 17
  189. SO_BROADCAST = 1
  190. SO_KEEPALIVE = 2
  191. SO_LINGER = 4
  192. SO_OOBINLINE = 8
  193. SO_RCVBUF = 16
  194. SO_REUSEADDR = 32
  195. SO_SNDBUF = 64
  196. SO_TIMEOUT = 128
  197. TCP_NODELAY = 256
  198. INADDR_ANY = "0.0.0.0"
  199. INADDR_BROADCAST = "255.255.255.255"
  200. IN6ADDR_ANY_INIT = "::"
  201. # Options with negative constants are not supported
  202. # They are being added here so that code that refers to them
  203. # will not break with an AttributeError
  204. SO_ACCEPTCONN = -1
  205. SO_DEBUG = -2
  206. SO_DONTROUTE = -4
  207. SO_ERROR = -8
  208. SO_EXCLUSIVEADDRUSE = -16
  209. SO_RCVLOWAT = -32
  210. SO_RCVTIMEO = -64
  211. SO_REUSEPORT = -128
  212. SO_SNDLOWAT = -256
  213. SO_SNDTIMEO = -512
  214. SO_TYPE = -1024
  215. SO_USELOOPBACK = -2048
  216. __all__ = ['AF_UNSPEC', 'AF_INET', 'AF_INET6', 'AI_PASSIVE', 'SOCK_DGRAM',
  217. 'SOCK_RAW', 'SOCK_RDM', 'SOCK_SEQPACKET', 'SOCK_STREAM', 'SOL_SOCKET',
  218. 'SO_BROADCAST', 'SO_ERROR', 'SO_KEEPALIVE', 'SO_LINGER', 'SO_OOBINLINE',
  219. 'SO_RCVBUF', 'SO_REUSEADDR', 'SO_SNDBUF', 'SO_TIMEOUT', 'TCP_NODELAY',
  220. 'INADDR_ANY', 'INADDR_BROADCAST', 'IPPROTO_TCP', 'IPPROTO_UDP',
  221. 'SocketType', 'error', 'herror', 'gaierror', 'timeout',
  222. 'getfqdn', 'gethostbyaddr', 'gethostbyname', 'gethostname',
  223. 'socket', 'getaddrinfo', 'getdefaulttimeout', 'setdefaulttimeout',
  224. 'has_ipv6', 'htons', 'htonl', 'ntohs', 'ntohl',
  225. 'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR',
  226. ]
  227. def _constant_to_name(const_value):
  228. sock_module = sys.modules['socket']
  229. try:
  230. for name in dir(sock_module):
  231. if getattr(sock_module, name) is const_value and \
  232. (name.startswith('SO_') or name.startswith('SOL_') or \
  233. name.startswith('TCP_') or name.startswith('IPPROTO_')):
  234. return name
  235. return "Unknown"
  236. finally:
  237. sock_module = None
  238. import _google_ipaddr_r234
  239. def _is_ip_address(addr, version=None):
  240. try:
  241. _google_ipaddr_r234.IPAddress(addr, version)
  242. return True
  243. except ValueError:
  244. return False
  245. def is_ipv4_address(addr):
  246. return _is_ip_address(addr, 4)
  247. def is_ipv6_address(addr):
  248. return _is_ip_address(addr, 6)
  249. def is_ip_address(addr):
  250. return _is_ip_address(addr)
  251. class _nio_impl:
  252. timeout = None
  253. mode = MODE_BLOCKING
  254. def getpeername(self):
  255. return (self.jsocket.getInetAddress().getHostAddress(), self.jsocket.getPort() )
  256. def config(self, mode, timeout):
  257. self.mode = mode
  258. if self.mode == MODE_BLOCKING:
  259. self.jchannel.configureBlocking(1)
  260. if self.mode == MODE_NONBLOCKING:
  261. self.jchannel.configureBlocking(0)
  262. if self.mode == MODE_TIMEOUT:
  263. self.jchannel.configureBlocking(1)
  264. self._timeout_millis = int(timeout*1000)
  265. self.jsocket.setSoTimeout(self._timeout_millis)
  266. def getsockopt(self, level, option):
  267. if (level, option) in self.options:
  268. result = getattr(self.jsocket, "get%s" % self.options[ (level, option) ])()
  269. if option == SO_LINGER:
  270. if result == -1:
  271. enabled, linger_time = 0, 0
  272. else:
  273. enabled, linger_time = 1, result
  274. return struct.pack('ii', enabled, linger_time)
  275. return result
  276. else:
  277. raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % (_constant_to_name(option), _constant_to_name(level), str(self.jsocket)))
  278. def setsockopt(self, level, option, value):
  279. if (level, option) in self.options:
  280. if option == SO_LINGER:
  281. values = struct.unpack('ii', value)
  282. self.jsocket.setSoLinger(*values)
  283. else:
  284. getattr(self.jsocket, "set%s" % self.options[ (level, option) ])(value)
  285. else:
  286. raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % (_constant_to_name(option), _constant_to_name(level), str(self.jsocket)))
  287. def close(self):
  288. self.jsocket.close()
  289. def getchannel(self):
  290. return self.jchannel
  291. def fileno(self):
  292. return self.socketio
  293. class _client_socket_impl(_nio_impl):
  294. options = {
  295. (SOL_SOCKET, SO_KEEPALIVE): 'KeepAlive',
  296. (SOL_SOCKET, SO_LINGER): 'SoLinger',
  297. (SOL_SOCKET, SO_OOBINLINE): 'OOBInline',
  298. (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize',
  299. (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress',
  300. (SOL_SOCKET, SO_SNDBUF): 'SendBufferSize',
  301. (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout',
  302. (IPPROTO_TCP, TCP_NODELAY): 'TcpNoDelay',
  303. }
  304. def __init__(self, socket=None):
  305. if socket:
  306. self.jchannel = socket.getChannel()
  307. else:
  308. self.jchannel = java.nio.channels.SocketChannel.open()
  309. self.jsocket = self.jchannel.socket()
  310. self.socketio = org.python.core.io.SocketIO(self.jchannel, 'rw')
  311. def bind(self, jsockaddr, reuse_addr):
  312. self.jsocket.setReuseAddress(reuse_addr)
  313. self.jsocket.bind(jsockaddr)
  314. def connect(self, jsockaddr):
  315. if self.mode == MODE_TIMEOUT:
  316. self.jsocket.connect (jsockaddr, self._timeout_millis)
  317. else:
  318. self.jchannel.connect(jsockaddr)
  319. def finish_connect(self):
  320. return self.jchannel.finishConnect()
  321. def _do_read_net(self, buf):
  322. # Need two separate implementations because the java.nio APIs do not support timeouts
  323. return self.jsocket.getInputStream().read(buf)
  324. def _do_read_nio(self, buf):
  325. bytebuf = java.nio.ByteBuffer.wrap(buf)
  326. count = self.jchannel.read(bytebuf)
  327. return count
  328. def _do_write_net(self, buf):
  329. self.jsocket.getOutputStream().write(buf)
  330. return len(buf)
  331. def _do_write_nio(self, buf):
  332. bytebuf = java.nio.ByteBuffer.wrap(buf)
  333. count = self.jchannel.write(bytebuf)
  334. return count
  335. def read(self, buf):
  336. if self.mode == MODE_TIMEOUT:
  337. return self._do_read_net(buf)
  338. else:
  339. return self._do_read_nio(buf)
  340. def write(self, buf):
  341. if self.mode == MODE_TIMEOUT:
  342. return self._do_write_net(buf)
  343. else:
  344. return self._do_write_nio(buf)
  345. def shutdown(self, how):
  346. if how in (SHUT_RD, SHUT_RDWR):
  347. self.jsocket.shutdownInput()
  348. if how in (SHUT_WR, SHUT_RDWR):
  349. self.jsocket.shutdownOutput()
  350. class _server_socket_impl(_nio_impl):
  351. options = {
  352. (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize',
  353. (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress',
  354. (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout',
  355. }
  356. def __init__(self, jsockaddr, backlog, reuse_addr):
  357. self.jchannel = java.nio.channels.ServerSocketChannel.open()
  358. self.jsocket = self.jchannel.socket()
  359. self.jsocket.setReuseAddress(reuse_addr)
  360. self.jsocket.bind(jsockaddr, backlog)
  361. self.socketio = org.python.core.io.ServerSocketIO(self.jchannel, 'rw')
  362. def accept(self):
  363. if self.mode in (MODE_BLOCKING, MODE_NONBLOCKING):
  364. new_cli_chan = self.jchannel.accept()
  365. if new_cli_chan is not None:
  366. return _client_socket_impl(new_cli_chan.socket())
  367. else:
  368. return None
  369. else:
  370. # In timeout mode now
  371. new_cli_sock = self.jsocket.accept()
  372. return _client_socket_impl(new_cli_sock)
  373. def shutdown(self, how):
  374. # This is no-op on java, for server sockets.
  375. # What the user wants to achieve is achieved by calling close() on
  376. # java/jython. But we can't call that here because that would then
  377. # later cause the user explicit close() call to fail
  378. pass
  379. class _datagram_socket_impl(_nio_impl):
  380. options = {
  381. (SOL_SOCKET, SO_BROADCAST): 'Broadcast',
  382. (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize',
  383. (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress',
  384. (SOL_SOCKET, SO_SNDBUF): 'SendBufferSize',
  385. (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout',
  386. }
  387. def __init__(self, jsockaddr=None, reuse_addr=0):
  388. self.jchannel = java.nio.channels.DatagramChannel.open()
  389. self.jsocket = self.jchannel.socket()
  390. if jsockaddr is not None:
  391. self.jsocket.setReuseAddress(reuse_addr)
  392. self.jsocket.bind(jsockaddr)
  393. self.socketio = org.python.core.io.DatagramSocketIO(self.jchannel, 'rw')
  394. def connect(self, jsockaddr):
  395. self.jchannel.connect(jsockaddr)
  396. def disconnect(self):
  397. """
  398. Disconnect the datagram socket.
  399. cpython appears not to have this operation
  400. """
  401. self.jchannel.disconnect()
  402. def shutdown(self, how):
  403. # This is no-op on java, for datagram sockets.
  404. # What the user wants to achieve is achieved by calling close() on
  405. # java/jython. But we can't call that here because that would then
  406. # later cause the user explicit close() call to fail
  407. pass
  408. def _do_send_net(self, byte_array, socket_address, flags):
  409. # Need two separate implementations because the java.nio APIs do not support timeouts
  410. num_bytes = len(byte_array)
  411. if self.jsocket.isConnected() and socket_address is None:
  412. packet = java.net.DatagramPacket(byte_array, num_bytes)
  413. else:
  414. packet = java.net.DatagramPacket(byte_array, num_bytes, socket_address)
  415. self.jsocket.send(packet)
  416. return num_bytes
  417. def _do_send_nio(self, byte_array, socket_address, flags):
  418. byte_buf = java.nio.ByteBuffer.wrap(byte_array)
  419. if self.jchannel.isConnected() and socket_address is None:
  420. bytes_sent = self.jchannel.write(byte_buf)
  421. else:
  422. bytes_sent = self.jchannel.send(byte_buf, socket_address)
  423. return bytes_sent
  424. def sendto(self, byte_array, jsockaddr, flags):
  425. if self.mode == MODE_TIMEOUT:
  426. return self._do_send_net(byte_array, jsockaddr, flags)
  427. else:
  428. return self._do_send_nio(byte_array, jsockaddr, flags)
  429. def send(self, byte_array, flags):
  430. if self.mode == MODE_TIMEOUT:
  431. return self._do_send_net(byte_array, None, flags)
  432. else:
  433. return self._do_send_nio(byte_array, None, flags)
  434. def _do_receive_net(self, return_source_address, num_bytes, flags):
  435. byte_array = jarray.zeros(num_bytes, 'b')
  436. packet = java.net.DatagramPacket(byte_array, num_bytes)
  437. self.jsocket.receive(packet)
  438. bytes_rcvd = packet.getLength()
  439. if bytes_rcvd < num_bytes:
  440. byte_array = byte_array[:bytes_rcvd]
  441. return_data = byte_array.tostring()
  442. if return_source_address:
  443. host = None
  444. if packet.getAddress():
  445. host = packet.getAddress().getHostAddress()
  446. port = packet.getPort()
  447. return return_data, (host, port)
  448. else:
  449. return return_data
  450. def _do_receive_nio(self, return_source_address, num_bytes, flags):
  451. byte_array = jarray.zeros(num_bytes, 'b')
  452. byte_buf = java.nio.ByteBuffer.wrap(byte_array)
  453. source_address = self.jchannel.receive(byte_buf)
  454. if source_address is None and not self.jchannel.isBlocking():
  455. raise would_block_error()
  456. byte_buf.flip() ; bytes_read = byte_buf.remaining()
  457. if bytes_read < num_bytes:
  458. byte_array = byte_array[:bytes_read]
  459. return_data = byte_array.tostring()
  460. if return_source_address:
  461. return return_data, (source_address.getAddress().getHostAddress(), source_address.getPort())
  462. else:
  463. return return_data
  464. def recvfrom(self, num_bytes, flags):
  465. if self.mode == MODE_TIMEOUT:
  466. return self._do_receive_net(1, num_bytes, flags)
  467. else:
  468. return self._do_receive_nio(1, num_bytes, flags)
  469. def recv(self, num_bytes, flags):
  470. if self.mode == MODE_TIMEOUT:
  471. return self._do_receive_net(0, num_bytes, flags)
  472. else:
  473. return self._do_receive_nio(0, num_bytes, flags)
  474. has_ipv6 = True # IPV6 FTW!
  475. # Name and address functions
  476. def _gethostbyaddr(name):
  477. # This is as close as I can get; at least the types are correct...
  478. addresses = java.net.InetAddress.getAllByName(gethostbyname(name))
  479. names = []
  480. addrs = []
  481. for addr in addresses:
  482. names.append(asPyString(addr.getHostName()))
  483. addrs.append(asPyString(addr.getHostAddress()))
  484. return (names, addrs)
  485. def getfqdn(name=None):
  486. """
  487. Return a fully qualified domain name for name. If name is omitted or empty
  488. it is interpreted as the local host. To find the fully qualified name,
  489. the hostname returned by gethostbyaddr() is checked, then aliases for the
  490. host, if available. The first name which includes a period is selected.
  491. In case no fully qualified domain name is available, the hostname is retur
  492. New in version 2.0.
  493. """
  494. if not name:
  495. name = gethostname()
  496. names, addrs = _gethostbyaddr(name)
  497. for a in names:
  498. if a.find(".") >= 0:
  499. return a
  500. return name
  501. def gethostname():
  502. try:
  503. return asPyString(java.net.InetAddress.getLocalHost().getHostName())
  504. except java.lang.Exception, jlx:
  505. raise _map_exception(jlx)
  506. def gethostbyname(name):
  507. try:
  508. return asPyString(java.net.InetAddress.getByName(name).getHostAddress())
  509. except java.lang.Exception, jlx:
  510. raise _map_exception(jlx)
  511. def gethostbyaddr(name):
  512. names, addrs = _gethostbyaddr(name)
  513. return (names[0], names, addrs)
  514. def getservbyname(service_name, protocol_name=None):
  515. try:
  516. from jnr.netdb import Service
  517. except ImportError:
  518. return None
  519. service = Service.getServiceByName(service_name, protocol_name)
  520. if service is None:
  521. raise error('service/proto not found')
  522. return service.getPort()
  523. def getservbyport(port, protocol_name=None):
  524. try:
  525. from jnr.netdb import Service
  526. except ImportError:
  527. return None
  528. service = Service.getServiceByPort(port, protocol_name)
  529. if service is None:
  530. raise error('port/proto not found')
  531. return service.getName()
  532. def getprotobyname(protocol_name=None):
  533. try:
  534. from jnr.netdb import Protocol
  535. except ImportError:
  536. return None
  537. proto = Protocol.getProtocolByName(protocol_name)
  538. if proto is None:
  539. raise error('protocol not found')
  540. return proto.getProto()
  541. def _realsocket(family = AF_INET, sock_type = SOCK_STREAM, protocol=0):
  542. assert family in (AF_INET, AF_INET6), "Only AF_INET and AF_INET6 sockets are currently supported on jython"
  543. assert sock_type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython"
  544. if sock_type == SOCK_STREAM:
  545. if protocol != 0:
  546. assert protocol == IPPROTO_TCP, "Only IPPROTO_TCP supported on SOCK_STREAM sockets"
  547. else:
  548. protocol = IPPROTO_TCP
  549. result = _tcpsocket()
  550. else:
  551. if protocol != 0:
  552. assert protocol == IPPROTO_UDP, "Only IPPROTO_UDP supported on SOCK_DGRAM sockets"
  553. else:
  554. protocol = IPPROTO_UDP
  555. result = _udpsocket()
  556. setattr(result, "family", family)
  557. setattr(result, "type", sock_type)
  558. setattr(result, "proto", protocol)
  559. return result
  560. #
  561. # Attempt to provide IDNA (RFC 3490) support.
  562. #
  563. # Try java.net.IDN, built into java 6
  564. #
  565. idna_libraries = [
  566. ('java.net.IDN', 'toASCII', 'toUnicode',
  567. 'ALLOW_UNASSIGNED', 'USE_STD3_ASCII_RULES',
  568. java.lang.IllegalArgumentException)
  569. ]
  570. for idna_lib, efn, dfn, au, usar, exc in idna_libraries:
  571. try:
  572. m = __import__(idna_lib, globals(), locals(), [efn, dfn, au, usar])
  573. encode_fn = getattr(m, efn)
  574. def _encode_idna(name):
  575. try:
  576. return encode_fn(name)
  577. except exc:
  578. raise UnicodeEncodeError(name)
  579. decode_fn = getattr(m, dfn)
  580. def _decode_idna(name, flags=0):
  581. try:
  582. jflags = 0
  583. if flags & NI_IDN_ALLOW_UNASSIGNED:
  584. jflags |= au
  585. if flags & NI_IDN_USE_STD3_ASCII_RULES:
  586. jflags |= usar
  587. return decode_fn(name, jflags)
  588. except Exception, x:
  589. raise UnicodeDecodeError(name)
  590. supports('idna', True)
  591. break
  592. except (AttributeError, ImportError), e:
  593. pass
  594. else:
  595. _encode_idna = lambda x: x.encode("ascii")
  596. _decode_idna = lambda x, y=0: x.decode("ascii")
  597. #
  598. # Define data structures to support IPV4 and IPV6.
  599. #
  600. class _ip_address_t: pass
  601. class _ipv4_address_t(_ip_address_t):
  602. def __init__(self, sockaddr, port, jaddress):
  603. self.sockaddr = sockaddr
  604. self.port = port
  605. self.jaddress = jaddress
  606. def __getitem__(self, index):
  607. if 0 == index:
  608. return self.sockaddr
  609. elif 1 == index:
  610. return self.port
  611. else:
  612. raise IndexError()
  613. def __len__(self):
  614. return 2
  615. def __str__(self):
  616. return "('%s', %d)" % (self.sockaddr, self.port)
  617. __repr__ = __str__
  618. class _ipv6_address_t(_ip_address_t):
  619. def __init__(self, sockaddr, port, jaddress):
  620. self.sockaddr = sockaddr
  621. self.port = port
  622. self.jaddress = jaddress
  623. def __getitem__(self, index):
  624. if 0 == index:
  625. return self.sockaddr
  626. elif 1 == index:
  627. return self.port
  628. elif 2 == index:
  629. return 0
  630. elif 3 == index:
  631. return self.jaddress.scopeId
  632. else:
  633. raise IndexError()
  634. def __len__(self):
  635. return 4
  636. def __str__(self):
  637. return "('%s', %d, 0, %d)" % (self.sockaddr, self.port, self.jaddress.scopeId)
  638. __repr__ = __str__
  639. def _get_jsockaddr(address_object, family, sock_type, proto, flags):
  640. # Is this an object that was returned from getaddrinfo? If so, it already contains an InetAddress
  641. if isinstance(address_object, _ip_address_t):
  642. return java.net.InetSocketAddress(address_object.jaddress, address_object[1])
  643. # The user passed an address tuple, not an object returned from getaddrinfo
  644. # So we must call getaddrinfo, after some translations and checking
  645. if address_object is None:
  646. address_object = ("", 0)
  647. error_message = "Address must be a 2-tuple (ipv4: (host, port)) or a 4-tuple (ipv6: (host, port, flow, scope))"
  648. if not isinstance(address_object, tuple) or \
  649. ((family == AF_INET and len(address_object) != 2) or (family == AF_INET6 and len(address_object) not in [2,4] )) or \
  650. not isinstance(address_object[0], basestring) or \
  651. not isinstance(address_object[1], (int, long)):
  652. raise TypeError(error_message)
  653. if len(address_object) == 4 and not isinstance(address_object[3], (int, long)):
  654. raise TypeError(error_message)
  655. hostname, port = address_object[0].strip(), address_object[1]
  656. if family == AF_INET and sock_type == SOCK_DGRAM and hostname == "<broadcast>":
  657. hostname = INADDR_BROADCAST
  658. if hostname == "":
  659. if flags & AI_PASSIVE:
  660. hostname = {AF_INET: INADDR_ANY, AF_INET6: IN6ADDR_ANY_INIT}[family]
  661. else:
  662. hostname = "localhost"
  663. if isinstance(hostname, unicode):
  664. hostname = _encode_idna(hostname)
  665. addresses = getaddrinfo(hostname, port, family, sock_type, proto, flags)
  666. if len(addresses) == 0:
  667. raise gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed')
  668. return java.net.InetSocketAddress(addresses[0][4].jaddress, port)
  669. # Workaround for this (predominantly windows) issue
  670. # http://wiki.python.org/jython/NewSocketModule#IPV6_address_support
  671. _ipv4_addresses_only = False
  672. def _use_ipv4_addresses_only(value):
  673. global _ipv4_addresses_only
  674. _ipv4_addresses_only = value
  675. def _getaddrinfo_get_host(host, family, flags):
  676. if host is None:
  677. return host
  678. if not isinstance(host, basestring):
  679. raise TypeError("getaddrinfo() argument 1 must be string or None")
  680. if flags & AI_NUMERICHOST:
  681. if not is_ip_address(host):
  682. raise gaierror(EAI_NONAME, "Name or service not known")
  683. if family == AF_INET and not is_ipv4_address(host):
  684. raise gaierror(EAI_ADDRFAMILY, "Address family for hostname not supported")
  685. if family == AF_INET6 and not is_ipv6_address(host):
  686. raise gaierror(EAI_ADDRFAMILY, "Address family for hostname not supported")
  687. if isinstance(host, unicode):
  688. host = _encode_idna(host)
  689. return host
  690. def _getaddrinfo_get_port(port, flags):
  691. if isinstance(port, basestring):
  692. try:
  693. int_port = int(port)
  694. except ValueError:
  695. if flags & AI_NUMERICSERV:
  696. raise gaierror(EAI_NONAME, "Name or service not known")
  697. # Lookup the service by name
  698. try:
  699. int_port = getservbyname(port)
  700. except error:
  701. raise gaierror(EAI_SERVICE, "Servname not supported for ai_socktype")
  702. elif port is None:
  703. int_port = 0
  704. elif not isinstance(port, (int, long)):
  705. raise error("Int or String expected")
  706. else:
  707. int_port = int(port)
  708. return int_port % 65536
  709. def getaddrinfo(host, port, family=AF_INET, socktype=None, proto=0, flags=0):
  710. try:
  711. if _ipv4_addresses_only:
  712. family = AF_INET
  713. if not family in [AF_INET, AF_INET6, AF_UNSPEC]:
  714. raise gaierror(errno.EIO, 'ai_family not supported')
  715. host = _getaddrinfo_get_host(host, family, flags)
  716. port = _getaddrinfo_get_port(port, flags)
  717. filter_fns = []
  718. filter_fns.append({
  719. AF_INET: lambda x: isinstance(x, java.net.Inet4Address),
  720. AF_INET6: lambda x: isinstance(x, java.net.Inet6Address),
  721. AF_UNSPEC: lambda x: isinstance(x, java.net.InetAddress),
  722. }[family])
  723. passive_mode = flags is not None and flags & AI_PASSIVE
  724. canonname_mode = flags is not None and flags & AI_CANONNAME
  725. results = []
  726. for a in java.net.InetAddress.getAllByName(host):
  727. if len([f for f in filter_fns if f(a)]):
  728. family = {java.net.Inet4Address: AF_INET, java.net.Inet6Address: AF_INET6}[a.getClass()]
  729. if passive_mode and not canonname_mode:
  730. canonname = ""
  731. else:
  732. canonname = asPyString(a.getCanonicalHostName())
  733. if host is None and passive_mode and not canonname_mode:
  734. sockaddr = INADDR_ANY
  735. else:
  736. sockaddr = asPyString(a.getHostAddress())
  737. # TODO: Include flowinfo and scopeid in a 4-tuple for IPv6 addresses
  738. sock_tuple = {AF_INET : _ipv4_address_t, AF_INET6 : _ipv6_address_t}[family](sockaddr, port, a)
  739. results.append((family, socktype, proto, canonname, sock_tuple))
  740. return results
  741. except java.lang.Exception, jlx:
  742. raise _map_exception(jlx)
  743. def _getnameinfo_get_host(address, flags):
  744. if not isinstance(address, basestring):
  745. raise TypeError("getnameinfo() address 1 must be string, not None")
  746. if isinstance(address, unicode):
  747. address = _encode_idna(address)
  748. jia = java.net.InetAddress.getByName(address)
  749. result = jia.getCanonicalHostName()
  750. if flags & NI_NAMEREQD:
  751. if is_ip_address(result):
  752. raise gaierror(EAI_NONAME, "Name or service not known")
  753. elif flags & NI_NUMERICHOST:
  754. result = jia.getHostAddress()
  755. # Ignoring NI_NOFQDN for now
  756. if flags & NI_IDN:
  757. result = _decode_idna(result, flags)
  758. return result
  759. def _getnameinfo_get_port(port, flags):
  760. if not isinstance(port, (int, long)):
  761. raise TypeError("getnameinfo() port number must be an integer")
  762. if flags & NI_NUMERICSERV:
  763. return port
  764. proto = None
  765. if flags & NI_DGRAM:
  766. proto = "udp"
  767. return getservbyport(port, proto)
  768. def getnameinfo(sock_addr, flags):
  769. if not isinstance(sock_addr, tuple) or len(sock_addr) < 2:
  770. raise TypeError("getnameinfo() argument 1 must be a tuple")
  771. host = _getnameinfo_get_host(sock_addr[0], flags)
  772. port = _getnameinfo_get_port(sock_addr[1], flags)
  773. return (host, port)
  774. def getdefaulttimeout():
  775. return _defaulttimeout
  776. def _calctimeoutvalue(value):
  777. if value is None:
  778. return None
  779. try:
  780. floatvalue = float(value)
  781. except:
  782. raise TypeError('Socket timeout value must be a number or None')
  783. if floatvalue < 0.0:
  784. raise ValueError("Socket timeout value cannot be negative")
  785. if floatvalue < 0.000001:
  786. return 0.0
  787. return floatvalue
  788. def setdefaulttimeout(timeout):
  789. global _defaulttimeout
  790. try:
  791. _defaulttimeout = _calctimeoutvalue(timeout)
  792. finally:
  793. _nonblocking_api_mixin.timeout = _defaulttimeout
  794. def htons(x): return x
  795. def htonl(x): return x
  796. def ntohs(x): return x
  797. def ntohl(x): return x
  798. def inet_pton(family, ip_string):
  799. try:
  800. if family == AF_INET:
  801. if not is_ipv4_address(ip_string):
  802. raise error("illegal IP address string passed to inet_pton")
  803. elif family == AF_INET6:
  804. if not is_ipv6_address(ip_string):
  805. raise error("illegal IP address string passed to inet_pton")
  806. else:
  807. raise error(errno.EAFNOSUPPORT, "Address family not supported by protocol")
  808. ia = java.net.InetAddress.getByName(ip_string)
  809. bytes = []
  810. for byte in ia.getAddress():
  811. if byte < 0:
  812. bytes.append(byte+256)
  813. else:
  814. bytes.append(byte)
  815. return "".join([chr(byte) for byte in bytes])
  816. except java.lang.Exception, jlx:
  817. raise _map_exception(jlx)
  818. def inet_ntop(family, packed_ip):
  819. try:
  820. jByteArray = jarray.array(packed_ip, 'b')
  821. if family == AF_INET:
  822. if len(jByteArray) != 4:
  823. raise ValueError("invalid length of packed IP address string")
  824. elif family == AF_INET6:
  825. if len(jByteArray) != 16:
  826. raise ValueError("invalid length of packed IP address string")
  827. else:
  828. raise ValueError("unknown address family %s" % family)
  829. ia = java.net.InetAddress.getByAddress(jByteArray)
  830. return ia.getHostAddress()
  831. except java.lang.Exception, jlx:
  832. raise _map_exception(jlx)
  833. def inet_aton(ip_string):
  834. return inet_pton(AF_INET, ip_string)
  835. def inet_ntoa(packed_ip):
  836. return inet_ntop(AF_INET, packed_ip)
  837. class _nonblocking_api_mixin:
  838. mode = MODE_BLOCKING
  839. reference_count = 0
  840. close_lock = threading.Lock()
  841. def __init__(self):
  842. self.timeout = _defaulttimeout
  843. if self.timeout is not None:
  844. self.mode = MODE_TIMEOUT
  845. self.pending_options = {
  846. (SOL_SOCKET, SO_REUSEADDR): 0,
  847. }
  848. def gettimeout(self):
  849. return self.timeout
  850. def settimeout(self, timeout):
  851. self.timeout = _calctimeoutvalue(timeout)
  852. if self.timeout is None:
  853. self.mode = MODE_BLOCKING
  854. elif self.timeout < 0.000001:
  855. self.mode = MODE_NONBLOCKING
  856. else:
  857. self.mode = MODE_TIMEOUT
  858. self._config()
  859. def setblocking(self, flag):
  860. if flag:
  861. self.mode = MODE_BLOCKING
  862. self.timeout = None
  863. else:
  864. self.mode = MODE_NONBLOCKING
  865. self.timeout = 0.0
  866. self._config()
  867. def getblocking(self):
  868. return self.mode == MODE_BLOCKING
  869. def setsockopt(self, level, optname, value):
  870. try:
  871. if self.sock_impl:
  872. self.sock_impl.setsockopt(level, optname, value)
  873. else:
  874. self.pending_options[ (level, optname) ] = value
  875. except java.lang.Exception, jlx:
  876. raise _map_exception(jlx)
  877. def getsockopt(self, level, optname):
  878. try:
  879. if self.sock_impl:
  880. return self.sock_impl.getsockopt(level, optname)
  881. else:
  882. return self.pending_options.get( (level, optname), None)
  883. except java.lang.Exception, jlx:
  884. raise _map_exception(jlx)
  885. def shutdown(self, how):
  886. assert how in (SHUT_RD, SHUT_WR, SHUT_RDWR)
  887. if not self.sock_impl:
  888. raise error(errno.ENOTCONN, "Transport endpoint is not connected")
  889. try:
  890. self.sock_impl.shutdown(how)
  891. except java.lang.Exception, jlx:
  892. raise _map_exception(jlx)
  893. def close(self):
  894. try:
  895. if self.sock_impl:
  896. self.sock_impl.close()
  897. except java.lang.Exception, jlx:
  898. raise _map_exception(jlx)
  899. def _config(self):
  900. assert self.mode in _permitted_modes
  901. if self.sock_impl:
  902. self.sock_impl.config(self.mode, self.timeout)
  903. for level, optname in self.pending_options.keys():
  904. if optname != SO_REUSEADDR:
  905. self.sock_impl.setsockopt(level, optname, self.pending_options[ (level, optname) ])
  906. def getchannel(self):
  907. if not self.sock_impl:
  908. return None
  909. return self.sock_impl.getchannel()
  910. def fileno(self):
  911. if not self.sock_impl:
  912. return None
  913. return self.sock_impl.fileno()
  914. def _get_jsocket(self):
  915. return self.sock_impl.jsocket
  916. class _tcpsocket(_nonblocking_api_mixin):
  917. sock_impl = None
  918. istream = None
  919. ostream = None
  920. local_addr = None
  921. server = 0
  922. def __init__(self):
  923. _nonblocking_api_mixin.__init__(self)
  924. def bind(self, addr):
  925. assert not self.sock_impl
  926. assert not self.local_addr
  927. # Do the address format check
  928. _get_jsockaddr(addr, self.family, self.type, self.proto, 0)
  929. self.local_addr = addr
  930. def listen(self, backlog):
  931. "This signifies a server socket"
  932. try:
  933. assert not self.sock_impl
  934. self.server = 1
  935. self.sock_impl = _server_socket_impl(_get_jsockaddr(self.local_addr, self.family, self.type, self.proto, AI_PASSIVE),
  936. backlog, self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
  937. self._config()
  938. except java.lang.Exception, jlx:
  939. raise _map_exception(jlx)
  940. def accept(self):
  941. "This signifies a server socket"
  942. try:
  943. if not self.sock_impl:
  944. self.listen()
  945. assert self.server
  946. new_sock = self.sock_impl.accept()
  947. if not new_sock:
  948. raise would_block_error()
  949. cliconn = _tcpsocket()
  950. cliconn.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ] = new_sock.jsocket.getReuseAddress()
  951. cliconn.sock_impl = new_sock
  952. cliconn._setup()
  953. return cliconn, new_sock.getpeername()
  954. except java.lang.Exception, jlx:
  955. raise _map_exception(jlx)
  956. def _do_connect(self, addr):
  957. try:
  958. assert not self.sock_impl
  959. self.sock_impl = _client_socket_impl()
  960. if self.local_addr: # Has the socket been bound to a local address?
  961. self.sock_impl.bind(_get_jsockaddr(self.local_addr, self.family, self.type, self.proto, 0),
  962. self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
  963. self._config() # Configure timeouts, etc, now that the socket exists
  964. self.sock_impl.connect(_get_jsockaddr(addr, self.family, self.type, self.proto, 0))
  965. except java.lang.Exception, jlx:
  966. raise _map_exception(jlx)
  967. def connect(self, addr):
  968. "This signifies a client socket"
  969. self._do_connect(addr)
  970. self._setup()
  971. def connect_ex(self, addr):
  972. "This signifies a client socket"
  973. if not self.sock_impl:
  974. self._do_connect(addr)
  975. if self.sock_impl.finish_connect():
  976. self._setup()
  977. if self.mode == MODE_NONBLOCKING:
  978. return errno.EISCONN
  979. return 0
  980. return errno.EINPROGRESS
  981. def _setup(self):
  982. if self.mode != MODE_NONBLOCKING:
  983. self.istream = self.sock_impl.jsocket.getInputStream()
  984. self.ostream = self.sock_impl.jsocket.getOutputStream()
  985. def recv(self, n):
  986. try:
  987. if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected')
  988. if self.sock_impl.jchannel.isConnectionPending():
  989. self.sock_impl.jchannel.finishConnect()
  990. data = jarray.zeros(n, 'b')
  991. m = self.sock_impl.read(data)
  992. if m == -1:#indicates EOF has been reached, so we just return the empty string
  993. return ""
  994. elif m <= 0:
  995. if self.mode == MODE_NONBLOCKING:
  996. raise would_block_error()
  997. return ""
  998. if m < n:
  999. data = data[:m]
  1000. return data.tostring()
  1001. except java.lang.Exception, jlx:
  1002. raise _map_exception(jlx)
  1003. def recvfrom(self, n):
  1004. return self.recv(n), None
  1005. def send(self, s):
  1006. try:
  1007. if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected')
  1008. if self.sock_impl.jchannel.isConnectionPending():
  1009. self.sock_impl.jchannel.finishConnect()
  1010. numwritten = self.sock_impl.write(s)
  1011. if numwritten == 0 and self.mode == MODE_NONBLOCKING:
  1012. raise would_block_error()
  1013. return numwritten
  1014. except java.lang.Exception, jlx:
  1015. raise _map_exception(jlx)
  1016. sendall = send
  1017. def getsockname(self):
  1018. try:
  1019. if not self.sock_impl:
  1020. host, port = self.local_addr or ("", 0)
  1021. host = java.net.InetAddress.getByName(host).getHostAddress()
  1022. else:
  1023. if self.server:
  1024. host = self.sock_impl.jsocket.getInetAddress().getHostAddress()
  1025. else:
  1026. host = self.sock_impl.jsocket.getLocalAddress().getHostAddress()
  1027. port = self.sock_impl.jsocket.getLocalPort()
  1028. return (host, port)
  1029. except java.lang.Exception, jlx:
  1030. raise _map_exception(jlx)
  1031. def getpeername(self):
  1032. try:
  1033. assert self.sock_impl
  1034. assert not self.server
  1035. host = self.sock_impl.jsocket.getInetAddress().getHostAddress()
  1036. port = self.sock_impl.jsocket.getPort()
  1037. return (host, port)
  1038. except java.lang.Exception, jlx:
  1039. raise _map_exception(jlx)
  1040. def close(self):
  1041. try:
  1042. if self.istream:
  1043. self.istream.close()
  1044. if self.ostream:
  1045. self.ostream.close()
  1046. if self.sock_impl:
  1047. self.sock_impl.close()
  1048. except java.lang.Exception, jlx:
  1049. raise _map_exception(jlx)
  1050. class _udpsocket(_nonblocking_api_mixin):
  1051. sock_impl = None
  1052. connected = False
  1053. def __init__(self):
  1054. _nonblocking_api_mixin.__init__(self)
  1055. def bind(self, addr):
  1056. try:
  1057. assert not self.sock_impl
  1058. self.sock_impl = _datagram_socket_impl(_get_jsockaddr(addr, self.family, self.type, self.proto, AI_PASSIVE),
  1059. self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ])
  1060. self._config()
  1061. except java.lang.Exception, jlx:
  1062. raise _map_exception(jlx)
  1063. def _do_connect(self, addr):
  1064. try:
  1065. assert not self.connected, "Datagram Socket is already connected"
  1066. if not self.sock_impl:
  1067. self.sock_impl = _datagram_socket_impl()
  1068. self._config()
  1069. self.sock_impl.connect(_get_jsockaddr(addr, self.family, self.type, self.proto, 0))
  1070. self.connected = True
  1071. except java.lang.Exception, jlx:
  1072. raise _map_exception(jlx)
  1073. def connect(self, addr):
  1074. self._do_connect(addr)
  1075. def connect_ex(self, addr):
  1076. if not self.sock_impl:
  1077. self._do_connect(addr)
  1078. return 0
  1079. def sendto(self, data, p1, p2=None):
  1080. try:
  1081. if not p2:
  1082. flags, addr = 0, p1
  1083. else:
  1084. flags, addr = 0, p2
  1085. if not self.sock_impl:
  1086. self.sock_impl = _datagram_socket_impl()
  1087. self._config()
  1088. byte_array = java.lang.String(data).getBytes('iso-8859-1')
  1089. result = self.sock_impl.sendto(byte_array, _get_jsockaddr(addr, self.family, self.type, self.proto, 0), flags)
  1090. return result
  1091. except java.lang.Exception, jlx:
  1092. raise _map_exception(jlx)
  1093. def send(self, data, flags=None):
  1094. if not self.connected: raise error(errno.ENOTCONN, "Socket is not connected")
  1095. byte_array = java.lang.String(data).getBytes('iso-8859-1')
  1096. return self.sock_impl.send(byte_array, flags)
  1097. def recvfrom(self, num_bytes, flags=None):
  1098. """
  1099. There is some disagreement as to what the behaviour should be if
  1100. a recvfrom operation is requested on an unbound socket.
  1101. See the following links for more information
  1102. http://bugs.jython.org/issue1005
  1103. http://bugs.sun.com/view_bug.do?bug_id=6621689
  1104. """
  1105. try:
  1106. # This is the old 2.1 behaviour
  1107. #assert self.sock_impl
  1108. # This is amak's preferred interpretation
  1109. #raise error(errno.ENOTCONN, "Recvfrom on unbound udp socket meaningless operation")
  1110. # And this is the option for cpython compatibility
  1111. if not self.sock_impl:
  1112. self.sock_impl = _datagram_socket_impl()
  1113. self._config()
  1114. return self.sock_impl.recvfrom(num_bytes, flags)
  1115. except java.lang.Exception, jlx:
  1116. raise _map_exception(jlx)
  1117. def recv(self, num_bytes, flags=None):
  1118. if not self.sock_impl: raise error(errno.ENOTCONN, "Socket is not connected")
  1119. try:
  1120. return self.sock_impl.recv(num_bytes, flags)
  1121. except java.lang.Exception, jlx:
  1122. raise _map_exception(jlx)
  1123. def getsockname(self):
  1124. try:
  1125. assert self.sock_impl
  1126. host = self.sock_impl.jsocket.getLocalAddress().getHostAddress()
  1127. port = self.sock_impl.jsocket.getLocalPort()
  1128. return (host, port)
  1129. except java.lang.Exception, jlx:
  1130. raise _map_exception(jlx)
  1131. def getpeername(self):
  1132. try:
  1133. assert self.sock
  1134. host = self.sock_impl.jsocket.getInetAddress().getHostAddress()
  1135. port = self.sock_impl.jsocket.getPort()
  1136. return (host, port)
  1137. except java.lang.Exception, jlx:
  1138. raise _map_exception(jlx)
  1139. def __del__(self):
  1140. self.close()
  1141. _socketmethods = (
  1142. 'bind', 'connect', 'connect_ex', 'fileno', 'listen',
  1143. 'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
  1144. 'sendall', 'setblocking',
  1145. 'settimeout', 'gettimeout', 'shutdown', 'getchannel')
  1146. # All the method names that must be delegated to either the real socket
  1147. # object or the _closedsocket object.
  1148. _delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into",
  1149. "send", "sendto")
  1150. class _closedsocket(object):
  1151. __slots__ = []
  1152. def _dummy(*args):
  1153. raise error(errno.EBADF, 'Bad file descriptor')
  1154. # All _delegate_methods must also be initialized here.
  1155. send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
  1156. __getattr__ = _dummy
  1157. _active_sockets = set()
  1158. def _closeActiveSockets():
  1159. for socket in _active_sockets.copy():
  1160. try:
  1161. socket.close()
  1162. except error:
  1163. msg = 'Problem closing socket: %s: %r' % (socket, sys.exc_info())
  1164. print >> sys.stderr, msg
  1165. class _socketobject(object):
  1166. __doc__ = _realsocket.__doc__
  1167. __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods)
  1168. def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
  1169. if _sock is None:
  1170. _sock = _realsocket(family, type, proto)
  1171. _sock.reference_count += 1
  1172. elif isinstance(_sock, _nonblocking_api_mixin):
  1173. _sock.reference_count += 1
  1174. self._sock = _sock
  1175. for method in _delegate_methods:
  1176. meth = getattr(_sock, method, None)
  1177. if meth:
  1178. setattr(self, method, meth)
  1179. _active_sockets.add(self)
  1180. def close(self):
  1181. try:
  1182. _active_sockets.remove(self)
  1183. except KeyError:
  1184. pass
  1185. _sock = self._sock
  1186. if isinstance(_sock, _nonblocking_api_mixin):
  1187. _sock.close_lock.acquire()
  1188. try:
  1189. _sock.reference_count -=1
  1190. if not _sock.reference_count:
  1191. _sock.close()
  1192. self._sock = _closedsocket()
  1193. dummy = self._sock._dummy
  1194. for method in _delegate_methods:
  1195. setattr(self, method, dummy)
  1196. self.send = self.recv = self.sendto = self.recvfrom = \
  1197. self._sock._dummy
  1198. finally:
  1199. _sock.close_lock.release()
  1200. #close.__doc__ = _realsocket.close.__doc__
  1201. def accept(self):
  1202. sock, addr = self._so

Large files files are truncated, but you can click here to view the full file