1 """socket.py for mac - Emulate socket module with mactcp and macdnr
3 Currently only implements TCP sockets (AF_INET, SOCK_STREAM).
4 Esoteric things like socket options don't work,
5 but getpeername() and makefile() do work; everything used by ftplib works!
8 # Jack Jansen, CWI, November 1994 (initial version)
9 # Guido van Rossum, CWI, March 1995 (bug fixes and lay-out)
19 _myerror
= 'socket_wrapper.error'
20 error
= (mactcp
.error
, macdnr
.error
, _myerror
)
30 _BUFSIZE
= 15*1024 # Size of TCP/UDP input buffer
39 if _myaddress
== None:
40 _myaddress
= mactcp
.IPAddr()
45 if type(str) == type(1):
46 return str # Already numeric
47 ptr
= macdnr
.StrToAddr(str)
52 def gethostbyname(str):
54 return macdnr
.AddrToStr(id)
57 def gethostbyaddr(str):
59 ptr
= macdnr
.AddrToName(id)
62 if name
[-1:] == '.': name
= name
[:-1]
63 names
, addresses
= [], [str]
64 return name
, names
, addresses
70 ptr
= macdnr
.AddrToName(id)
76 def _gethostaddress():
78 if _myaddrstr
== None:
80 _myaddrstr
= macdnr
.AddrToStr(id)
84 def socket(family
, type, *which
):
86 raise _myerror
, 'Protocol family %d not supported' % type
87 if type == SOCK_DGRAM
:
89 elif type == SOCK_STREAM
:
91 raise _myerror
, 'Protocol type %d not supported' % type
95 raise _myerror
, 'Operation not supported on a mac'
99 def unsupported(self
, *args
):
100 raise _myerror
, 'Operation not supported on this socket'
105 connect
= unsupported
107 getpeername
= unsupported
108 getsockname
= unsupported
109 getsockopt
= unsupported
112 recvfrom
= unsupported
115 setblocking
= unsupported
116 setsockopt
= unsupported
117 shutdown
= unsupported
120 class _tcpsocket(_socket
):
123 self
.stream
= mactcp
.TCPCreate(_BUFSIZE
)
124 ##self.stream.asr = self.asr
132 if not self
.listening
:
133 raise _myerror
, 'Not listening'
137 return self
, self
.getsockname()
139 # bind has two ways of calling: s.bind(host, port) or s.bind((host, port));
140 # the latter is more proper but the former more common
141 def bind(self
, a1
, a2
=None):
154 # connect has the same problem as bind (see above)
155 def connect(self
, a1
, a2
=None):
160 self
.stream
.ActiveOpen(self
.port
, _ipaddress(host
), port
)
162 def getsockname(self
):
163 host
, port
= self
.stream
.GetSockName()
164 host
= macdnr
.AddrToStr(host
)
167 def getpeername(self
):
168 st
= self
.stream
.Status()
169 host
= macdnr
.AddrToStr(st
.remoteHost
)
170 return host
, st
.remotePort
172 def listen(self
, backlog
):
173 self
.stream
.PassiveOpen(self
.port
)
176 def makefile(self
, rw
= 'r', bs
= 512):
177 return _socketfile(self
, rw
, bs
)
179 def recv(self
, bufsize
, flags
=0):
181 raise _myerror
, 'recv flags not yet supported on mac'
184 self
.databuf
, urg
, mark
= self
.stream
.Rcv(0)
185 except mactcp
.error
, arg
:
186 if arg
[0] != MACTCPconst
.connectionClosing
:
187 raise mactcp
.error
, arg
188 rv
= self
.databuf
[:bufsize
]
189 self
.databuf
= self
.databuf
[bufsize
:]
193 self
.stream
.Send(buf
)
196 def shutdown(self
, how
):
201 def bytes_readable(self
):
202 st
= self
.stream
.Status()
203 return st
.amtUnreadData
205 def bytes_writeable(self
):
206 st
= self
.stream
.Status()
207 return st
.sendWindow
- st
.sendUnacked
;
210 class _udpsocket(_socket
):
218 def __init__(self
, sock
, rw
, bs
):
219 if rw
[1:] == 'b': rw
= rw
[:1]
220 if rw
not in ('r', 'w'): raise _myerror
, "mode must be 'r' or 'w'"
226 def read(self
, length
= -1):
229 while len(self
.buf
) < length
:
230 new
= self
.sock
.recv(0x7fffffff)
233 self
.buf
= self
.buf
+ new
234 rv
= self
.buf
[:length
]
235 self
.buf
= self
.buf
[length
:]
240 while not '\n' in self
.buf
:
241 new
= self
.sock
.recv(0x7fffffff)
244 self
.buf
= self
.buf
+ new
245 if not '\n' in self
.buf
:
249 i
= string
.index(self
.buf
, '\n')
251 self
.buf
= self
.buf
[i
+1:]
256 line
= self
.readline()
259 line
= self
.readline()
262 def write(self
, buf
):
267 elif len(buf
) + len(self
.buf
) >= BS
:
271 self
.buf
= self
.buf
+ buf
273 def writelines(self
, list):
278 if self
.buf
and self
.rw
== 'w':
279 self
.sock
.send(self
.buf
)
289 s
= socket(AF_INET
, SOCK_STREAM
)
290 s
.connect('poseidon.cwi.nl', 13)
292 print 'Time/date:', rv
295 print 'Unexpected extra data:', rv
300 s
= socket(AF_INET
, SOCK_DGRAM
)
301 print 'Sending data... (hello world)'
302 s
.sendto(('poseidon.cwi.nl', 7), 'hello world')
303 rv
, host
= s
.recvfrom(1000)
304 print 'Got from ', host
, ':', rv