1 /* Copyright (C) 2007   Versant Inc.   http://www.db4o.com */
2 using System;
3 using System.IO;
4 using System.Net;
5 using Sharpen.IO;
6 using NativeSocket=System.Net.Sockets.Socket;
7 using System.Net.Sockets;
8 
9 namespace Sharpen.Net
10 {
11 	public class Socket : SocketWrapper
12 	{
13 #if SILVERLIGHT
Socket(string hostName, int port)14 		public Socket(string hostName, int port)
15 		{
16 		}
17 	}
18 #else
19 		public Socket(string hostName, int port)
20 		{
21 		    NativeSocket socket = new NativeSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
22 			socket.Connect(new IPEndPoint(Resolve(hostName), port));
23 			Initialize(socket);
24 			_toString = StringRepresentation();
25 		}
26 
27 	    private static IPAddress Resolve(string hostName)
28 	    {
29 	    	IPHostEntry found = Dns.GetHostEntry(hostName);
30 	        foreach (IPAddress address in found.AddressList)
31 	        {
32                 if (address.AddressFamily == AddressFamily.InterNetwork)
33                 {
34                     return address;
35                 }
36 	        }
37 	        throw new IOException("couldn't find suitable address for name '" + hostName + "'");
38 	    }
39 
40 	    public Socket(NativeSocket socket)
41 		{
42 			Initialize(socket);
43 		}
44 
45 		public IInputStream GetInputStream()
46 		{
47 			return _in;
48 		}
49 
50 		public IOutputStream GetOutputStream()
51 		{
52 			return _out;
53 		}
54 
55 		public int GetPort()
56 		{
57 			return ((IPEndPoint) _delegate.RemoteEndPoint).Port;
58 		}
59 
60 		override protected void Initialize(NativeSocket socket)
61 		{
62 			base.Initialize(socket);
63 
64 			NetworkStream stream = new NetworkStream(_delegate);
65 
66 #if CF
67 			_in = new SocketInputStream(this);
68 #else
69 			_in = new InputStream(stream);
70 #endif
71 			_out = new OutputStream(stream);
72 		}
73 
74 		public override string ToString()
75 		{
76 			return _toString;
77 		}
78 
79 		private string StringRepresentation()
80 		{
81 			return ((IPEndPoint)_delegate.LocalEndPoint).Port + " => "+ UnderlyingSocket.RemoteEndPoint;
82 		}
83 
84 		private IInputStream _in;
85 		private IOutputStream _out;
86 		private readonly string _toString;
87 	}
88 #if CF
89 	internal class SocketInputStream : IInputStream
90     {
91     	private readonly Socket _socket;
92 
93     	public SocketInputStream(Socket socket)
94         {
95     		_socket = socket;
96         }
97 
98     	public int Read()
99     	{
100 			byte[] buffer = new byte[1];
101     		if (1 != Read(buffer))
102     		{
103     			return -1;
104     		}
105     		return (int) buffer[0];
106     	}
107 
108     	public int Read(byte[] bytes)
109     	{
110     		return Read(bytes, 0, bytes.Length);
111     	}
112 
113     	public int Read(byte[] bytes, int offset, int length)
114     	{
115 			try
116 			{
117 				if (_socket.SoTimeout > 0)
118 				{
119 					if (!UnderlyingSocket.Poll(_socket.SoTimeout*1000, SelectMode.SelectRead))
120 					{
121 						throw new IOException("read timeout");
122 					}
123 				}
124 				return InputStream.TranslateReadReturnValue(
125 					UnderlyingSocket.Receive(bytes, offset, length, SocketFlags.None));
126 			}
127 			catch (ObjectDisposedException x)
128 			{
129 				throw new IOException(x.Message, x);
130 			}
131 			catch (SocketException x)
132 			{
133 				throw new IOException(x.Message, x);
134 			}
135     	}
136 
137     	public void Close()
138     	{
139     		// nothing to do
140     	}
141 
142     	private System.Net.Sockets.Socket UnderlyingSocket
143     	{
144 			get { return _socket.UnderlyingSocket;  }
145     	}
146 	}
147 #endif // CF
148 #endif // SILVERLIGHT
149 }
150