Update for release.
[python/dscho.git] / Lib / socket.py
bloba8a4e39d5a18f464aedba1e91557bf82b7a5fbae
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
34 Integer constants:
36 AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
37 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
39 Many other constants may be defined; these may be used in calls to
40 the setsockopt() and getsockopt() methods.
41 """
43 import _socket
44 from _socket import *
46 _have_ssl = False
47 try:
48 import _ssl
49 from _ssl import *
50 _have_ssl = True
51 except ImportError:
52 pass
54 import os, sys
56 __all__ = ["getfqdn"]
57 __all__.extend(os._get_exports_list(_socket))
58 if _have_ssl:
59 __all__.extend(os._get_exports_list(_ssl))
61 _realsocket = socket
62 _needwrapper = False
63 if (sys.platform.lower().startswith("win")
64 or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")
65 or sys.platform=="riscos"):
67 _needwrapper = True
69 if _have_ssl:
70 _realssl = ssl
71 def ssl(sock, keyfile=None, certfile=None):
72 if hasattr(sock, "_sock"):
73 sock = sock._sock
74 return _realssl(sock, keyfile, certfile)
76 # WSA error codes
77 if sys.platform.lower().startswith("win"):
78 errorTab = {}
79 errorTab[10004] = "The operation was interrupted."
80 errorTab[10009] = "A bad file handle was passed."
81 errorTab[10013] = "Permission denied."
82 errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
83 errorTab[10022] = "An invalid operation was attempted."
84 errorTab[10035] = "The socket operation would block"
85 errorTab[10036] = "A blocking operation is already in progress."
86 errorTab[10048] = "The network address is in use."
87 errorTab[10054] = "The connection has been reset."
88 errorTab[10058] = "The network has been shut down."
89 errorTab[10060] = "The operation timed out."
90 errorTab[10061] = "Connection refused."
91 errorTab[10063] = "The name is too long."
92 errorTab[10064] = "The host is down."
93 errorTab[10065] = "The host is unreachable."
94 __all__.append("errorTab")
96 del os, sys
99 def getfqdn(name=''):
100 """Get fully qualified domain name from name.
102 An empty argument is interpreted as meaning the local host.
104 First the hostname returned by gethostbyaddr() is checked, then
105 possibly existing aliases. In case no FQDN is available, hostname
106 is returned.
108 name = name.strip()
109 if not name or name == '0.0.0.0':
110 name = gethostname()
111 try:
112 hostname, aliases, ipaddrs = gethostbyaddr(name)
113 except error:
114 pass
115 else:
116 aliases.insert(0, hostname)
117 for name in aliases:
118 if '.' in name:
119 break
120 else:
121 name = hostname
122 return name
126 # These classes are used by the socket() defined on Windows and BeOS
127 # platforms to provide a best-effort implementation of the cleanup
128 # semantics needed when sockets can't be dup()ed.
130 # These are not actually used on other platforms.
133 _socketmethods = (
134 'bind', 'connect', 'connect_ex', 'fileno', 'listen',
135 'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
136 'recv', 'recvfrom', 'send', 'sendall', 'sendto', 'setblocking',
137 'settimeout', 'gettimeout', 'shutdown')
139 class _closedsocket(object):
140 __slots__ = []
141 def __getattr__(self, name):
142 raise error(9, 'Bad file descriptor')
144 class _socketobject(object):
146 __doc__ = _realsocket.__doc__
148 __slots__ = ["_sock"]
150 def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
151 if _sock is None:
152 _sock = _realsocket(family, type, proto)
153 self._sock = _sock
155 def close(self):
156 self._sock = _closedsocket()
157 close.__doc__ = _realsocket.close.__doc__
159 def accept(self):
160 sock, addr = self._sock.accept()
161 return _socketobject(_sock=sock), addr
162 accept.__doc__ = _realsocket.accept.__doc__
164 def dup(self):
165 """dup() -> socket object
167 Return a new socket object connected to the same system resource."""
168 return _socketobject(_sock=self._sock)
170 def makefile(self, mode='r', bufsize=-1):
171 """makefile([mode[, bufsize]]) -> file object
173 Return a regular file object corresponding to the socket. The mode
174 and bufsize arguments are as for the built-in open() function."""
175 return _fileobject(self._sock, mode, bufsize)
177 _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
178 "%s.__doc__ = _realsocket.%s.__doc__\n")
179 for _m in _socketmethods:
180 exec _s % (_m, _m, _m, _m)
181 del _m, _s
183 if _needwrapper:
184 socket = SocketType = _socketobject
186 class _fileobject(object):
187 """Faux file object attached to a socket object."""
189 default_bufsize = 8192
190 name = "<socket>"
192 __slots__ = ["mode", "bufsize", "softspace",
193 # "closed" is a property, see below
194 "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf"]
196 def __init__(self, sock, mode='rb', bufsize=-1):
197 self._sock = sock
198 self.mode = mode # Not actually used in this version
199 if bufsize < 0:
200 bufsize = self.default_bufsize
201 self.bufsize = bufsize
202 self.softspace = False
203 if bufsize == 0:
204 self._rbufsize = 1
205 elif bufsize == 1:
206 self._rbufsize = self.default_bufsize
207 else:
208 self._rbufsize = bufsize
209 self._wbufsize = bufsize
210 self._rbuf = "" # A string
211 self._wbuf = [] # A list of strings
213 def _getclosed(self):
214 return self._sock is not None
215 closed = property(_getclosed, doc="True if the file is closed")
217 def close(self):
218 try:
219 if self._sock:
220 self.flush()
221 finally:
222 self._sock = None
224 def __del__(self):
225 self.close()
227 def flush(self):
228 if self._wbuf:
229 buffer = "".join(self._wbuf)
230 self._wbuf = []
231 self._sock.sendall(buffer)
233 def fileno(self):
234 return self._sock.fileno()
236 def write(self, data):
237 data = str(data) # XXX Should really reject non-string non-buffers
238 if not data:
239 return
240 self._wbuf.append(data)
241 if (self._wbufsize == 0 or
242 self._wbufsize == 1 and '\n' in data or
243 self._get_wbuf_len() >= self._wbufsize):
244 self.flush()
246 def writelines(self, list):
247 # XXX We could do better here for very long lists
248 # XXX Should really reject non-string non-buffers
249 self._wbuf.extend(filter(None, map(str, list)))
250 if (self._wbufsize <= 1 or
251 self._get_wbuf_len() >= self._wbufsize):
252 self.flush()
254 def _get_wbuf_len(self):
255 buf_len = 0
256 for x in self._wbuf:
257 buf_len += len(x)
258 return buf_len
260 def read(self, size=-1):
261 data = self._rbuf
262 if size < 0:
263 # Read until EOF
264 buffers = []
265 if data:
266 buffers.append(data)
267 self._rbuf = ""
268 if self._rbufsize <= 1:
269 recv_size = self.default_bufsize
270 else:
271 recv_size = self._rbufsize
272 while True:
273 data = self._sock.recv(recv_size)
274 if not data:
275 break
276 buffers.append(data)
277 return "".join(buffers)
278 else:
279 # Read until size bytes or EOF seen, whichever comes first
280 buf_len = len(data)
281 if buf_len >= size:
282 self._rbuf = data[size:]
283 return data[:size]
284 buffers = []
285 if data:
286 buffers.append(data)
287 self._rbuf = ""
288 while True:
289 left = size - buf_len
290 recv_size = max(self._rbufsize, left)
291 data = self._sock.recv(recv_size)
292 if not data:
293 break
294 buffers.append(data)
295 n = len(data)
296 if n >= left:
297 self._rbuf = data[left:]
298 buffers[-1] = data[:left]
299 break
300 buf_len += n
301 return "".join(buffers)
303 def readline(self, size=-1):
304 data = self._rbuf
305 if size < 0:
306 # Read until \n or EOF, whichever comes first
307 if self._rbufsize <= 1:
308 # Speed up unbuffered case
309 assert data == ""
310 buffers = []
311 recv = self._sock.recv
312 while data != "\n":
313 data = recv(1)
314 if not data:
315 break
316 buffers.append(data)
317 return "".join(buffers)
318 nl = data.find('\n')
319 if nl >= 0:
320 nl += 1
321 self._rbuf = data[nl:]
322 return data[:nl]
323 buffers = []
324 if data:
325 buffers.append(data)
326 self._rbuf = ""
327 while True:
328 data = self._sock.recv(self._rbufsize)
329 if not data:
330 break
331 buffers.append(data)
332 nl = data.find('\n')
333 if nl >= 0:
334 nl += 1
335 self._rbuf = data[nl:]
336 buffers[-1] = data[:nl]
337 break
338 return "".join(buffers)
339 else:
340 # Read until size bytes or \n or EOF seen, whichever comes first
341 nl = data.find('\n', 0, size)
342 if nl >= 0:
343 nl += 1
344 self._rbuf = data[nl:]
345 return data[:nl]
346 buf_len = len(data)
347 if buf_len >= size:
348 self._rbuf = data[size:]
349 return data[:size]
350 buffers = []
351 if data:
352 buffers.append(data)
353 self._rbuf = ""
354 while True:
355 data = self._sock.recv(self._rbufsize)
356 if not data:
357 break
358 buffers.append(data)
359 left = size - buf_len
360 nl = data.find('\n', 0, left)
361 if nl >= 0:
362 nl += 1
363 self._rbuf = data[nl:]
364 buffers[-1] = data[:nl]
365 break
366 n = len(data)
367 if n >= left:
368 self._rbuf = data[left:]
369 buffers[-1] = data[:left]
370 break
371 buf_len += n
372 return "".join(buffers)
374 def readlines(self, sizehint=0):
375 total = 0
376 list = []
377 while True:
378 line = self.readline()
379 if not line:
380 break
381 list.append(line)
382 total += len(line)
383 if sizehint and total >= sizehint:
384 break
385 return list
387 # Iterator protocols
389 def __iter__(self):
390 return self
392 def next(self):
393 line = self.readline()
394 if not line:
395 raise StopIteration
396 return line