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