blob: 10227aa3f705c76daf5727d5cdc4820a2a4690b5 [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.
Martin v. Löwisaf484d52000-09-30 11:34:30 +00007On other systems, it only supports IP. Functions specific for a
8socket 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
45if (sys.platform.lower().startswith("win")
Jack Jansen344ecdb2000-09-15 12:59:46 +000046 or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")):
Fred Drakea6070f02000-08-16 14:14:32 +000047
48 # be sure this happens only once, even in the face of reload():
49 try:
50 _realsocketcall
51 except NameError:
52 _realsocketcall = socket
53
54 def socket(family, type, proto=0):
55 return _socketobject(_realsocketcall(family, type, proto))
56
57
58# WSA error codes
59if sys.platform.lower().startswith("win"):
60 errorTab = {}
61 errorTab[10004] = "The operation was interrupted."
62 errorTab[10009] = "A bad file handle was passed."
63 errorTab[10013] = "Permission denied."
64 errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
65 errorTab[10022] = "An invalid operation was attempted."
66 errorTab[10035] = "The socket operation would block"
67 errorTab[10036] = "A blocking operation is already in progress."
68 errorTab[10048] = "The network address is in use."
69 errorTab[10054] = "The connection has been reset."
70 errorTab[10058] = "The network has been shut down."
71 errorTab[10060] = "The operation timed out."
72 errorTab[10061] = "Connection refused."
73 errorTab[10063] = "The name is too long."
74 errorTab[10064] = "The host is down."
75 errorTab[10065] = "The host is unreachable."
76del os, sys
77
78
79def getfqdn(name=''):
80 """Get fully qualified domain name from name.
81
82 An empty argument is interpreted as meaning the local host.
83
84 First the hostname returned by gethostbyaddr() is checked, then
85 possibly existing aliases. In case no FQDN is available, hostname
86 is returned.
87 """
88 name = name.strip()
Peter Schneider-Kamp2d2785a2000-08-16 20:30:21 +000089 if not name or name == '0.0.0.0':
Fred Drakea6070f02000-08-16 14:14:32 +000090 name = gethostname()
91 try:
92 hostname, aliases, ipaddrs = gethostbyaddr(name)
93 except error:
94 pass
95 else:
96 aliases.insert(0, hostname)
97 for name in aliases:
98 if '.' in name:
99 break
100 else:
101 name = hostname
102 return name
103
104
105#
106# These classes are used by the socket() defined on Windows and BeOS
107# platforms to provide a best-effort implementation of the cleanup
108# semantics needed when sockets can't be dup()ed.
109#
110# These are not actually used on other platforms.
111#
112
113class _socketobject:
114
115 def __init__(self, sock):
116 self._sock = sock
117
118 def close(self):
119 self._sock = 0
120
121 def __del__(self):
122 self.close()
123
124 def accept(self):
125 sock, addr = self._sock.accept()
126 return _socketobject(sock), addr
127
128 def dup(self):
129 return _socketobject(self._sock)
130
131 def makefile(self, mode='r', bufsize=-1):
132 return _fileobject(self._sock, mode, bufsize)
133
134 _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n"
135 for _m in ('bind', 'connect', 'connect_ex', 'fileno', 'listen',
136 'getpeername', 'getsockname',
137 'getsockopt', 'setsockopt',
138 'recv', 'recvfrom', 'send', 'sendto',
139 'setblocking',
140 'shutdown'):
141 exec _s % (_m, _m)
142
143
144class _fileobject:
145
146 def __init__(self, sock, mode, bufsize):
147 self._sock = sock
148 self._mode = mode
149 if bufsize < 0:
150 bufsize = 512
151 self._rbufsize = max(1, bufsize)
152 self._wbufsize = bufsize
153 self._wbuf = self._rbuf = ""
154
155 def close(self):
156 try:
157 if self._sock:
158 self.flush()
159 finally:
160 self._sock = 0
161
162 def __del__(self):
163 self.close()
164
165 def flush(self):
166 if self._wbuf:
167 self._sock.send(self._wbuf)
168 self._wbuf = ""
169
170 def fileno(self):
171 return self._sock.fileno()
172
173 def write(self, data):
174 self._wbuf = self._wbuf + data
175 if self._wbufsize == 1:
176 if '\n' in data:
177 self.flush()
178 else:
179 if len(self._wbuf) >= self._wbufsize:
180 self.flush()
181
182 def writelines(self, list):
183 filter(self._sock.send, list)
184 self.flush()
185
186 def read(self, n=-1):
187 if n >= 0:
188 k = len(self._rbuf)
189 if n <= k:
190 data = self._rbuf[:n]
191 self._rbuf = self._rbuf[n:]
192 return data
193 n = n - k
194 L = [self._rbuf]
195 self._rbuf = ""
196 while n > 0:
197 new = self._sock.recv(max(n, self._rbufsize))
198 if not new: break
199 k = len(new)
200 if k > n:
201 L.append(new[:n])
202 self._rbuf = new[n:]
203 break
204 L.append(new)
205 n = n - k
206 return "".join(L)
207 k = max(512, self._rbufsize)
208 L = [self._rbuf]
209 self._rbuf = ""
210 while 1:
211 new = self._sock.recv(k)
212 if not new: break
213 L.append(new)
214 k = min(k*2, 1024**2)
215 return "".join(L)
216
217 def readline(self, limit=-1):
218 data = ""
219 i = self._rbuf.find('\n')
220 while i < 0 and not (0 < limit <= len(self._rbuf)):
221 new = self._sock.recv(self._rbufsize)
222 if not new: break
223 i = new.find('\n')
224 if i >= 0: i = i + len(self._rbuf)
225 self._rbuf = self._rbuf + new
226 if i < 0: i = len(self._rbuf)
227 else: i = i+1
228 if 0 <= limit < len(self._rbuf): i = limit
229 data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
230 return data
231
Martin v. Löwis6df27f82000-09-19 11:25:58 +0000232 def readlines(self, sizehint = 0):
233 total = 0
Fred Drakea6070f02000-08-16 14:14:32 +0000234 list = []
235 while 1:
236 line = self.readline()
237 if not line: break
238 list.append(line)
Martin v. Löwis6df27f82000-09-19 11:25:58 +0000239 total += len(line)
240 if sizehint and total >= sizehint:
241 break
Fred Drakea6070f02000-08-16 14:14:32 +0000242 return list