// ByteFX.Data data access components for .Net // Copyright (C) 2002-2004 ByteFX, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Collections; #if __MonoCS__ using Mono.Posix; #endif namespace ByteFX.Data.Common { /// /// Summary description for StreamCreator. /// internal class StreamCreator { string hostList; int port; string pipeName; int timeOut; public StreamCreator( string hosts, int port, string pipeName) { hostList = hosts; this.port = port; this.pipeName = pipeName; } public Stream GetStream(int timeOut) { this.timeOut = timeOut; if (hostList.StartsWith("/")) return CreateUnixSocketStream(); string [] dnsHosts = hostList.Split('&'); ArrayList ipAddresses = new ArrayList(); ArrayList hostNames = new ArrayList(); // // Each host name specified may contain multiple IP addresses // Lets look at the DNS entries for each host name foreach (string h in dnsHosts) { IPHostEntry hostAddress = Dns.GetHostByName(h); foreach (IPAddress addr in hostAddress.AddressList) { ipAddresses.Add( addr ); hostNames.Add( hostAddress.HostName ); } } System.Random random = new Random((int)DateTime.Now.Ticks); int index = random.Next(ipAddresses.Count-1); bool usePipe = pipeName != String.Empty; Stream stream = null; for (int i=0; i < ipAddresses.Count; i++) { if (usePipe) stream = CreateNamedPipeStream( (string)hostNames[index] ); else stream = CreateSocketStream( (IPAddress)ipAddresses[index], port ); if (stream != null) return stream; index++; if (index == ipAddresses.Count) index = 0; } return stream; } private Stream CreateUnixSocketStream() { #if __MonoCS__ && !WINDOWS Socket socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); try { UnixEndPoint endPoint = new UnixEndPoint (hostList); socket.Connect (endPoint); return new NetworkStream (socket, true); } catch (Exception ex) { return null; } #else throw new PlatformNotSupportedException ("Unix sockets are only supported on this platform"); #endif } private Stream CreateNamedPipeStream( string hostname ) { string pipePath; if (hostname.ToLower().Equals("localhost")) pipePath = @"\\.\pipe\" + pipeName; else pipePath = String.Format(@"\\{0}\pipe\{1}", hostname.ToString(), pipeName); return new NamedPipeStream(pipePath, FileAccess.ReadWrite); } private void ConnectSocketCallback( IAsyncResult iar ) { } private Stream CreateSocketStream( IPAddress ip, int port ) { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { // // Lets try to connect IPEndPoint endPoint = new IPEndPoint( ip, port); // IAsyncResult iar = socket.BeginConnect( endPoint, // new AsyncCallback(ConnectSocketCallback), socket ); socket.Connect(endPoint); socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1 ); return new NetworkStream( socket, true ); } catch (Exception) { return null; } } } }