Remove a ?? in the description of Mac OS support.
[python/dscho.git] / Lib / socket.py
blob7658c0735d07da8a8ba62bd887a38ec440351022
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.
9 Functions:
11 socket() -- create a new socket object
12 fromfd() -- create a socket object from an open file descriptor [*]
13 gethostname() -- return the current hostname
14 gethostbyname() -- map a hostname to its IP number
15 gethostbyaddr() -- map an IP number or hostname to DNS info
16 getservbyname() -- map a service name and a protocol name to a port number
17 getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
18 ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
19 htons(), htonl() -- convert 16, 32 bit int from host to network byte order
20 inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
21 inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
22 ssl() -- secure socket layer support (only available if configured)
24 [*] not available on all platforms!
26 Special objects:
28 SocketType -- type object for socket objects
29 error -- exception raised for I/O errors
31 Integer constants:
33 AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
34 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
36 Many other constants may be defined; these may be used in calls to
37 the setsockopt() and getsockopt() methods.
38 """
40 from _socket import *
42 import os, sys
44 if (sys.platform.lower().startswith("win")
45 or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")):
47 # be sure this happens only once, even in the face of reload():
48 try:
49 _realsocketcall
50 except NameError:
51 _realsocketcall = socket
53 def socket(family, type, proto=0):
54 return _socketobject(_realsocketcall(family, type, proto))
57 # WSA error codes
58 if sys.platform.lower().startswith("win"):
59 errorTab = {}
60 errorTab[10004] = "The operation was interrupted."
61 errorTab[10009] = "A bad file handle was passed."
62 errorTab[10013] = "Permission denied."
63 errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
64 errorTab[10022] = "An invalid operation was attempted."
65 errorTab[10035] = "The socket operation would block"
66 errorTab[10036] = "A blocking operation is already in progress."
67 errorTab[10048] = "The network address is in use."
68 errorTab[10054] = "The connection has been reset."
69 errorTab[10058] = "The network has been shut down."
70 errorTab[10060] = "The operation timed out."
71 errorTab[10061] = "Connection refused."
72 errorTab[10063] = "The name is too long."
73 errorTab[10064] = "The host is down."
74 errorTab[10065] = "The host is unreachable."
75 del os, sys
78 def getfqdn(name=''):
79 """Get fully qualified domain name from name.
81 An empty argument is interpreted as meaning the local host.
83 First the hostname returned by gethostbyaddr() is checked, then
84 possibly existing aliases. In case no FQDN is available, hostname
85 is returned.
86 """
87 name = name.strip()
88 if not name or name == '0.0.0.0':
89 name = gethostname()
90 try:
91 hostname, aliases, ipaddrs = gethostbyaddr(name)
92 except error:
93 pass
94 else:
95 aliases.insert(0, hostname)
96 for name in aliases:
97 if '.' in name:
98 break
99 else:
100 name = hostname
101 return name
105 # These classes are used by the socket() defined on Windows and BeOS
106 # platforms to provide a best-effort implementation of the cleanup
107 # semantics needed when sockets can't be dup()ed.
109 # These are not actually used on other platforms.
112 class _socketobject:
114 def __init__(self, sock):
115 self._sock = sock
117 def close(self):
118 self._sock = 0
120 def __del__(self):
121 self.close()
123 def accept(self):
124 sock, addr = self._sock.accept()
125 return _socketobject(sock), addr
127 def dup(self):
128 return _socketobject(self._sock)
130 def makefile(self, mode='r', bufsize=-1):
131 return _fileobject(self._sock, mode, bufsize)
133 _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n"
134 for _m in ('bind', 'connect', 'connect_ex', 'fileno', 'listen',
135 'getpeername', 'getsockname',
136 'getsockopt', 'setsockopt',
137 'recv', 'recvfrom', 'send', 'sendto',
138 'setblocking',
139 'shutdown'):
140 exec _s % (_m, _m)
143 class _fileobject:
145 def __init__(self, sock, mode, bufsize):
146 self._sock = sock
147 self._mode = mode
148 if bufsize < 0:
149 bufsize = 512
150 self._rbufsize = max(1, bufsize)
151 self._wbufsize = bufsize
152 self._wbuf = self._rbuf = ""
154 def close(self):
155 try:
156 if self._sock:
157 self.flush()
158 finally:
159 self._sock = 0
161 def __del__(self):
162 self.close()
164 def flush(self):
165 if self._wbuf:
166 self._sock.send(self._wbuf)
167 self._wbuf = ""
169 def fileno(self):
170 return self._sock.fileno()
172 def write(self, data):
173 self._wbuf = self._wbuf + data
174 if self._wbufsize == 1:
175 if '\n' in data:
176 self.flush()
177 else:
178 if len(self._wbuf) >= self._wbufsize:
179 self.flush()
181 def writelines(self, list):
182 filter(self._sock.send, list)
183 self.flush()
185 def read(self, n=-1):
186 if n >= 0:
187 k = len(self._rbuf)
188 if n <= k:
189 data = self._rbuf[:n]
190 self._rbuf = self._rbuf[n:]
191 return data
192 n = n - k
193 L = [self._rbuf]
194 self._rbuf = ""
195 while n > 0:
196 new = self._sock.recv(max(n, self._rbufsize))
197 if not new: break
198 k = len(new)
199 if k > n:
200 L.append(new[:n])
201 self._rbuf = new[n:]
202 break
203 L.append(new)
204 n = n - k
205 return "".join(L)
206 k = max(512, self._rbufsize)
207 L = [self._rbuf]
208 self._rbuf = ""
209 while 1:
210 new = self._sock.recv(k)
211 if not new: break
212 L.append(new)
213 k = min(k*2, 1024**2)
214 return "".join(L)
216 def readline(self, limit=-1):
217 data = ""
218 i = self._rbuf.find('\n')
219 while i < 0 and not (0 < limit <= len(self._rbuf)):
220 new = self._sock.recv(self._rbufsize)
221 if not new: break
222 i = new.find('\n')
223 if i >= 0: i = i + len(self._rbuf)
224 self._rbuf = self._rbuf + new
225 if i < 0: i = len(self._rbuf)
226 else: i = i+1
227 if 0 <= limit < len(self._rbuf): i = limit
228 data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
229 return data
231 def readlines(self, sizehint = 0):
232 total = 0
233 list = []
234 while 1:
235 line = self.readline()
236 if not line: break
237 list.append(line)
238 total += len(line)
239 if sizehint and total >= sizehint:
240 break
241 return list