3 * Copyright (C)2007-2008 Versabanq Innovations Inc. and contributors.
4 * See the included file named LICENSE for license information.
7 using System
.Collections
.Generic
;
9 using System
.Net
.Sockets
;
15 public class WvSockStream
: WvStream
18 protected Socket sock
{
25 _sock
.Blocking
= false;
29 public override bool ok
{
30 get { return (sock != null) && base.ok; }
33 public WvSockStream(Socket sock
)
38 public override EndPoint localaddr
{
42 return sock
.LocalEndPoint
;
46 public override EndPoint remoteaddr
{
50 return sock
.RemoteEndPoint
;
54 public override int read(WvBytes b
)
61 int ret
= sock
.Receive(b
.bytes
, b
.start
, b
.len
, 0);
71 catch (SocketException e
)
73 if (e
.ErrorCode
== 10004) // EINTR is normal when non-blocking
75 else if (e
.ErrorCode
== 10035) // EWOULDBLOCK too
80 // err = new Exception(wv.fmt("Error code {0}\n", e.ErrorCode));
86 public override int write(WvBytes b
)
93 int ret
= sock
.Send(b
.bytes
, b
.start
, b
.len
, 0);
94 if (ret
< 0) // Unexpected error
96 err
= new Exception(wv
.fmt("Write error #{0}", ret
));
102 catch (SocketException e
)
104 if (e
.ErrorCode
== 10004) // EINTR is normal when non-blocking
106 else if (e
.ErrorCode
== 10035) // EWOULDBLOCK too
111 // err = new Exception(wv.fmt("Error code {0}\n", e.ErrorCode));
117 public override event Action onreadable
{
118 add { base.onreadable
+= value;
119 if (ok
) ev
.onreadable(sock
, do_readable
); }
120 remove { base.onreadable
-= value;
121 if (!can_onreadable
) ev
.onreadable(sock
, null); }
124 public override event Action onwritable
{
125 add { base.onwritable
+= value;
126 if (ok
) ev
.onwritable(sock
, do_writable
); }
127 remove { base.onwritable
-= value;
128 if (!can_onwritable
) ev
.onwritable(sock
, null); }
131 void tryshutdown(SocketShutdown sd
)
137 catch (SocketException
)
143 public override bool wait(int msec_timeout
,
144 bool readable
, bool writable
)
146 foreach (int remain
in wv
.until(msec_timeout
))
150 if (!readable
&& !writable
)
154 var rlist
= new List
<Socket
>();
155 var wlist
= new List
<Socket
>();
160 Socket
.Select(rlist
, wlist
, null, remain
* 1000);
162 if (rlist
.Count
> 0 || wlist
.Count
> 0)
170 public override void noread()
174 tryshutdown(SocketShutdown
.Receive
);
175 ev
.onreadable(sock
, null);
178 public override void nowrite()
182 tryshutdown(SocketShutdown
.Send
);
183 ev
.onwritable(sock
, null);
186 public override void close()
192 ev
.onreadable(sock
, null);
193 ev
.onwritable(sock
, null);
194 tryshutdown(SocketShutdown
.Both
);
196 ((IDisposable
)sock
).Dispose();
205 public class WvTcp
: WvSockStream
207 public WvTcp(string remote
, ushort port
) : base(null)
209 // FIXME: do DNS lookups asynchronously?
212 IPHostEntry ipe
= Dns
.GetHostEntry(remote
);
213 IPEndPoint ipep
= new IPEndPoint(ipe
.AddressList
[0], port
);
214 Socket sock
= new Socket(AddressFamily
.InterNetwork
,
227 public class WvUnix
: WvSockStream
229 public WvUnix(string path
) : base(null)
233 if (path
.StartsWith("@"))
234 ep
= new AbstractUnixEndPoint(path
.Substring(1));
236 ep
= new UnixEndPoint(path
);
238 Socket sock
= new Socket(AddressFamily
.Unix
,
239 SocketType
.Stream
, 0);