Tachyon /Users/simon/.local/share/uv/python/cpython-3.15.0-macos-aarch64-none/lib/python3.15/socket.py
27
Self Samples
31
Cumulative
4
Lines Hit
0.11%
% of Total
14
Max Self
14
Max Total
Intensity:
Cold Hot
Self Time
Total Time
Show All
Hot Only
Heat
Specialization
Line
Self
Total
Code
1
# Wrapper module for _socket, providing some additional facilities
2
# implemented in Python.
3
4
"""\
5
This module provides socket operations and some related functions.
6
On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
7
On other systems, it only supports IP. Functions specific for a
8
socket are available as methods of the socket object.
9
10
Functions:
11
12
socket() -- create a new socket object
13
socketpair() -- create a pair of new socket objects [*]
14
fromfd() -- create a socket object from an open file descriptor [*]
15
send_fds() -- Send file descriptor to the socket.
16
recv_fds() -- Receive file descriptors from the socket.
17
fromshare() -- create a socket object from data received from socket.share() [*]
18
gethostname() -- return the current hostname
19
gethostbyname() -- map a hostname to its IP number
20
gethostbyaddr() -- map an IP number or hostname to DNS info
21
getservbyname() -- map a service name and a protocol name to a port number
22
getprotobyname() -- map a protocol name (e.g. 'tcp') to a number
23
ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
24
htons(), htonl() -- convert 16, 32 bit int from host to network byte order
25
inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
26
inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
27
socket.getdefaulttimeout() -- get the default timeout value
28
socket.setdefaulttimeout() -- set the default timeout value
29
create_connection() -- connects to an address, with an optional timeout and
30
optional source address.
31
create_server() -- create a TCP socket and bind it to a specified address.
32
33
[*] not available on all platforms!
34
35
Special objects:
36
37
SocketType -- type object for socket objects
38
error -- exception raised for I/O errors
39
has_ipv6 -- boolean value indicating if IPv6 is supported
40
41
IntEnum constants:
42
43
AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
44
SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
45
46
Integer constants:
47
48
Many other constants may be defined; these may be used in calls to
49
the setsockopt() and getsockopt() methods.
50
"""
51
52
import _socket
53
from _socket import *
54
55
import io
56
import os
57
import sys
58
from enum import IntEnum, IntFlag
59
from functools import partial
60
61
try:
62
import errno
63
except ImportError:
64
errno = None
65
EBADF = getattr(errno, 'EBADF', 9)
66
EAGAIN = getattr(errno, 'EAGAIN', 11)
67
EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11)
68
69
__all__ = ["fromfd", "getfqdn", "create_connection", "create_server",
70
"has_dualstack_ipv6", "AddressFamily", "SocketKind"]
71
__all__.extend(os._get_exports_list(_socket))
72
73
# Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for
74
# nicer string representations.
75
# Note that _socket only knows about the integer values. The public interface
76
# in this module understands the enums and translates them back from integers
77
# where needed (e.g. .family property of a socket object).
78
79
IntEnum._convert_(
80
'AddressFamily',
81
__name__,
82
lambda C: C.isupper() and C.startswith('AF_'))
83
84
IntEnum._convert_(
85
'SocketKind',
86
__name__,
87
lambda C: C.isupper() and C.startswith('SOCK_'))
88
89
IntFlag._convert_(
90
'MsgFlag',
91
__name__,
92
lambda C: C.isupper() and C.startswith('MSG_'))
93
94
IntFlag._convert_(
95
'AddressInfo',
96
__name__,
97
lambda C: C.isupper() and C.startswith('AI_'))
98
99
_LOCALHOST = '127.0.0.1'
100
_LOCALHOST_V6 = '::1'
101
102
103
def _intenum_converter(value, enum_klass):
104
"""Convert a numeric family value to an IntEnum member.
105
106
If it's not a known member, return the numeric value itself.
107
"""
108
try:
109
return enum_klass(value)
110
except ValueError:
111
return value
112
113
114
# WSA error codes
115
if sys.platform.lower().startswith("win"):
116
errorTab = {
117
6: "Specified event object handle is invalid.",
118
8: "Insufficient memory available.",
119
87: "One or more parameters are invalid.",
120
995: "Overlapped operation aborted.",
121
996: "Overlapped I/O event object not in signaled state.",
122
997: "Overlapped operation will complete later.",
123
10004: "The operation was interrupted.",
124
10009: "A bad file handle was passed.",
125
10013: "Permission denied.",
126
10014: "An invalid pointer was passed.",
127
10022: "An invalid operation was attempted.",
128
10024: "Too many open files.",
129
10035: "The socket operation would block.",
130
10036: "A blocking operation is already in progress.",
131
10037: "Operation already in progress.",
132
10038: "Socket operation on nonsocket.",
133
10039: "Destination address required.",
134
10040: "Message too long.",
135
10041: "Protocol wrong type for socket.",
136
10042: "Bad protocol option.",
137
10043: "Protocol not supported.",
138
10044: "Socket type not supported.",
139
10045: "Operation not supported.",
140
10046: "Protocol family not supported.",
141
10047: "Address family not supported by protocol family.",
142
10048: "The network address is in use.",
143
10049: "Cannot assign requested address.",
144
10050: "Network is down.",
145
10051: "Network is unreachable.",
146
10052: "Network dropped connection on reset.",
147
10053: "Software caused connection abort.",
148
10054: "The connection has been reset.",
149
10055: "No buffer space available.",
150
10056: "Socket is already connected.",
151
10057: "Socket is not connected.",
152
10058: "The network has been shut down.",
153
10059: "Too many references.",
154
10060: "The operation timed out.",
155
10061: "Connection refused.",
156
10062: "Cannot translate name.",
157
10063: "The name is too long.",
158
10064: "The host is down.",
159
10065: "The host is unreachable.",
160
10066: "Directory not empty.",
161
10067: "Too many processes.",
162
10068: "User quota exceeded.",
163
10069: "Disk quota exceeded.",
164
10070: "Stale file handle reference.",
165
10071: "Item is remote.",
166
10091: "Network subsystem is unavailable.",
167
10092: "Winsock.dll version out of range.",
168
10093: "Successful WSAStartup not yet performed.",
169
10101: "Graceful shutdown in progress.",
170
10102: "No more results from WSALookupServiceNext.",
171
10103: "Call has been canceled.",
172
10104: "Procedure call table is invalid.",
173
10105: "Service provider is invalid.",
174
10106: "Service provider failed to initialize.",
175
10107: "System call failure.",
176
10108: "Service not found.",
177
10109: "Class type not found.",
178
10110: "No more results from WSALookupServiceNext.",
179
10111: "Call was canceled.",
180
10112: "Database query was refused.",
181
11001: "Host not found.",
182
11002: "Nonauthoritative host not found.",
183
11003: "This is a nonrecoverable error.",
184
11004: "Valid name, no data record of requested type.",
185
11005: "QoS receivers.",
186
11006: "QoS senders.",
187
11007: "No QoS senders.",
188
11008: "QoS no receivers.",
189
11009: "QoS request confirmed.",
190
11010: "QoS admission error.",
191
11011: "QoS policy failure.",
192
11012: "QoS bad style.",
193
11013: "QoS bad object.",
194
11014: "QoS traffic control error.",
195
11015: "QoS generic error.",
196
11016: "QoS service type error.",
197
11017: "QoS flowspec error.",
198
11018: "Invalid QoS provider buffer.",
199
11019: "Invalid QoS filter style.",
200
11020: "Invalid QoS filter type.",
201
11021: "Incorrect QoS filter count.",
202
11022: "Invalid QoS object length.",
203
11023: "Incorrect QoS flow count.",
204
11024: "Unrecognized QoS object.",
205
11025: "Invalid QoS policy object.",
206
11026: "Invalid QoS flow descriptor.",
207
11027: "Invalid QoS provider-specific flowspec.",
208
11028: "Invalid QoS provider-specific filterspec.",
209
11029: "Invalid QoS shape discard mode object.",
210
11030: "Invalid QoS shaping rate object.",
211
11031: "Reserved policy QoS element type."
212
}
213
__all__.append("errorTab")
214
215
216
class _GiveupOnSendfile(Exception): pass
217
218
219
class socket(_socket.socket):
220
221
"""A subclass of _socket.socket adding the makefile() method."""
222
223
__slots__ = ["__weakref__", "_io_refs", "_closed"]
224
225
def __init__(self, family=-1, type=-1, proto=-1, fileno=None):
226
# For user code address family and type values are IntEnum members, but
227
# for the underlying _socket.socket they're just integers. The
228
# constructor of _socket.socket converts the given argument to an
229
# integer automatically.
230
if fileno is None:
231
if family == -1:
232
family = AF_INET
233
if type == -1:
234
type = SOCK_STREAM
235
if proto == -1:
236
proto = 0
237
_socket.socket.__init__(self, family, type, proto, fileno)
238
self._io_refs = 0
239
self._closed = False
240
241
def __enter__(self):
242
return self
243
244
def __exit__(self, *args):
245
if not self._closed:
246
self.close()
247
248
def __repr__(self):
249
"""Wrap __repr__() to reveal the real class name and socket
250
address(es).
251
"""
252
closed = getattr(self, '_closed', False)
253
s = "<%s.%s%s fd=%i, family=%s, type=%s, proto=%i" \
254
% (self.__class__.__module__,
255
self.__class__.__qualname__,
256
" [closed]" if closed else "",
257
self.fileno(),
258
self.family,
259
self.type,
260
self.proto)
261
if not closed:
262
# getsockname and getpeername may not be available on WASI.
263
try:
264
laddr = self.getsockname()
265
if laddr:
266
s += ", laddr=%s" % str(laddr)
267
except (error, AttributeError):
268
pass
269
try:
270
raddr = self.getpeername()
271
if raddr:
272
s += ", raddr=%s" % str(raddr)
273
except (error, AttributeError):
274
pass
275
s += '>'
276
return s
277
278
def __getstate__(self):
279
raise TypeError(f"cannot pickle {self.__class__.__name__!r} object")
280
281
def dup(self):
282
"""dup() -> socket object
283
284
Duplicate the socket. Return a new socket object connected to the same
285
system resource. The new socket is non-inheritable.
286
"""
287
fd = dup(self.fileno())
288
sock = self.__class__(self.family, self.type, self.proto, fileno=fd)
289
sock.settimeout(self.gettimeout())
290
return sock
291
292
def accept(self):
293
"""accept() -> (socket object, address info)
294
295
Wait for an incoming connection. Return a new socket
296
representing the connection, and the address of the client.
297
For IP sockets, the address info is a pair (hostaddr, port).
298
"""
299
4
4
fd, addr = self._accept()
300
14
14
sock = socket(self.family, self.type, self.proto, fileno=fd)
301
# Issue #7995: if no default timeout is set and the listening
302
# socket had a (non-zero) timeout, force the new socket in blocking
303
# mode to override platform-specific socket flags inheritance.
304
if getdefaulttimeout() is None and self.gettimeout():
305
sock.setblocking(True)
306
return sock, addr
307
308
def makefile(self, mode="r", buffering=None, *,
309
encoding=None, errors=None, newline=None):
310
"""makefile(...) -> an I/O stream connected to the socket
311
312
The arguments are as for io.open() after the filename, except the only
313
supported mode values are 'r' (default), 'w', 'b', or a combination of
314
those.
315
"""
316
# XXX refactor to share code?
317
if not set(mode) <= {"r", "w", "b"}:
318
raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
319
writing = "w" in mode
320
reading = "r" in mode or not writing
321
assert reading or writing
322
binary = "b" in mode
323
rawmode = ""
324
if reading:
325
rawmode += "r"
326
if writing:
327
rawmode += "w"
328
raw = SocketIO(self, rawmode)
329
self._io_refs += 1
330
if buffering is None:
331
buffering = -1
332
if buffering < 0:
333
buffering = io.DEFAULT_BUFFER_SIZE
334
if buffering == 0:
335
if not binary:
336
raise ValueError("unbuffered streams must be binary")
337
return raw
338
if reading and writing:
339
buffer = io.BufferedRWPair(raw, raw, buffering)
340
elif reading:
341
buffer = io.BufferedReader(raw, buffering)
342
else:
343
assert writing
344
buffer = io.BufferedWriter(raw, buffering)
345
if binary:
346
return buffer
347
encoding = io.text_encoding(encoding)
348
text = io.TextIOWrapper(buffer, encoding, errors, newline)
349
text.mode = mode
350
return text
351
352
def _sendfile_zerocopy(self, zerocopy_func, giveup_exc_type, file,
353
offset=0, count=None):
354
"""
355
Send a file using a zero-copy function.
356
"""
357
import selectors
358
359
self._check_sendfile_params(file, offset, count)
360
sockno = self.fileno()
361
try:
362
fileno = file.fileno()
363
except (AttributeError, io.UnsupportedOperation) as err:
364
raise giveup_exc_type(err) # not a regular file
365
try:
366
fsize = os.fstat(fileno).st_size
367
except OSError as err:
368
raise giveup_exc_type(err) # not a regular file
369
if not fsize:
370
return 0 # empty file
371
# Truncate to 1GiB to avoid OverflowError, see bpo-38319.
372
blocksize = min(count or fsize, 2 ** 30)
373
timeout = self.gettimeout()
374
if timeout == 0:
375
raise ValueError("non-blocking sockets are not supported")
376
# poll/select have the advantage of not requiring any
377
# extra file descriptor, contrarily to epoll/kqueue
378
# (also, they require a single syscall).
379
if hasattr(selectors, 'PollSelector'):
380
selector = selectors.PollSelector()
381
else:
382
selector = selectors.SelectSelector()
383
selector.register(sockno, selectors.EVENT_WRITE)
384
385
total_sent = 0
386
# localize variable access to minimize overhead
387
selector_select = selector.select
388
try:
389
while True:
390
if timeout and not selector_select(timeout):
391
raise TimeoutError('timed out')
392
if count:
393
blocksize = min(count - total_sent, blocksize)
394
if blocksize <= 0:
395
break
396
try:
397
sent = zerocopy_func(fileno, offset, blocksize)
398
except BlockingIOError:
399
if not timeout:
400
# Block until the socket is ready to send some
401
# data; avoids hogging CPU resources.
402
selector_select()
403
continue
404
except OSError as err:
405
if total_sent == 0:
406
# We can get here for different reasons, the main
407
# one being 'file' is not a regular mmap(2)-like
408
# file, in which case we'll fall back on using
409
# plain send().
410
raise giveup_exc_type(err)
411
raise err from None
412
else:
413
if sent == 0:
414
break # EOF
415
offset += sent
416
total_sent += sent
417
return total_sent
418
finally:
419
if total_sent > 0 and hasattr(file, 'seek'):
420
file.seek(offset)
421
422
if hasattr(os, 'sendfile'):
423
def _sendfile_use_sendfile(self, file, offset=0, count=None):
424
return self._sendfile_zerocopy(
425
partial(os.sendfile, self.fileno()),
426
_GiveupOnSendfile,
427
file, offset, count,
428
)
429
else:
430
def _sendfile_use_sendfile(self, file, offset=0, count=None):
431
raise _GiveupOnSendfile(
432
"os.sendfile() not available on this platform")
433
434
def _sendfile_use_send(self, file, offset=0, count=None):
435
self._check_sendfile_params(file, offset, count)
436
if self.gettimeout() == 0:
437
raise ValueError("non-blocking sockets are not supported")
438
if offset:
439
file.seek(offset)
440
blocksize = min(count, 8192) if count else 8192
441
total_sent = 0
442
# localize variable access to minimize overhead
443
file_read = file.read
444
sock_send = self.send
445
try:
446
while True:
447
if count:
448
blocksize = min(count - total_sent, blocksize)
449
if blocksize <= 0:
450
break
451
data = memoryview(file_read(blocksize))
452
if not data:
453
break # EOF
454
while True:
455
try:
456
sent = sock_send(data)
457
except BlockingIOError:
458
continue
459
else:
460
total_sent += sent
461
if sent < len(data):
462
data = data[sent:]
463
else:
464
break
465
return total_sent
466
finally:
467
if total_sent > 0 and hasattr(file, 'seek'):
468
file.seek(offset + total_sent)
469
470
def _check_sendfile_params(self, file, offset, count):
471
if 'b' not in getattr(file, 'mode', 'b'):
472
raise ValueError("file should be opened in binary mode")
473
if not self.type & SOCK_STREAM:
474
raise ValueError("only SOCK_STREAM type sockets are supported")
475
if count is not None:
476
if not isinstance(count, int):
477
raise TypeError(
478
"count must be a positive integer (got {!r})".format(count))
479
if count <= 0:
480
raise ValueError(
481
"count must be a positive integer (got {!r})".format(count))
482
483
def sendfile(self, file, offset=0, count=None):
484
"""sendfile(file[, offset[, count]]) -> sent
485
486
Send a file until EOF is reached by using high-performance
487
os.sendfile() and return the total number of bytes which
488
were sent.
489
*file* must be a regular file object opened in binary mode.
490
If os.sendfile() is not available (e.g. Windows) or file is
491
not a regular file socket.send() will be used instead.
492
*offset* tells from where to start reading the file.
493
If specified, *count* is the total number of bytes to transmit
494
as opposed to sending the file until EOF is reached.
495
File position is updated on return or also in case of error in
496
which case file.tell() can be used to figure out the number of
497
bytes which were sent.
498
The socket must be of SOCK_STREAM type.
499
Non-blocking sockets are not supported.
500
"""
501
try:
502
return self._sendfile_use_sendfile(file, offset, count)
503
except _GiveupOnSendfile:
504
return self._sendfile_use_send(file, offset, count)
505
506
def _decref_socketios(self):
507
if self._io_refs > 0:
508
self._io_refs -= 1
509
if self._closed:
510
self.close()
511
512
def _real_close(self, _ss=_socket.socket):
513
# This function should not reference any globals. See issue #808164.
514
4
4
_ss.close(self)
515
516
def close(self):
517
# This function should not reference any globals. See issue #808164.
518
self._closed = True
519
if self._io_refs <= 0:
520
5
9
self._real_close()
521
522
def detach(self):
523
"""detach() -> file descriptor
524
525
Close the socket object without closing the underlying file descriptor.
526
The object cannot be used after this call, but the file descriptor
527
can be reused for other purposes. The file descriptor is returned.
528
"""
529
self._closed = True
530
return super().detach()
531
532
@property
533
def family(self):
534
"""Read-only access to the address family for this socket.
535
"""
536
return _intenum_converter(super().family, AddressFamily)
537
538
@property
539
def type(self):
540
"""Read-only access to the socket type.
541
"""
542
return _intenum_converter(super().type, SocketKind)
543
544
if os.name == 'nt':
545
def get_inheritable(self):
546
return os.get_handle_inheritable(self.fileno())
547
def set_inheritable(self, inheritable):
548
os.set_handle_inheritable(self.fileno(), inheritable)
549
else:
550
def get_inheritable(self):
551
return os.get_inheritable(self.fileno())
552
def set_inheritable(self, inheritable):
553
os.set_inheritable(self.fileno(), inheritable)
554
get_inheritable.__doc__ = "Get the inheritable flag of the socket"
555
set_inheritable.__doc__ = "Set the inheritable flag of the socket"
556
557
def fromfd(fd, family, type, proto=0):
558
""" fromfd(fd, family, type[, proto]) -> socket object
559
560
Create a socket object from a duplicate of the given file
561
descriptor. The remaining arguments are the same as for socket().
562
"""
563
nfd = dup(fd)
564
return socket(family, type, proto, nfd)
565
566
if hasattr(_socket.socket, "sendmsg"):
567
def send_fds(sock, buffers, fds, flags=0, address=None):
568
""" send_fds(sock, buffers, fds[, flags[, address]]) -> integer
569
570
Send the list of file descriptors fds over an AF_UNIX socket.
571
"""
572
import array
573
574
return sock.sendmsg(buffers, [(_socket.SOL_SOCKET,
575
_socket.SCM_RIGHTS, array.array("i", fds))])
576
__all__.append("send_fds")
577
578
if hasattr(_socket.socket, "recvmsg"):
579
def recv_fds(sock, bufsize, maxfds, flags=0):
580
""" recv_fds(sock, bufsize, maxfds[, flags]) -> (data, list of file
581
descriptors, msg_flags, address)
582
583
Receive up to maxfds file descriptors returning the message
584
data and a list containing the descriptors.
585
"""
586
import array
587
588
# Array of ints
589
fds = array.array("i")
590
msg, ancdata, flags, addr = sock.recvmsg(bufsize,
591
_socket.CMSG_LEN(maxfds * fds.itemsize))
592
for cmsg_level, cmsg_type, cmsg_data in ancdata:
593
if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS):
594
fds.frombytes(cmsg_data[:
595
len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
596
597
return msg, list(fds), flags, addr
598
__all__.append("recv_fds")
599
600
if hasattr(_socket.socket, "share"):
601
def fromshare(info):
602
""" fromshare(info) -> socket object
603
604
Create a socket object from the bytes object returned by
605
socket.share(pid).
606
"""
607
return socket(0, 0, 0, info)
608
__all__.append("fromshare")
609
610
# Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
611
# This is used if _socket doesn't natively provide socketpair. It's
612
# always defined so that it can be patched in for testing purposes.
613
def _fallback_socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
614
if family == AF_INET:
615
host = _LOCALHOST
616
elif family == AF_INET6:
617
host = _LOCALHOST_V6
618
else:
619
raise ValueError("Only AF_INET and AF_INET6 socket address families "
620
"are supported")
621
if type != SOCK_STREAM:
622
raise ValueError("Only SOCK_STREAM socket type is supported")
623
if proto != 0:
624
raise ValueError("Only protocol zero is supported")
625
626
# We create a connected TCP socket. Note the trick with
627
# setblocking(False) that prevents us from having to create a thread.
628
lsock = socket(family, type, proto)
629
try:
630
lsock.bind((host, 0))
631
lsock.listen()
632
# On IPv6, ignore flow_info and scope_id
633
addr, port = lsock.getsockname()[:2]
634
csock = socket(family, type, proto)
635
try:
636
csock.setblocking(False)
637
try:
638
csock.connect((addr, port))
639
except (BlockingIOError, InterruptedError):
640
pass
641
csock.setblocking(True)
642
ssock, _ = lsock.accept()
643
except:
644
csock.close()
645
raise
646
finally:
647
lsock.close()
648
649
# Authenticating avoids using a connection from something else
650
# able to connect to {host}:{port} instead of us.
651
# We expect only AF_INET and AF_INET6 families.
652
#
653
# Note that we skip this on WASI because on that platorm the client socket
654
# may not have finished connecting by the time we've reached this point (gh-146139).
655
if sys.platform != "wasi":
656
try:
657
if (
658
ssock.getsockname() != csock.getpeername()
659
or csock.getsockname() != ssock.getpeername()
660
):
661
raise ConnectionError("Unexpected peer connection")
662
except:
663
# getsockname() and getpeername() can fail
664
# if either socket isn't connected.
665
ssock.close()
666
csock.close()
667
raise
668
669
return (ssock, csock)
670
671
if hasattr(_socket, "socketpair"):
672
def socketpair(family=None, type=SOCK_STREAM, proto=0):
673
if family is None:
674
try:
675
family = AF_UNIX
676
except NameError:
677
family = AF_INET
678
a, b = _socket.socketpair(family, type, proto)
679
a = socket(family, type, proto, a.detach())
680
b = socket(family, type, proto, b.detach())
681
return a, b
682
683
else:
684
socketpair = _fallback_socketpair
685
__all__.append("socketpair")
686
687
socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
688
Create a pair of socket objects from the sockets returned by the platform
689
socketpair() function.
690
The arguments are the same as for socket() except the default family is AF_UNIX
691
if defined on the platform; otherwise, the default is AF_INET.
692
"""
693
694
_blocking_errnos = { EAGAIN, EWOULDBLOCK }
695
696
class SocketIO(io.RawIOBase):
697
698
"""Raw I/O implementation for stream sockets.
699
700
This class supports the makefile() method on sockets. It provides
701
the raw I/O interface on top of a socket object.
702
"""
703
704
# One might wonder why not let FileIO do the job instead. There are two
705
# main reasons why FileIO is not adapted:
706
# - it wouldn't work under Windows (where you can't used read() and
707
# write() on a socket handle)
708
# - it wouldn't work with socket timeouts (FileIO would ignore the
709
# timeout and consider the socket non-blocking)
710
711
# XXX More docs
712
713
def __init__(self, sock, mode):
714
if mode not in ("r", "w", "rw", "rb", "wb", "rwb"):
715
raise ValueError("invalid mode: %r" % mode)
716
io.RawIOBase.__init__(self)
717
self._sock = sock
718
if "b" not in mode:
719
mode += "b"
720
self._mode = mode
721
self._reading = "r" in mode
722
self._writing = "w" in mode
723
self._timeout_occurred = False
724
725
def readinto(self, b):
726
"""Read up to len(b) bytes into the writable buffer *b* and return
727
the number of bytes read. If the socket is non-blocking and no bytes
728
are available, None is returned.
729
730
If *b* is non-empty, a 0 return value indicates that the connection
731
was shutdown at the other end.
732
"""
733
self._checkClosed()
734
self._checkReadable()
735
if self._timeout_occurred:
736
raise OSError("cannot read from timed out object")
737
try:
738
return self._sock.recv_into(b)
739
except timeout:
740
self._timeout_occurred = True
741
raise
742
except error as e:
743
if e.errno in _blocking_errnos:
744
return None
745
raise
746
747
def write(self, b):
748
"""Write the given bytes or bytearray object *b* to the socket
749
and return the number of bytes written. This can be less than
750
len(b) if not all data could be written. If the socket is
751
non-blocking and no bytes could be written None is returned.
752
"""
753
self._checkClosed()
754
self._checkWritable()
755
try:
756
return self._sock.send(b)
757
except error as e:
758
# XXX what about EINTR?
759
if e.errno in _blocking_errnos:
760
return None
761
raise
762
763
def readable(self):
764
"""True if the SocketIO is open for reading.
765
"""
766
if self.closed:
767
raise ValueError("I/O operation on closed socket.")
768
return self._reading
769
770
def writable(self):
771
"""True if the SocketIO is open for writing.
772
"""
773
if self.closed:
774
raise ValueError("I/O operation on closed socket.")
775
return self._writing
776
777
def seekable(self):
778
"""True if the SocketIO is open for seeking.
779
"""
780
if self.closed:
781
raise ValueError("I/O operation on closed socket.")
782
return super().seekable()
783
784
def fileno(self):
785
"""Return the file descriptor of the underlying socket.
786
"""
787
self._checkClosed()
788
return self._sock.fileno()
789
790
@property
791
def name(self):
792
if not self.closed:
793
return self.fileno()
794
else:
795
return -1
796
797
@property
798
def mode(self):
799
return self._mode
800
801
def close(self):
802
"""Close the SocketIO object. This doesn't close the underlying
803
socket, except if all references to it have disappeared.
804
"""
805
if self.closed:
806
return
807
io.RawIOBase.close(self)
808
self._sock._decref_socketios()
809
self._sock = None
810
811
812
def getfqdn(name=''):
813
"""Get fully qualified domain name from name.
814
815
An empty argument is interpreted as meaning the local host.
816
817
First the hostname returned by gethostbyaddr() is checked, then
818
possibly existing aliases. In case no FQDN is available and `name`
819
was given, it is returned unchanged. If `name` was empty, '0.0.0.0' or '::',
820
hostname from gethostname() is returned.
821
"""
822
name = name.strip()
823
if not name or name in ('0.0.0.0', '::'):
824
name = gethostname()
825
try:
826
hostname, aliases, ipaddrs = gethostbyaddr(name)
827
except error:
828
pass
829
else:
830
aliases.insert(0, hostname)
831
for name in aliases:
832
if '.' in name:
833
break
834
else:
835
name = hostname
836
return name
837
838
839
_GLOBAL_DEFAULT_TIMEOUT = object()
840
841
def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
842
source_address=None, *, all_errors=False):
843
"""Connect to *address* and return the socket object.
844
845
Convenience function. Connect to *address* (a 2-tuple ``(host,
846
port)``) and return the socket object. Passing the optional
847
*timeout* parameter will set the timeout on the socket instance
848
before attempting to connect. If no *timeout* is supplied, the
849
global default timeout setting returned by :func:`getdefaulttimeout`
850
is used. If *source_address* is set it must be a tuple of (host, port)
851
for the socket to bind as a source address before making the connection.
852
A host of '' or port 0 tells the OS to use the default. When a connection
853
cannot be created, raises the last error if *all_errors* is False,
854
and an ExceptionGroup of all errors if *all_errors* is True.
855
"""
856
857
host, port = address
858
exceptions = []
859
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
860
af, socktype, proto, canonname, sa = res
861
sock = None
862
try:
863
sock = socket(af, socktype, proto)
864
if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
865
sock.settimeout(timeout)
866
if source_address:
867
sock.bind(source_address)
868
sock.connect(sa)
869
# Break explicitly a reference cycle
870
exceptions.clear()
871
return sock
872
873
except error as exc:
874
if not all_errors:
875
exceptions.clear() # raise only the last error
876
exceptions.append(exc)
877
if sock is not None:
878
sock.close()
879
880
if len(exceptions):
881
try:
882
if not all_errors:
883
raise exceptions[0]
884
raise ExceptionGroup("create_connection failed", exceptions)
885
finally:
886
# Break explicitly a reference cycle
887
exceptions.clear()
888
else:
889
raise error("getaddrinfo returns an empty list")
890
891
892
def has_dualstack_ipv6():
893
"""Return True if the platform supports creating a SOCK_STREAM socket
894
which can handle both AF_INET and AF_INET6 (IPv4 / IPv6) connections.
895
"""
896
if not has_ipv6 \
897
or not hasattr(_socket, 'IPPROTO_IPV6') \
898
or not hasattr(_socket, 'IPV6_V6ONLY'):
899
return False
900
try:
901
with socket(AF_INET6, SOCK_STREAM) as sock:
902
sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0)
903
# On some platforms (e.g. DragonFly BSD) setting IPV6_V6ONLY to 0
904
# silently has no effect, so check that it was actually cleared.
905
return sock.getsockopt(IPPROTO_IPV6, IPV6_V6ONLY) == 0
906
except error:
907
return False
908
909
910
def create_server(address, *, family=AF_INET, backlog=None, reuse_port=False,
911
dualstack_ipv6=False):
912
"""Convenience function which creates a SOCK_STREAM type socket
913
bound to *address* (a 2-tuple (host, port)) and return the socket
914
object.
915
916
*family* should be either AF_INET or AF_INET6.
917
*backlog* is the queue size passed to socket.listen().
918
*reuse_port* dictates whether to use the SO_REUSEPORT socket option.
919
*dualstack_ipv6*: if true and the platform supports it, it will
920
create an AF_INET6 socket able to accept both IPv4 or IPv6
921
connections. When false it will explicitly disable this option on
922
platforms that enable it by default (e.g. Linux).
923
924
>>> with create_server(('', 8000)) as server:
925
... while True:
926
... conn, addr = server.accept()
927
... # handle new connection
928
"""
929
if reuse_port and not hasattr(_socket, "SO_REUSEPORT"):
930
raise ValueError("SO_REUSEPORT not supported on this platform")
931
if dualstack_ipv6:
932
if not has_dualstack_ipv6():
933
raise ValueError("dualstack_ipv6 not supported on this platform")
934
if family != AF_INET6:
935
raise ValueError("dualstack_ipv6 requires AF_INET6 family")
936
sock = socket(family, SOCK_STREAM)
937
try:
938
# Note about Windows. We don't set SO_REUSEADDR because:
939
# 1) It's unnecessary: bind() will succeed even in case of a
940
# previous closed socket on the same address and still in
941
# TIME_WAIT state.
942
# 2) If set, another socket is free to bind() on the same
943
# address, effectively preventing this one from accepting
944
# connections. Also, it may set the process in a state where
945
# it'll no longer respond to any signals or graceful kills.
946
# See: https://learn.microsoft.com/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
947
if os.name not in ('nt', 'cygwin') and \
948
hasattr(_socket, 'SO_REUSEADDR'):
949
try:
950
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
951
except error:
952
# Fail later on bind(), for platforms which may not
953
# support this option.
954
pass
955
# Since Linux 6.12.9, SO_REUSEPORT is not allowed
956
# on other address families than AF_INET/AF_INET6.
957
if reuse_port and family in (AF_INET, AF_INET6):
958
sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
959
if has_ipv6 and family == AF_INET6:
960
if dualstack_ipv6:
961
sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0)
962
elif hasattr(_socket, "IPV6_V6ONLY") and \
963
hasattr(_socket, "IPPROTO_IPV6"):
964
sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 1)
965
try:
966
sock.bind(address)
967
except error as err:
968
msg = '%s (while attempting to bind on address %r)' % \
969
(err.strerror, address)
970
raise error(err.errno, msg) from None
971
if backlog is None:
972
sock.listen()
973
else:
974
sock.listen(backlog)
975
return sock
976
except error:
977
sock.close()
978
raise
979
980
981
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
982
"""Resolve host and port into list of address info entries.
983
984
Translate the host/port argument into a sequence of 5-tuples that contain
985
all the necessary arguments for creating a socket connected to that service.
986
host is a domain name, a string representation of an IPv4/v6 address or
987
None. port is a string service name such as 'http', a numeric port number or
988
None. By passing None as the value of host and port, you can pass NULL to
989
the underlying C API.
990
991
The family, type and proto arguments can be optionally specified in order to
992
narrow the list of addresses returned. Passing zero as a value for each of
993
these arguments selects the full range of results.
994
"""
995
# We override this function since we want to translate the numeric family
996
# and socket type values to enum constants.
997
addrlist = []
998
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
999
af, socktype, proto, canonname, sa = res
1000
addrlist.append((_intenum_converter(af, AddressFamily),
1001
_intenum_converter(socktype, SocketKind),
1002
proto, canonname, sa))
1003
return addrlist