2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / ByteFX.Data / Common / StreamCreator.cs
1 // ByteFX.Data data access components for .Net\r
2 // Copyright (C) 2002-2004  ByteFX, Inc.\r
3 //\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
8 // \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
13 // \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
17 \r
18 using System;\r
19 using System.IO;\r
20 using System.Net;\r
21 using System.Net.Sockets;\r
22 using System.Collections;\r
23 #if __MonoCS__ \r
24 using Mono.Posix;\r
25 #endif\r
26 \r
27 namespace ByteFX.Data.Common\r
28 {\r
29         /// <summary>\r
30         /// Summary description for StreamCreator.\r
31         /// </summary>\r
32         internal class StreamCreator\r
33         {\r
34                 string          hostList;\r
35                 int                     port;\r
36                 string          pipeName;\r
37                 int                     timeOut;\r
38 \r
39                 public StreamCreator( string hosts, int port, string pipeName)\r
40                 {\r
41                         hostList = hosts;\r
42                         this.port = port;\r
43                         this.pipeName = pipeName;\r
44                 }\r
45 \r
46                 public Stream GetStream(int timeOut) \r
47                 {\r
48                         this.timeOut = timeOut;\r
49 \r
50                         if (hostList.StartsWith("/"))\r
51                                 return CreateUnixSocketStream();\r
52 \r
53                         string [] dnsHosts = hostList.Split('&');\r
54                         ArrayList ipAddresses = new ArrayList();\r
55                         ArrayList hostNames = new ArrayList();\r
56 \r
57                         //\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
61                         {\r
62                                 IPHostEntry hostAddress = Dns.GetHostByName(h);\r
63                                 foreach (IPAddress addr in hostAddress.AddressList)\r
64                                 {\r
65                                         ipAddresses.Add( addr );\r
66                                         hostNames.Add( hostAddress.HostName );\r
67                                 }\r
68                         }\r
69 \r
70                         System.Random random = new Random((int)DateTime.Now.Ticks);\r
71                         int index = random.Next(ipAddresses.Count-1);\r
72 \r
73                         bool usePipe = pipeName != String.Empty;\r
74                         Stream stream = null;\r
75                         for (int i=0; i < ipAddresses.Count; i++)\r
76                         {\r
77                                 if (usePipe)\r
78                                         stream = CreateNamedPipeStream( (string)hostNames[index] );\r
79                                 else\r
80                                         stream = CreateSocketStream( (IPAddress)ipAddresses[index], port );\r
81                                 if (stream != null) return stream;\r
82 \r
83                                 index++;\r
84                                 if (index == ipAddresses.Count) index = 0;\r
85                         }\r
86 \r
87                         return stream;\r
88                 }\r
89 \r
90                 private Stream CreateUnixSocketStream() \r
91                 {\r
92 #if __MonoCS__ && !WINDOWS\r
93 \r
94                         Socket socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);\r
95 \r
96                         try\r
97                         {\r
98                                 UnixEndPoint endPoint = new UnixEndPoint (hostList);\r
99                                 socket.Connect (endPoint);\r
100                                 return new NetworkStream (socket, true);\r
101                         }\r
102                         catch (Exception ex)\r
103                         {\r
104                                 return null;\r
105                         }\r
106 #else\r
107                         throw new PlatformNotSupportedException ("Unix sockets are only supported on this platform");\r
108 #endif          \r
109                 }\r
110 \r
111                 private Stream CreateNamedPipeStream( string hostname ) \r
112                 {\r
113                         string pipePath;\r
114                         if (hostname.ToLower().Equals("localhost"))\r
115                                 pipePath = @"\\.\pipe\" + pipeName;\r
116                         else\r
117                                 pipePath = String.Format(@"\\{0}\pipe\{1}", hostname.ToString(), pipeName);\r
118                         return new NamedPipeStream(pipePath, FileAccess.ReadWrite);\r
119                 }\r
120 \r
121                 private void ConnectSocketCallback( IAsyncResult iar )\r
122                 {\r
123                 }\r
124 \r
125                 private Stream CreateSocketStream( IPAddress ip, int port ) \r
126                 {\r
127                         Socket socket = new Socket(AddressFamily.InterNetwork, \r
128                                 SocketType.Stream, ProtocolType.Tcp);\r
129 \r
130                         try\r
131                         {\r
132                                 //\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
137 \r
138                                 socket.Connect(endPoint);\r
139                                 socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1 );\r
140                                 return new NetworkStream( socket, true );\r
141                         }\r
142                         catch (Exception)\r
143                         {\r
144                                 return null;\r
145                         }\r
146                 }\r
147         }\r
148 }\r