comparison Net/TCPStream.cs @ 0:3ab940a0c7a0

Initial commit
author Ivo Smits <Ivo@UCIS.nl>
date Tue, 11 Sep 2012 16:28:53 +0200
parents
children d0117dc37c34
comparison
equal deleted inserted replaced
-1:000000000000 0:3ab940a0c7a0
1 using System;
2 using System.IO;
3 using System.Net;
4 using System.Net.Sockets;
5 using System.Threading;
6
7 namespace UCIS.Net {
8 public class TCPStream : Stream, INetworkConnection {
9 private static long _totalBytesRead = 0;
10 private static long _totalBytesWritten = 0;
11 public static ulong TotalBytesWritten { get { return (ulong)_totalBytesWritten; } set { _totalBytesWritten = (long)value; } }
12 public static ulong TotalBytesRead { get { return (ulong)_totalBytesRead; } set { _totalBytesRead = (long)value; } }
13
14 private Socket _Socket;
15 private byte _PeekByte;
16 private bool _HasPeekByte;
17 private ulong _BytesWritten;
18 private ulong _BytesRead;
19 private DateTime _StartTime;
20 private bool _Blocking;
21
22 public event EventHandler Closed;
23
24 public TCPStream(Socket Socket) {
25 _Socket = Socket;
26 _HasPeekByte = false;
27 _StartTime = DateTime.Now;
28 _Blocking = _Socket.Blocking;
29 }
30
31 public Socket Socket {
32 get { return _Socket; }
33 }
34
35 public DateTime CreationTime {
36 get { return _StartTime; }
37 }
38
39 public bool Blocking {
40 get { return _Blocking; }
41 set {
42 Socket.Blocking = value;
43 _Blocking = value;
44 }
45 }
46
47 public bool NoDelay {
48 get { return Socket.NoDelay; }
49 set { Socket.NoDelay = value; }
50 }
51
52 public override bool CanTimeout {
53 get { return true; }
54 }
55
56 public override int ReadTimeout {
57 get { return Socket.ReceiveTimeout; }
58 set { Socket.ReceiveTimeout = value; }
59 }
60
61 public override int WriteTimeout {
62 get { return Socket.SendTimeout; }
63 set { Socket.SendTimeout = value; }
64 }
65
66 public override int ReadByte() {
67 if (_HasPeekByte) {
68 _HasPeekByte = false;
69 return _PeekByte;
70 } else {
71 byte[] Buffer = new byte[1];
72 if (Read(Buffer, 0, 1) != 1) return -1;
73 return Buffer[0];
74 }
75 }
76
77 public override int Read(byte[] buffer, int offset, int size) {
78 int Count = 0;
79
80 if (size < 1) return 0;
81 if (_HasPeekByte) {
82 buffer[offset] = _PeekByte;
83 _HasPeekByte = false;
84 Count = 1;
85 offset += 1;
86 size -= 1;
87 }
88
89 try {
90 if (size > 0) Count += Socket.Receive(buffer, offset, size, SocketFlags.None);
91 } catch (SocketException ex) {
92 switch (ex.SocketErrorCode) {
93 case SocketError.WouldBlock:
94 _Socket.Blocking = _Blocking;
95 throw new TimeoutException("The receive operation would block", ex);
96 case SocketError.TimedOut:
97 throw new TimeoutException("The receive operation timed out", ex);
98 case SocketError.ConnectionReset:
99 case SocketError.Disconnecting:
100 case SocketError.NetworkDown:
101 case SocketError.NetworkReset:
102 case SocketError.NetworkUnreachable:
103 case SocketError.NotConnected:
104 Close();
105 throw new SocketException((int)ex.SocketErrorCode);
106 default:
107 throw new SocketException((int)ex.SocketErrorCode);
108 }
109 }
110
111 _BytesRead += (ulong)Count;
112 Interlocked.Add(ref _totalBytesRead, (long)Count);
113 return Count;
114 }
115
116 public int PeekByte() {
117 if (_HasPeekByte) {
118 return _PeekByte;
119 } else {
120 int Result = 0;
121 Result = ReadByte();
122 if (Result >= 0 && Result <= 255) {
123 _PeekByte = (byte)Result;
124 _HasPeekByte = true;
125 }
126 return Result;
127 }
128 }
129
130 public int WriteBufferSize {
131 get { return Socket.SendBufferSize; }
132 set { Socket.SendBufferSize = value; }
133 }
134
135 public int ReadBufferSize {
136 get { return Socket.ReceiveBufferSize; }
137 set { Socket.ReceiveBufferSize = value; }
138 }
139
140 public override bool CanRead {
141 get { return Socket.Connected && (Blocking || (Socket.Available > 0)); }
142 }
143
144 public override bool CanSeek {
145 get { return false; }
146 }
147
148 public override bool CanWrite {
149 get { return Socket.Connected; }
150 }
151
152 public override void Flush() {
153 //Do nothing
154 //_Socket.NoDelay = true;
155 }
156
157 public override long Length {
158 get {
159 throw new NotSupportedException();
160 }
161 }
162
163 public override long Position {
164 get {
165 throw new NotSupportedException();
166 }
167 set {
168 throw new NotSupportedException();
169 }
170 }
171
172 public override long Seek(long offset, SeekOrigin origin) {
173 throw new NotSupportedException();
174 }
175
176 public override void SetLength(long value) {
177 throw new NotSupportedException();
178 }
179
180 public override void Write(byte[] buffer, int offset, int size) {
181 int left = size;
182 if (_Socket == null) throw new ObjectDisposedException("socket");
183 try {
184 while (left > 0) {
185 int sent = _Socket.Send(buffer, offset, left, 0);
186 left -= sent;
187 offset += sent;
188 }
189 } catch (SocketException ex) {
190 switch (ex.SocketErrorCode) {
191 case SocketError.WouldBlock:
192 _Socket.Blocking = _Blocking;
193 throw new TimeoutException("The send operation would block", ex);
194 case SocketError.TimedOut:
195 throw new TimeoutException("The send operation timed out", ex);
196 case SocketError.ConnectionReset:
197 case SocketError.Disconnecting:
198 case SocketError.NetworkDown:
199 case SocketError.NetworkReset:
200 case SocketError.NetworkUnreachable:
201 case SocketError.NotConnected:
202 Close();
203 throw new SocketException((int)ex.SocketErrorCode);
204 default:
205 throw new SocketException((int)ex.SocketErrorCode);
206 }
207 }
208 _BytesWritten += (ulong)size;
209 Interlocked.Add(ref _totalBytesWritten, (long)size);
210 }
211
212 public override void Close() {
213 System.Net.Sockets.Socket s = Interlocked.Exchange(ref _Socket, null);
214 try {
215 if (s != null) {
216 try {
217 if (s.Connected) s.Shutdown(SocketShutdown.Both);
218 } catch { }
219 s.Close();
220 }
221 } finally {
222 base.Close();
223 if (Closed != null) Closed(this, new EventArgs());
224 }
225 }
226
227 public bool Connected {
228 get {
229 if (Socket == null) return false;
230 if (Socket.Connected) return true;
231 Close();
232 return false;
233 }
234 }
235
236 public object Tag { get; set; }
237
238 public ulong BytesWritten { get { return _BytesWritten; } }
239 public ulong BytesRead { get { return _BytesRead; } }
240 public TimeSpan Age { get { return DateTime.Now.Subtract(_StartTime); } }
241 public EndPoint RemoteEndPoint {
242 get {
243 if (_Socket == null || !_Socket.Connected) return null;
244 try {
245 return _Socket.RemoteEndPoint;
246 } catch (SocketException) {
247 return null;
248 }
249 }
250 }
251 //public Object Proxy { get { return null; } }
252 Object INetworkConnection.Handler { get { return Tag; } }
253 }
254 }