blob: 7658c0735d07da8a8ba62bd887a38ec440351022 [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.
7On other systems, it only supports IP.
8
9Functions:
10
11socket() -- create a new socket object
12fromfd() -- create a socket object from an open file descriptor [*]
13gethostname() -- return the current hostname
14gethostbyname() -- map a hostname to its IP number
15gethostbyaddr() -- map an IP number or hostname to DNS info
16getservbyname() -- map a service name and a protocol name to a port number
17getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number
18ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
19htons(), htonl() -- convert 16, 32 bit int from host to network byte order
20inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
21inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
22ssl() -- secure socket layer support (only available if configured)
23
24 [*] not available on all platforms!
25
26Special objects:
27
28SocketType -- type object for socket objects
29error -- exception raised for I/O errors
30
31Integer constants:
32
33AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
34SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
35
36Many other constants may be defined; these may be used in calls to
37the setsockopt() and getsockopt() methods.
38"""
39
40from _socket import *
41
42import os, sys
43
44if (sys.platform.lower().startswith("win")
Jack Jansen344ecdb2000-09-15 12:59:46 +000045 or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")):
Fred Drakea6070f02000-08-16 14:14:32 +000046
47 # be sure this happens only once, even in the face of reload():
48 try:
49 _realsocketcall
50 except NameError:
51 _realsocketcall = socket
52
53 def socket(family, type, proto=0):
54 return _socketobject(_realsocketcall(family, type, proto))
55
56
57# WSA error codes
58if 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."
75del os, sys
76
77
78def getfqdn(name=''):
79 """Get fully qualified domain name from name.
80
81 An empty argument is interpreted as meaning the local host.
82
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()
Peter Schneider-Kamp2d2785a2000-08-16 20:30:21 +000088 if not name or name == '0.0.0.0':
Fred Drakea6070f02000-08-16 14:14:32 +000089 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
102
103
104#
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.
108#
109# These are not actually used on other platforms.
110#
111
112class _socketobject:
113
114 def __init__(self, sock):
115 self._sock = sock
116
117 def close(self):
118 self._sock = 0
119
120 def __del__(self):
121 self.close()
122
123 def accept(self):
124 sock, addr = self._sock.accept()
125 return _socketobject(sock), addr
126
127 def dup(self):
128 return _socketobject(self._sock)
129
130 def makefile(self, mode='r', bufsize=-1):
131 return _fileobject(self._sock, mode, bufsize)
132
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)
141
142
143class _fileobject:
144
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 = ""
153
154 def close(self):
155 try:
156 if self._sock:
157 self.flush()
158 finally:
159 self._sock = 0
160
161 def __del__(self):
162 self.close()
163
164 def flush(self):
165 if self._wbuf:
166 self._sock.send(self._wbuf)
167 self._wbuf = ""
168
169 def fileno(self):
170 return self._sock.fileno()
171
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()
180
181 def writelines(self, list):
182 filter(self._sock.send, list)
183 self.flush()
184
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)
215
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
230
Martin v. Löwis6df27f82000-09-19 11:25:58 +0000231 def readlines(self, sizehint = 0):
232 total = 0
Fred Drakea6070f02000-08-16 14:14:32 +0000233 list = []
234 while 1:
235 line = self.readline()
236 if not line: break
237 list.append(line)
Martin v. Löwis6df27f82000-09-19 11:25:58 +0000238 total += len(line)
239 if sizehint and total >= sizehint:
240 break
Fred Drakea6070f02000-08-16 14:14:32 +0000241 return list