This commit was manufactured by cvs2svn to create tag 'r234c1'.
[python/dscho.git] / Lib / socket.py
blob8e30ce0a34a20e3d025941ce283c73de8828ae65
1 # Wrapper module for _socket, providing some additional facilities
2 # implemented in Python.
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.
10 Functions:
12 socket() -- create a new socket object
13 fromfd() -- create a socket object from an open file descriptor [*]
14 gethostname() -- return the current hostname
15 gethostbyname() -- map a hostname to its IP number
16 gethostbyaddr() -- map an IP number or hostname to DNS info
17 getservbyname() -- map a service name and a protocol name to a port number
18 getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
19 ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
20 htons(), htonl() -- convert 16, 32 bit int from host to network byte order
21 inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
22 inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
23 ssl() -- secure socket layer support (only available if configured)
24 socket.getdefaulttimeout() -- get the default timeout value
25 socket.setdefaulttimeout() -- set the default timeout value
27 [*] not available on all platforms!
29 Special objects:
31 SocketType -- type object for socket objects
32 error -- exception raised for I/O errors
33 has_ipv6 -- boolean value indicating if IPv6 is supported
35 Integer constants:
37 AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
38 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
40 Many other constants may be defined; these may be used in calls to
41 the setsockopt() and getsockopt() methods.
42 """
44 import _socket
45 from _socket import *
47 _have_ssl = False
48 try:
49 import _ssl
50 from _ssl import *
51 _have_ssl = True
52 except ImportError:
53 pass
55 import os, sys
57 try:
58 from errno import EBADF
59 except ImportError:
60 EBADF = 9
62 __all__ = ["getfqdn"]
63 __all__.extend(os._get_exports_list(_socket))
64 if _have_ssl:
65 __all__.extend(os._get_exports_list(_ssl))
67 _realsocket = socket
68 if _have_ssl:
69 _realssl = ssl
70 def ssl(sock, keyfile=None, certfile=None):
71 if hasattr(sock, "_sock"):
72 sock = sock._sock
73 return _realssl(sock, keyfile, certfile)
75 # WSA error codes
76 if sys.platform.lower().startswith("win"):
77 errorTab = {}
78 errorTab[10004] = "The operation was interrupted."
79 errorTab[10009] = "A bad file handle was passed."
80 errorTab[10013] = "Permission denied."
81 errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
82 errorTab[10022] = "An invalid operation was attempted."
83 errorTab[10035] = "The socket operation would block"
84 errorTab[10036] = "A blocking operation is already in progress."
85 errorTab[10048] = "The network address is in use."
86 errorTab[10054] = "The connection has been reset."
87 errorTab[10058] = "The network has been shut down."
88 errorTab[10060] = "The operation timed out."
89 errorTab[10061] = "Connection refused."
90 errorTab[10063] = "The name is too long."
91 errorTab[10064] = "The host is down."
92 errorTab[10065] = "The host is unreachable."
93 __all__.append("errorTab")
97 def getfqdn(name=''):
98 """Get fully qualified domain name from name.
100 An empty argument is interpreted as meaning the local host.
102 First the hostname returned by gethostbyaddr() is checked, then
103 possibly existing aliases. In case no FQDN is available, hostname
104 is returned.
106 name = name.strip()
107 if not name or name == '0.0.0.0':
108 name = gethostname()
109 try:
110 hostname, aliases, ipaddrs = gethostbyaddr(name)
111 except error:
112 pass
113 else:
114 aliases.insert(0, hostname)
115 for name in aliases:
116 if '.' in name:
117 break
118 else:
119 name = hostname
120 return name
124 # These classes are used by the socket() defined on Windows and BeOS
125 # platforms to provide a best-effort implementation of the cleanup
126 # semantics needed when sockets can't be dup()ed.
128 # These are not actually used on other platforms.
131 _socketmethods = (
132 'bind', 'connect', 'connect_ex', 'fileno', 'listen',
133 'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
134 'sendall', 'setblocking',
135 'settimeout', 'gettimeout', 'shutdown')
137 if sys.platform == "riscos":
138 _socketmethods = _socketmethods + ('sleeptaskw',)
140 class _closedsocket(object):
141 __slots__ = []
142 def _dummy(*args):
143 raise error(EBADF, 'Bad file descriptor')
144 send = recv = sendto = recvfrom = __getattr__ = _dummy
146 class _socketobject(object):
148 __doc__ = _realsocket.__doc__
150 __slots__ = ["_sock", "send", "recv", "sendto", "recvfrom"]
152 def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
153 if _sock is None:
154 _sock = _realsocket(family, type, proto)
155 self._sock = _sock
156 self.send = self._sock.send
157 self.recv = self._sock.recv
158 self.sendto = self._sock.sendto
159 self.recvfrom = self._sock.recvfrom
161 def close(self):
162 self._sock = _closedsocket()
163 self.send = self.recv = self.sendto = self.recvfrom = self._sock._dummy
164 close.__doc__ = _realsocket.close.__doc__
166 def accept(self):
167 sock, addr = self._sock.accept()
168 return _socketobject(_sock=sock), addr
169 accept.__doc__ = _realsocket.accept.__doc__
171 def dup(self):
172 """dup() -> socket object
174 Return a new socket object connected to the same system resource."""
175 return _socketobject(_sock=self._sock)
177 def makefile(self, mode='r', bufsize=-1):
178 """makefile([mode[, bufsize]]) -> file object
180 Return a regular file object corresponding to the socket. The mode
181 and bufsize arguments are as for the built-in open() function."""
182 return _fileobject(self._sock, mode, bufsize)
184 _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
185 "%s.__doc__ = _realsocket.%s.__doc__\n")
186 for _m in _socketmethods:
187 exec _s % (_m, _m, _m, _m)
188 del _m, _s
190 socket = SocketType = _socketobject
192 class _fileobject(object):
193 """Faux file object attached to a socket object."""
195 default_bufsize = 8192
196 name = "<socket>"
198 __slots__ = ["mode", "bufsize", "softspace",
199 # "closed" is a property, see below
200 "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf"]
202 def __init__(self, sock, mode='rb', bufsize=-1):
203 self._sock = sock
204 self.mode = mode # Not actually used in this version
205 if bufsize < 0:
206 bufsize = self.default_bufsize
207 self.bufsize = bufsize
208 self.softspace = False
209 if bufsize == 0:
210 self._rbufsize = 1
211 elif bufsize == 1:
212 self._rbufsize = self.default_bufsize
213 else:
214 self._rbufsize = bufsize
215 self._wbufsize = bufsize
216 self._rbuf = "" # A string
217 self._wbuf = [] # A list of strings
219 def _getclosed(self):
220 return self._sock is not None
221 closed = property(_getclosed, doc="True if the file is closed")
223 def close(self):
224 try:
225 if self._sock:
226 self.flush()
227 finally:
228 self._sock = None
230 def __del__(self):
231 try:
232 self.close()
233 except:
234 # close() may fail if __init__ didn't complete
235 pass
237 def flush(self):
238 if self._wbuf:
239 buffer = "".join(self._wbuf)
240 self._wbuf = []
241 self._sock.sendall(buffer)
243 def fileno(self):
244 return self._sock.fileno()
246 def write(self, data):
247 data = str(data) # XXX Should really reject non-string non-buffers
248 if not data:
249 return
250 self._wbuf.append(data)
251 if (self._wbufsize == 0 or
252 self._wbufsize == 1 and '\n' in data or
253 self._get_wbuf_len() >= self._wbufsize):
254 self.flush()
256 def writelines(self, list):
257 # XXX We could do better here for very long lists
258 # XXX Should really reject non-string non-buffers
259 self._wbuf.extend(filter(None, map(str, list)))
260 if (self._wbufsize <= 1 or
261 self._get_wbuf_len() >= self._wbufsize):
262 self.flush()
264 def _get_wbuf_len(self):
265 buf_len = 0
266 for x in self._wbuf:
267 buf_len += len(x)
268 return buf_len
270 def read(self, size=-1):
271 data = self._rbuf
272 if size < 0:
273 # Read until EOF
274 buffers = []
275 if data:
276 buffers.append(data)
277 self._rbuf = ""
278 if self._rbufsize <= 1:
279 recv_size = self.default_bufsize
280 else:
281 recv_size = self._rbufsize
282 while True:
283 data = self._sock.recv(recv_size)
284 if not data:
285 break
286 buffers.append(data)
287 return "".join(buffers)
288 else:
289 # Read until size bytes or EOF seen, whichever comes first
290 buf_len = len(data)
291 if buf_len >= size:
292 self._rbuf = data[size:]
293 return data[:size]
294 buffers = []
295 if data:
296 buffers.append(data)
297 self._rbuf = ""
298 while True:
299 left = size - buf_len
300 recv_size = max(self._rbufsize, left)
301 data = self._sock.recv(recv_size)
302 if not data:
303 break
304 buffers.append(data)
305 n = len(data)
306 if n >= left:
307 self._rbuf = data[left:]
308 buffers[-1] = data[:left]
309 break
310 buf_len += n
311 return "".join(buffers)
313 def readline(self, size=-1):
314 data = self._rbuf
315 if size < 0:
316 # Read until \n or EOF, whichever comes first
317 if self._rbufsize <= 1:
318 # Speed up unbuffered case
319 assert data == ""
320 buffers = []
321 recv = self._sock.recv
322 while data != "\n":
323 data = recv(1)
324 if not data:
325 break
326 buffers.append(data)
327 return "".join(buffers)
328 nl = data.find('\n')
329 if nl >= 0:
330 nl += 1
331 self._rbuf = data[nl:]
332 return data[:nl]
333 buffers = []
334 if data:
335 buffers.append(data)
336 self._rbuf = ""
337 while True:
338 data = self._sock.recv(self._rbufsize)
339 if not data:
340 break
341 buffers.append(data)
342 nl = data.find('\n')
343 if nl >= 0:
344 nl += 1
345 self._rbuf = data[nl:]
346 buffers[-1] = data[:nl]
347 break
348 return "".join(buffers)
349 else:
350 # Read until size bytes or \n or EOF seen, whichever comes first
351 nl = data.find('\n', 0, size)
352 if nl >= 0:
353 nl += 1
354 self._rbuf = data[nl:]
355 return data[:nl]
356 buf_len = len(data)
357 if buf_len >= size:
358 self._rbuf = data[size:]
359 return data[:size]
360 buffers = []
361 if data:
362 buffers.append(data)
363 self._rbuf = ""
364 while True:
365 data = self._sock.recv(self._rbufsize)
366 if not data:
367 break
368 buffers.append(data)
369 left = size - buf_len
370 nl = data.find('\n', 0, left)
371 if nl >= 0:
372 nl += 1
373 self._rbuf = data[nl:]
374 buffers[-1] = data[:nl]
375 break
376 n = len(data)
377 if n >= left:
378 self._rbuf = data[left:]
379 buffers[-1] = data[:left]
380 break
381 buf_len += n
382 return "".join(buffers)
384 def readlines(self, sizehint=0):
385 total = 0
386 list = []
387 while True:
388 line = self.readline()
389 if not line:
390 break
391 list.append(line)
392 total += len(line)
393 if sizehint and total >= sizehint:
394 break
395 return list
397 # Iterator protocols
399 def __iter__(self):
400 return self
402 def next(self):
403 line = self.readline()
404 if not line:
405 raise StopIteration
406 return line