1 // ByteFX.Data data access components for .Net
\r
2 // Copyright (C) 2002-2004 ByteFX, Inc.
\r
4 // This library is free software; you can redistribute it and/or
\r
5 // modify it under the terms of the GNU Lesser General Public
\r
6 // License as published by the Free Software Foundation; either
\r
7 // version 2.1 of the License, or (at your option) any later version.
\r
9 // This library is distributed in the hope that it will be useful,
\r
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
12 // Lesser General Public License for more details.
\r
14 // You should have received a copy of the GNU Lesser General Public
\r
15 // License along with this library; if not, write to the Free Software
\r
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
21 using System.Net.Sockets;
\r
22 using System.Collections;
\r
27 namespace ByteFX.Data.Common
\r
30 /// Summary description for StreamCreator.
\r
32 internal class StreamCreator
\r
39 public StreamCreator( string hosts, int port, string pipeName)
\r
43 this.pipeName = pipeName;
\r
46 public Stream GetStream(int timeOut)
\r
48 this.timeOut = timeOut;
\r
50 if (hostList.StartsWith("/"))
\r
51 return CreateUnixSocketStream();
\r
53 string [] dnsHosts = hostList.Split('&');
\r
54 ArrayList ipAddresses = new ArrayList();
\r
55 ArrayList hostNames = new ArrayList();
\r
58 // Each host name specified may contain multiple IP addresses
\r
59 // Lets look at the DNS entries for each host name
\r
60 foreach (string h in dnsHosts)
\r
62 IPHostEntry hostAddress = Dns.GetHostByName(h);
\r
63 foreach (IPAddress addr in hostAddress.AddressList)
\r
65 ipAddresses.Add( addr );
\r
66 hostNames.Add( hostAddress.HostName );
\r
70 System.Random random = new Random((int)DateTime.Now.Ticks);
\r
71 int index = random.Next(ipAddresses.Count-1);
\r
73 bool usePipe = pipeName != String.Empty;
\r
74 Stream stream = null;
\r
75 for (int i=0; i < ipAddresses.Count; i++)
\r
78 stream = CreateNamedPipeStream( (string)hostNames[index] );
\r
80 stream = CreateSocketStream( (IPAddress)ipAddresses[index], port );
\r
81 if (stream != null) return stream;
\r
84 if (index == ipAddresses.Count) index = 0;
\r
90 private Stream CreateUnixSocketStream()
\r
92 #if __MonoCS__ && !WINDOWS
\r
94 Socket socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
\r
98 UnixEndPoint endPoint = new UnixEndPoint (hostList);
\r
99 socket.Connect (endPoint);
\r
100 return new NetworkStream (socket, true);
\r
102 catch (Exception ex)
\r
107 throw new PlatformNotSupportedException ("Unix sockets are only supported on this platform");
\r
111 private Stream CreateNamedPipeStream( string hostname )
\r
114 if (hostname.ToLower().Equals("localhost"))
\r
115 pipePath = @"\\.\pipe\" + pipeName;
\r
117 pipePath = String.Format(@"\\{0}\pipe\{1}", hostname.ToString(), pipeName);
\r
118 return new NamedPipeStream(pipePath, FileAccess.ReadWrite);
\r
121 private void ConnectSocketCallback( IAsyncResult iar )
\r
125 private Stream CreateSocketStream( IPAddress ip, int port )
\r
127 Socket socket = new Socket(AddressFamily.InterNetwork,
\r
128 SocketType.Stream, ProtocolType.Tcp);
\r
133 // Lets try to connect
\r
134 IPEndPoint endPoint = new IPEndPoint( ip, port);
\r
135 // IAsyncResult iar = socket.BeginConnect( endPoint,
\r
136 // new AsyncCallback(ConnectSocketCallback), socket );
\r
138 socket.Connect(endPoint);
\r
139 socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1 );
\r
140 return new NetworkStream( socket, true );
\r