2006-09-14 Jonathan Chambers <joncham@gmail.com>
[mcs.git] / class / Microsoft.Web.Services / Microsoft.Web.Services.Messaging / SoapTcpChannel.cs
bloba6fb29d87c525fc192c3b520ed890b5b76bd72ad
1 //
2 // Microsoft.Web.Services.Messaging.SoapTcpChannel.cs
3 //
4 // Author: Todd Berman <tberman@gentoo.org>
5 //
6 // (C) 2003 Todd Berman
8 using System;
9 using System.Net;
10 using System.Net.Sockets;
12 namespace Microsoft.Web.Services.Messaging
15 public class SoapTcpChannel : SoapChannel
18 private bool _active = false;
19 private bool _disposed = false;
20 private AddressFamily _addrFam = AddressFamily.InterNetwork;
21 private DateTime _lastActivity = DateTime.Now;
22 private int _port = 0;
23 private Socket _socket = null;
24 private NetworkStream _stream = null;
25 private Uri _destination = null;
26 private string _hostname = null;
28 public SoapTcpChannel (Socket sock, ISoapFormatter format) : base (format)
30 _socket = sock;
31 _stream = new NetworkStream (sock, false);
32 _active = true;
34 IPEndPoint ep = sock.RemoteEndPoint as IPEndPoint;
36 _destination = new Uri ("soap.tcp://" + ep.Address.ToString () + ":" + ep.Port);
39 public SoapTcpChannel (Uri uri, ISoapFormatter format) : base (format)
41 if(uri == null) {
42 throw new ArgumentNullException ("to");
44 if(uri.Scheme != "soap.tcp") {
45 throw new ArgumentException ("Invalid Scheme");
47 _hostname = uri.Host;
48 _port = uri.Port < 0 ? 8081 : uri.Port;
51 public override void Close ()
53 lock(SyncRoot) {
54 try {
55 _active = false;
56 if(_socket != null || !_socket.Connected) {
57 _socket.Close ();
59 } catch {
60 _socket = null;
65 public void Connect ()
67 if(_disposed) {
68 throw new ObjectDisposedException (GetType ().FullName);
70 if(_active) {
71 return;
73 lock(SyncRoot) {
74 if(_active) {
75 return;
77 IPHostEntry host = Dns.Resolve (_hostname);
79 IPAddress[] ip_addrs = host.AddressList;
81 Exception exception = null;
83 for (int i = 0; i < ip_addrs.Length; i++) {
84 IPAddress addy = ip_addrs[i];
86 _addrFam = addy.AddressFamily;
87 _socket = new Socket (_addrFam, SocketType.Stream, ProtocolType.Tcp);
88 _active = false;
90 try {
91 Connect ( new IPEndPoint (addy, _port) );
92 break;
93 } catch (Exception e) {
94 _socket.Close ();
95 _socket = null;
96 exception = e;
100 if(_active == false) {
101 if(exception != null) {
102 throw exception;
105 throw new Exception ("Not Connected");
107 _stream = new NetworkStream (_socket, false);
111 public void Connect (IPEndPoint endpoint)
113 if(_disposed) {
114 throw new ObjectDisposedException (GetType ().FullName);
116 if(endpoint == null) {
117 throw new ArgumentNullException ("endpoint");
120 _socket.Connect (endpoint);
121 _active = true;
122 UpdateLastActivity ();
126 ~SoapTcpChannel ()
128 if(_active == false) {
129 Close ();
130 _disposed = true;
135 public override SoapEnvelope Receive ()
137 if(!_active) {
138 Connect ();
141 SoapEnvelope env = DeserializeMessage (_stream);
143 if(env != null) {
144 env.Context.Channel = this;
147 UpdateLastActivity ();
149 return env;
152 public override void Send (SoapEnvelope env)
154 lock(SyncRoot) {
155 if(!_active) {
156 Connect ();
158 SerializeMessage (env, _stream);
159 UpdateLastActivity ();
163 public void UpdateLastActivity ()
165 lock (SyncRoot) {
166 _lastActivity = DateTime.Now;
170 public override bool Active {
171 get { return _active; }
174 public Uri Destination {
175 get { return _destination; }
178 public DateTime LastActivity {
179 get { return _lastActivity; }
182 public override string Scheme {
183 get { return "soap.tcp"; }