blob: d2ac5932a28102a5be65d8a9021fe1dcee0293a9 [file] [log] [blame]
Fred Drakea6070f02000-08-16 14:14:32 +00001# Wrapper module for _socket, providing some additional facilities
2# implemented in Python.
3
4"""\
5This module provides socket operations and some related functions.
6On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
Tim Peters495ad3c2001-01-15 01:36:40 +00007On other systems, it only supports IP. Functions specific for a
Martin v. Löwisaf484d52000-09-30 11:34:30 +00008socket are available as methods of the socket object.
Fred Drakea6070f02000-08-16 14:14:32 +00009
10Functions:
11
12socket() -- create a new socket object
13fromfd() -- create a socket object from an open file descriptor [*]
14gethostname() -- return the current hostname
15gethostbyname() -- map a hostname to its IP number
16gethostbyaddr() -- map an IP number or hostname to DNS info
17getservbyname() -- map a service name and a protocol name to a port number
18getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
19ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
20htons(), htonl() -- convert 16, 32 bit int from host to network byte order
21inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
22inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
23ssl() -- secure socket layer support (only available if configured)
24
25 [*] not available on all platforms!
26
27Special objects:
28
29SocketType -- type object for socket objects
30error -- exception raised for I/O errors
31
32Integer constants:
33
34AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
35SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
36
37Many other constants may be defined; these may be used in calls to
38the setsockopt() and getsockopt() methods.
39"""
40
41from _socket import *
42
43import os, sys
44
Skip Montanaro0de65802001-02-15 22:15:14 +000045__all__ = ["getfqdn"]
46import _socket
47__all__.extend(os._get_exports_list(_socket))
Skip Montanaro0de65802001-02-15 22:15:14 +000048
Fred Drakea6070f02000-08-16 14:14:32 +000049if (sys.platform.lower().startswith("win")
Guido van Rossumd74fb6b2001-03-02 06:43:49 +000050 or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")
Guido van Rossume2ae77b2001-10-24 20:42:55 +000051 or (sys.platform=="riscos")):
Fred Drakea6070f02000-08-16 14:14:32 +000052
Guido van Rossum3f69f212001-03-22 22:12:17 +000053 _realsocketcall = _socket.socket
Fred Drakea6070f02000-08-16 14:14:32 +000054
55 def socket(family, type, proto=0):
56 return _socketobject(_realsocketcall(family, type, proto))
57
Guido van Rossum3f69f212001-03-22 22:12:17 +000058 try:
59 _realsslcall = _socket.ssl
60 except AttributeError:
61 pass # No ssl
62 else:
63 def ssl(sock, keyfile=None, certfile=None):
64 if hasattr(sock, "_sock"):
65 sock = sock._sock
Tim Petersa19a1682001-03-29 04:36:09 +000066 return _realsslcall(sock, keyfile, certfile)
Guido van Rossum3f69f212001-03-22 22:12:17 +000067
Fred Drakea6070f02000-08-16 14:14:32 +000068
69# WSA error codes
70if sys.platform.lower().startswith("win"):
71 errorTab = {}
72 errorTab[10004] = "The operation was interrupted."
73 errorTab[10009] = "A bad file handle was passed."
74 errorTab[10013] = "Permission denied."
75 errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
76 errorTab[10022] = "An invalid operation was attempted."
77 errorTab[10035] = "The socket operation would block"
78 errorTab[10036] = "A blocking operation is already in progress."
79 errorTab[10048] = "The network address is in use."
80 errorTab[10054] = "The connection has been reset."
81 errorTab[10058] = "The network has been shut down."
82 errorTab[10060] = "The operation timed out."
83 errorTab[10061] = "Connection refused."
84 errorTab[10063] = "The name is too long."
85 errorTab[10064] = "The host is down."
86 errorTab[10065] = "The host is unreachable."
Skip Montanaro64de1a42001-03-18 19:53:21 +000087 __all__.append("errorTab")
Fred Drakea6070f02000-08-16 14:14:32 +000088del os, sys
89
90
91def getfqdn(name=''):
92 """Get fully qualified domain name from name.
93
94 An empty argument is interpreted as meaning the local host.
95
96 First the hostname returned by gethostbyaddr() is checked, then
97 possibly existing aliases. In case no FQDN is available, hostname
98 is returned.
99 """
100 name = name.strip()
Peter Schneider-Kamp2d2785a2000-08-16 20:30:21 +0000101 if not name or name == '0.0.0.0':
Fred Drakea6070f02000-08-16 14:14:32 +0000102 name = gethostname()
103 try:
104 hostname, aliases, ipaddrs = gethostbyaddr(name)
105 except error:
106 pass
107 else:
108 aliases.insert(0, hostname)
109 for name in aliases:
110 if '.' in name:
111 break
112 else:
113 name = hostname
114 return name
115
116
117#
118# These classes are used by the socket() defined on Windows and BeOS
119# platforms to provide a best-effort implementation of the cleanup
120# semantics needed when sockets can't be dup()ed.
121#
122# These are not actually used on other platforms.
123#
124
Guido van Rossume5e50592001-08-18 01:23:20 +0000125_socketmethods = (
126 'bind', 'connect', 'connect_ex', 'fileno', 'listen',
127 'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
Guido van Rossumb2c763f2001-10-29 07:13:53 +0000128 'recv', 'recvfrom', 'send', 'sendall', 'sendto', 'setblocking', 'shutdown')
Guido van Rossume5e50592001-08-18 01:23:20 +0000129
Fred Drakea6070f02000-08-16 14:14:32 +0000130class _socketobject:
131
Guido van Rossum99d2fbb2001-12-18 22:22:25 +0000132 class _closedsocket:
133 def __getattr__(self, name):
134 raise error(9, 'Bad file descriptor')
135
Fred Drakea6070f02000-08-16 14:14:32 +0000136 def __init__(self, sock):
137 self._sock = sock
138
139 def close(self):
Guido van Rossum99d2fbb2001-12-18 22:22:25 +0000140 # Avoid referencing globals here
141 self._sock = self.__class__._closedsocket()
Fred Drakea6070f02000-08-16 14:14:32 +0000142
143 def __del__(self):
144 self.close()
145
146 def accept(self):
147 sock, addr = self._sock.accept()
148 return _socketobject(sock), addr
149
150 def dup(self):
151 return _socketobject(self._sock)
152
153 def makefile(self, mode='r', bufsize=-1):
154 return _fileobject(self._sock, mode, bufsize)
155
Guido van Rossume5e50592001-08-18 01:23:20 +0000156 _s = "def %s(self, *args): return self._sock.%s(*args)\n\n"
157 for _m in _socketmethods:
Fred Drakea6070f02000-08-16 14:14:32 +0000158 exec _s % (_m, _m)
159
160
161class _fileobject:
162
163 def __init__(self, sock, mode, bufsize):
164 self._sock = sock
165 self._mode = mode
166 if bufsize < 0:
167 bufsize = 512
168 self._rbufsize = max(1, bufsize)
169 self._wbufsize = bufsize
170 self._wbuf = self._rbuf = ""
171
172 def close(self):
173 try:
174 if self._sock:
175 self.flush()
176 finally:
177 self._sock = 0
178
179 def __del__(self):
180 self.close()
181
182 def flush(self):
183 if self._wbuf:
184 self._sock.send(self._wbuf)
185 self._wbuf = ""
186
187 def fileno(self):
188 return self._sock.fileno()
189
190 def write(self, data):
191 self._wbuf = self._wbuf + data
192 if self._wbufsize == 1:
193 if '\n' in data:
194 self.flush()
195 else:
196 if len(self._wbuf) >= self._wbufsize:
197 self.flush()
198
199 def writelines(self, list):
200 filter(self._sock.send, list)
201 self.flush()
202
203 def read(self, n=-1):
204 if n >= 0:
205 k = len(self._rbuf)
206 if n <= k:
207 data = self._rbuf[:n]
208 self._rbuf = self._rbuf[n:]
209 return data
210 n = n - k
211 L = [self._rbuf]
212 self._rbuf = ""
213 while n > 0:
214 new = self._sock.recv(max(n, self._rbufsize))
215 if not new: break
216 k = len(new)
217 if k > n:
218 L.append(new[:n])
219 self._rbuf = new[n:]
220 break
221 L.append(new)
222 n = n - k
223 return "".join(L)
224 k = max(512, self._rbufsize)
225 L = [self._rbuf]
226 self._rbuf = ""
227 while 1:
228 new = self._sock.recv(k)
229 if not new: break
230 L.append(new)
231 k = min(k*2, 1024**2)
232 return "".join(L)
233
234 def readline(self, limit=-1):
235 data = ""
236 i = self._rbuf.find('\n')
237 while i < 0 and not (0 < limit <= len(self._rbuf)):
238 new = self._sock.recv(self._rbufsize)
239 if not new: break
240 i = new.find('\n')
241 if i >= 0: i = i + len(self._rbuf)
242 self._rbuf = self._rbuf + new
243 if i < 0: i = len(self._rbuf)
244 else: i = i+1
245 if 0 <= limit < len(self._rbuf): i = limit
246 data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
247 return data
248
Martin v. Löwis6df27f82000-09-19 11:25:58 +0000249 def readlines(self, sizehint = 0):
250 total = 0
Fred Drakea6070f02000-08-16 14:14:32 +0000251 list = []
252 while 1:
253 line = self.readline()
254 if not line: break
255 list.append(line)
Martin v. Löwis6df27f82000-09-19 11:25:58 +0000256 total += len(line)
257 if sizehint and total >= sizehint:
258 break
Fred Drakea6070f02000-08-16 14:14:32 +0000259 return list