You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
@@ -45,7 +45,7 @@ namespace System.Net.Sockets {
|
||||
int error = 0;
|
||||
|
||||
Socket.Blocking_internal (handle, false, out error);
|
||||
#if MOBILE_STATIC
|
||||
#if FULL_AOT_DESKTOP
|
||||
/* It's only for platforms that do not have working syscall abort mechanism, like WatchOS and TvOS */
|
||||
Socket.Shutdown_internal (handle, SocketShutdown.Both, out error);
|
||||
#endif
|
||||
@@ -127,9 +127,12 @@ namespace System.Net.Sockets {
|
||||
{
|
||||
//If this NRE, we're in deep problems because Register Must have
|
||||
lock (blocking_threads) {
|
||||
blocking_threads.Remove (Thread.CurrentThread);
|
||||
if (THROW_ON_ABORT_RETRIES)
|
||||
threads_stacktraces.Remove (Thread.CurrentThread);
|
||||
var current = Thread.CurrentThread;
|
||||
blocking_threads.Remove (current);
|
||||
if (THROW_ON_ABORT_RETRIES) {
|
||||
if (blocking_threads.IndexOf (current) == -1)
|
||||
threads_stacktraces.Remove (current);
|
||||
}
|
||||
|
||||
if (in_cleanup && blocking_threads.Count == 0)
|
||||
Monitor.Pulse (blocking_threads);
|
||||
|
@@ -1,89 +0,0 @@
|
||||
// System.Net.Sockets.SocketAsyncEventArgs.cs
|
||||
//
|
||||
// Authors:
|
||||
// Marek Habersack (mhabersack@novell.com)
|
||||
//
|
||||
// Copyright (c) 2008 Novell, Inc. (http://www.novell.com)
|
||||
//
|
||||
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
using System;
|
||||
|
||||
namespace System.Net.Sockets
|
||||
{
|
||||
public class SendPacketsElement
|
||||
{
|
||||
public byte[] Buffer { get; private set; }
|
||||
public int Count { get; private set; }
|
||||
public bool EndOfPacket { get; private set; }
|
||||
public string FilePath { get; private set; }
|
||||
public int Offset { get; private set; }
|
||||
|
||||
public SendPacketsElement (byte[] buffer) : this (buffer, 0, buffer != null ? buffer.Length : 0)
|
||||
{
|
||||
}
|
||||
|
||||
public SendPacketsElement (byte[] buffer, int offset, int count) : this (buffer, offset, count, false)
|
||||
{
|
||||
}
|
||||
|
||||
public SendPacketsElement (byte[] buffer, int offset, int count, bool endOfPacket)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException ("buffer");
|
||||
|
||||
int buflen = buffer.Length;
|
||||
if (offset < 0 || offset >= buflen)
|
||||
throw new ArgumentOutOfRangeException ("offset");
|
||||
|
||||
if (count < 0 || offset + count >= buflen)
|
||||
throw new ArgumentOutOfRangeException ("count");
|
||||
|
||||
Buffer = buffer;
|
||||
Offset = offset;
|
||||
Count = count;
|
||||
EndOfPacket = endOfPacket;
|
||||
FilePath = null;
|
||||
}
|
||||
|
||||
public SendPacketsElement (string filepath) : this (filepath, 0, 0, false)
|
||||
{
|
||||
}
|
||||
|
||||
public SendPacketsElement (string filepath, int offset, int count) : this (filepath, offset, count, false)
|
||||
{
|
||||
}
|
||||
|
||||
// LAME SPEC: only ArgumentNullException for filepath is thrown
|
||||
public SendPacketsElement (string filepath, int offset, int count, bool endOfPacket)
|
||||
{
|
||||
if (filepath == null)
|
||||
throw new ArgumentNullException ("filepath");
|
||||
|
||||
Buffer = null;
|
||||
Offset = offset;
|
||||
Count = count;
|
||||
EndOfPacket = endOfPacket;
|
||||
FilePath = filepath;
|
||||
}
|
||||
}
|
||||
}
|
2786
mcs/class/System/System.Net.Sockets/Socket.cs
Normal file
2786
mcs/class/System/System.Net.Sockets/Socket.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
64363911e4072d3b513ab012ba99c8b2a99ce860
|
@@ -1,44 +0,0 @@
|
||||
// System.Net.Sockets.SocketAsyncOperation.cs
|
||||
//
|
||||
// Authors:
|
||||
// Marek Habersack (mhabersack@novell.com)
|
||||
//
|
||||
// Copyright (c) 2008 Novell, Inc. (http://www.novell.com)
|
||||
//
|
||||
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
namespace System.Net.Sockets
|
||||
{
|
||||
public enum SocketAsyncOperation
|
||||
{
|
||||
None,
|
||||
Accept,
|
||||
Connect,
|
||||
Disconnect,
|
||||
Receive,
|
||||
ReceiveFrom,
|
||||
ReceiveMessageFrom,
|
||||
Send,
|
||||
SendPackets,
|
||||
SendTo
|
||||
}
|
||||
}
|
@@ -140,52 +140,41 @@ namespace System.Net.Sockets
|
||||
|
||||
public void Complete ()
|
||||
{
|
||||
if (operation != SocketOperation.Receive && socket.is_disposed)
|
||||
if (operation != SocketOperation.Receive && socket.CleanedUp)
|
||||
DelayedException = new ObjectDisposedException (socket.GetType ().ToString ());
|
||||
|
||||
IsCompleted = true;
|
||||
|
||||
/* It is possible that this.socket is modified by this.Init which has been called by the callback. This
|
||||
* would lead to inconsistency, as we would for example not release the correct socket.ReadSem or
|
||||
* socket.WriteSem.
|
||||
* For example, this can happen with AcceptAsync followed by a ReceiveAsync on the same
|
||||
* SocketAsyncEventArgs */
|
||||
Socket completedSocket = socket;
|
||||
SocketOperation completedOperation = operation;
|
||||
|
||||
AsyncCallback callback = AsyncCallback;
|
||||
if (callback != null) {
|
||||
ThreadPool.UnsafeQueueUserWorkItem (_ => callback (this), null);
|
||||
}
|
||||
|
||||
Queue<KeyValuePair<IntPtr, IOSelectorJob>> queue = null;
|
||||
switch (operation) {
|
||||
/* Warning: any field on the current SocketAsyncResult might have changed, as the callback might have
|
||||
* called this.Init */
|
||||
|
||||
switch (completedOperation) {
|
||||
case SocketOperation.Receive:
|
||||
case SocketOperation.ReceiveFrom:
|
||||
case SocketOperation.ReceiveGeneric:
|
||||
case SocketOperation.Accept:
|
||||
queue = socket.readQ;
|
||||
completedSocket.ReadSem.Release ();
|
||||
break;
|
||||
case SocketOperation.Send:
|
||||
case SocketOperation.SendTo:
|
||||
case SocketOperation.SendGeneric:
|
||||
queue = socket.writeQ;
|
||||
completedSocket.WriteSem.Release ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (queue != null) {
|
||||
lock (queue) {
|
||||
/* queue.Count will only be 0 if the socket is closed while receive/send/accept
|
||||
* operation(s) are pending and at least one call to this method is waiting
|
||||
* on the lock while another one calls CompleteAllOnDispose() */
|
||||
if (queue.Count > 0)
|
||||
queue.Dequeue (); /* remove ourselves */
|
||||
if (queue.Count > 0) {
|
||||
if (!socket.is_disposed) {
|
||||
IOSelector.Add (queue.Peek ().Key, queue.Peek ().Value);
|
||||
} else {
|
||||
/* CompleteAllOnDispose */
|
||||
KeyValuePair<IntPtr, IOSelectorJob> [] jobs = queue.ToArray ();
|
||||
for (int i = 0; i < jobs.Length; i++)
|
||||
ThreadPool.QueueUserWorkItem (j => ((IOSelectorJob) j).MarkDisposed (), jobs [i].Value);
|
||||
queue.Clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMPORTANT: 'callback', if any is scheduled from unmanaged code
|
||||
}
|
||||
|
||||
|
@@ -1,450 +0,0 @@
|
||||
// TcpClient.cs
|
||||
//
|
||||
// Author:
|
||||
// Phillip Pearson (pp@myelin.co.nz)
|
||||
// Gonzalo Paniagua Javier (gonzalo@novell.com)
|
||||
// Sridhar Kulkarni (sridharkulkarni@gmail.com)
|
||||
// Marek Safar (marek.safar@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2001, Phillip Pearson http://www.myelin.co.nz
|
||||
// Copyright (c) 2006 Novell, Inc. (http://www.novell.com)
|
||||
// Copyright 2011 Xamarin Inc.
|
||||
//
|
||||
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Net.Sockets
|
||||
{
|
||||
public class TcpClient : IDisposable {
|
||||
enum Properties : uint {
|
||||
LingerState = 1,
|
||||
NoDelay = 2,
|
||||
ReceiveBufferSize = 4,
|
||||
ReceiveTimeout = 8,
|
||||
SendBufferSize = 16,
|
||||
SendTimeout = 32
|
||||
}
|
||||
|
||||
// private data
|
||||
NetworkStream stream;
|
||||
bool active;
|
||||
Socket client;
|
||||
bool disposed;
|
||||
Properties values;
|
||||
int recv_timeout, send_timeout;
|
||||
int recv_buffer_size, send_buffer_size;
|
||||
LingerOption linger_state;
|
||||
bool no_delay;
|
||||
|
||||
private void Init (AddressFamily family)
|
||||
{
|
||||
active = false;
|
||||
|
||||
if(client != null) {
|
||||
client.Close();
|
||||
client = null;
|
||||
}
|
||||
|
||||
client = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
|
||||
}
|
||||
|
||||
public TcpClient ()
|
||||
{
|
||||
Init(AddressFamily.InterNetwork);
|
||||
client.Bind(new IPEndPoint(IPAddress.Any, 0));
|
||||
}
|
||||
|
||||
internal TcpClient (Socket s)
|
||||
{
|
||||
client = s;
|
||||
}
|
||||
|
||||
public TcpClient (AddressFamily family)
|
||||
{
|
||||
if (family != AddressFamily.InterNetwork &&
|
||||
family != AddressFamily.InterNetworkV6) {
|
||||
throw new ArgumentException ("Family must be InterNetwork or InterNetworkV6", "family");
|
||||
}
|
||||
|
||||
Init (family);
|
||||
IPAddress any = IPAddress.Any;
|
||||
if (family == AddressFamily.InterNetworkV6)
|
||||
any = IPAddress.IPv6Any;
|
||||
client.Bind (new IPEndPoint (any, 0));
|
||||
}
|
||||
|
||||
public TcpClient (IPEndPoint localEP)
|
||||
{
|
||||
Init (localEP.AddressFamily);
|
||||
client.Bind (localEP);
|
||||
}
|
||||
|
||||
public TcpClient (string hostname, int port)
|
||||
{
|
||||
Connect(hostname, port);
|
||||
}
|
||||
|
||||
protected bool Active {
|
||||
get { return active; }
|
||||
set { active = value; }
|
||||
}
|
||||
|
||||
public Socket Client {
|
||||
get { return client; }
|
||||
set {
|
||||
client = value;
|
||||
stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
public int Available {
|
||||
get { return client.Available; }
|
||||
}
|
||||
|
||||
public bool Connected {
|
||||
get { return client.Connected; }
|
||||
}
|
||||
|
||||
public bool ExclusiveAddressUse {
|
||||
get {
|
||||
return(client.ExclusiveAddressUse);
|
||||
}
|
||||
set {
|
||||
client.ExclusiveAddressUse = value;
|
||||
}
|
||||
}
|
||||
|
||||
public LingerOption LingerState {
|
||||
get {
|
||||
if ((values & Properties.LingerState) != 0)
|
||||
return linger_state;
|
||||
|
||||
return (LingerOption) client.GetSocketOption (SocketOptionLevel.Socket,
|
||||
SocketOptionName.Linger);
|
||||
}
|
||||
set {
|
||||
if (!client.Connected) {
|
||||
linger_state = value;
|
||||
values |= Properties.LingerState;
|
||||
return;
|
||||
}
|
||||
client.SetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.Linger, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool NoDelay {
|
||||
get {
|
||||
if ((values & Properties.NoDelay) != 0)
|
||||
return no_delay;
|
||||
|
||||
return (bool)client.GetSocketOption(
|
||||
SocketOptionLevel.Tcp,
|
||||
SocketOptionName.NoDelay);
|
||||
}
|
||||
set {
|
||||
if (!client.Connected) {
|
||||
no_delay = value;
|
||||
values |= Properties.NoDelay;
|
||||
return;
|
||||
}
|
||||
client.SetSocketOption(
|
||||
SocketOptionLevel.Tcp,
|
||||
SocketOptionName.NoDelay, value ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int ReceiveBufferSize {
|
||||
get {
|
||||
if ((values & Properties.ReceiveBufferSize) != 0)
|
||||
return recv_buffer_size;
|
||||
|
||||
return (int)client.GetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.ReceiveBuffer);
|
||||
}
|
||||
set {
|
||||
if (!client.Connected) {
|
||||
recv_buffer_size = value;
|
||||
values |= Properties.ReceiveBufferSize;
|
||||
return;
|
||||
}
|
||||
client.SetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.ReceiveBuffer, value);
|
||||
}
|
||||
}
|
||||
|
||||
public int ReceiveTimeout {
|
||||
get {
|
||||
if ((values & Properties.ReceiveTimeout) != 0)
|
||||
return recv_timeout;
|
||||
|
||||
return (int)client.GetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.ReceiveTimeout);
|
||||
}
|
||||
set {
|
||||
if (!client.Connected) {
|
||||
recv_timeout = value;
|
||||
values |= Properties.ReceiveTimeout;
|
||||
return;
|
||||
}
|
||||
client.SetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.ReceiveTimeout, value);
|
||||
}
|
||||
}
|
||||
|
||||
public int SendBufferSize {
|
||||
get {
|
||||
if ((values & Properties.SendBufferSize) != 0)
|
||||
return send_buffer_size;
|
||||
|
||||
return (int)client.GetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.SendBuffer);
|
||||
}
|
||||
set {
|
||||
if (!client.Connected) {
|
||||
send_buffer_size = value;
|
||||
values |= Properties.SendBufferSize;
|
||||
return;
|
||||
}
|
||||
client.SetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.SendBuffer, value);
|
||||
}
|
||||
}
|
||||
|
||||
public int SendTimeout {
|
||||
get {
|
||||
if ((values & Properties.SendTimeout) != 0)
|
||||
return send_timeout;
|
||||
|
||||
return (int)client.GetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.SendTimeout);
|
||||
}
|
||||
set {
|
||||
if (!client.Connected) {
|
||||
send_timeout = value;
|
||||
values |= Properties.SendTimeout;
|
||||
return;
|
||||
}
|
||||
client.SetSocketOption(
|
||||
SocketOptionLevel.Socket,
|
||||
SocketOptionName.SendTimeout, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// methods
|
||||
|
||||
public void Close ()
|
||||
{
|
||||
Dispose ();
|
||||
}
|
||||
|
||||
public void Connect (IPEndPoint remoteEP)
|
||||
{
|
||||
try {
|
||||
client.Connect (remoteEP);
|
||||
active = true;
|
||||
} finally {
|
||||
CheckDisposed ();
|
||||
}
|
||||
}
|
||||
|
||||
public void Connect (IPAddress address, int port)
|
||||
{
|
||||
Connect(new IPEndPoint(address, port));
|
||||
}
|
||||
|
||||
void SetOptions ()
|
||||
{
|
||||
Properties props = values;
|
||||
values = 0;
|
||||
|
||||
if ((props & Properties.LingerState) != 0)
|
||||
LingerState = linger_state;
|
||||
if ((props & Properties.NoDelay) != 0)
|
||||
NoDelay = no_delay;
|
||||
if ((props & Properties.ReceiveBufferSize) != 0)
|
||||
ReceiveBufferSize = recv_buffer_size;
|
||||
if ((props & Properties.ReceiveTimeout) != 0)
|
||||
ReceiveTimeout = recv_timeout;
|
||||
if ((props & Properties.SendBufferSize) != 0)
|
||||
SendBufferSize = send_buffer_size;
|
||||
if ((props & Properties.SendTimeout) != 0)
|
||||
SendTimeout = send_timeout;
|
||||
}
|
||||
|
||||
public void Connect (string hostname, int port)
|
||||
{
|
||||
IPAddress [] addresses = Dns.GetHostAddresses (hostname);
|
||||
Connect (addresses, port);
|
||||
}
|
||||
|
||||
public void Connect (IPAddress[] ipAddresses, int port)
|
||||
{
|
||||
CheckDisposed ();
|
||||
|
||||
if (ipAddresses == null) {
|
||||
throw new ArgumentNullException ("ipAddresses");
|
||||
}
|
||||
|
||||
for(int i = 0; i < ipAddresses.Length; i++) {
|
||||
try {
|
||||
IPAddress address = ipAddresses[i];
|
||||
|
||||
if (address.Equals (IPAddress.Any) ||
|
||||
address.Equals (IPAddress.IPv6Any)) {
|
||||
throw new SocketException ((int)SocketError.AddressNotAvailable);
|
||||
}
|
||||
|
||||
Init (address.AddressFamily);
|
||||
|
||||
if (address.AddressFamily == AddressFamily.InterNetwork) {
|
||||
client.Bind (new IPEndPoint (IPAddress.Any, 0));
|
||||
} else if (address.AddressFamily == AddressFamily.InterNetworkV6) {
|
||||
client.Bind (new IPEndPoint (IPAddress.IPv6Any, 0));
|
||||
} else {
|
||||
throw new NotSupportedException ("This method is only valid for sockets in the InterNetwork and InterNetworkV6 families");
|
||||
}
|
||||
|
||||
Connect (new IPEndPoint (address, port));
|
||||
|
||||
if (values != 0) {
|
||||
SetOptions ();
|
||||
}
|
||||
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
/* Reinitialise the socket so
|
||||
* other properties still work
|
||||
* (see no-arg constructor)
|
||||
*/
|
||||
Init (AddressFamily.InterNetwork);
|
||||
|
||||
/* This is the last known
|
||||
* address, so re-throw the
|
||||
* exception
|
||||
*/
|
||||
if (i == ipAddresses.Length - 1) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EndConnect (IAsyncResult asyncResult)
|
||||
{
|
||||
client.EndConnect (asyncResult);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginConnect (IPAddress address, int port, AsyncCallback requestCallback, object state)
|
||||
{
|
||||
return client.BeginConnect (address, port, requestCallback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginConnect (IPAddress[] addresses, int port, AsyncCallback requestCallback, object state)
|
||||
{
|
||||
return client.BeginConnect (addresses, port, requestCallback, state);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginConnect (string host, int port, AsyncCallback requestCallback, object state)
|
||||
{
|
||||
return client.BeginConnect (host, port, requestCallback, state);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
disposed = true;
|
||||
|
||||
if (disposing) {
|
||||
// release managed resources
|
||||
NetworkStream s = stream;
|
||||
stream = null;
|
||||
if (s != null) {
|
||||
// This closes the socket as well, as the NetworkStream
|
||||
// owns the socket.
|
||||
s.Close();
|
||||
active = false;
|
||||
s = null;
|
||||
} else if (client != null){
|
||||
client.Close ();
|
||||
client = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~TcpClient ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
public NetworkStream GetStream()
|
||||
{
|
||||
try {
|
||||
if (stream == null)
|
||||
stream = new NetworkStream (client, true);
|
||||
return stream;
|
||||
}
|
||||
finally { CheckDisposed (); }
|
||||
}
|
||||
|
||||
public Task ConnectAsync (IPAddress address, int port)
|
||||
{
|
||||
return Task.Factory.FromAsync (BeginConnect, EndConnect, address, port, null);
|
||||
}
|
||||
|
||||
public Task ConnectAsync (IPAddress[] addresses, int port)
|
||||
{
|
||||
return Task.Factory.FromAsync (BeginConnect, EndConnect, addresses, port, null);
|
||||
}
|
||||
|
||||
public Task ConnectAsync (string host, int port)
|
||||
{
|
||||
return Task.Factory.FromAsync (BeginConnect, EndConnect, host, port, null);
|
||||
}
|
||||
private void CheckDisposed ()
|
||||
{
|
||||
if (disposed)
|
||||
throw new ObjectDisposedException (GetType().FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,335 +0,0 @@
|
||||
// TcpListener.cs
|
||||
//
|
||||
// Authors:
|
||||
// Phillip Pearson (pp@myelin.co.nz)
|
||||
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
|
||||
// Patrik Torstensson
|
||||
// Sridhar Kulkarni (sridharkulkarni@gmail.com)
|
||||
// Marek Safar (marek.safar@gmail.com)
|
||||
|
||||
//
|
||||
// Copyright (C) 2001, Phillip Pearson http://www.myelin.co.nz
|
||||
//
|
||||
// (c) 2003 Ximian, Inc. (http://www.ximian.com)
|
||||
// (c) 2004-2006 Novell, Inc.
|
||||
// Copyright 2011 Xamarin Inc.
|
||||
//
|
||||
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Net.Sockets
|
||||
{
|
||||
/// <remarks>
|
||||
/// A slightly more abstracted way to listen for incoming
|
||||
/// network connections than a Socket.
|
||||
/// </remarks>
|
||||
public class TcpListener
|
||||
{
|
||||
// private data
|
||||
|
||||
bool active;
|
||||
Socket server;
|
||||
EndPoint savedEP;
|
||||
|
||||
// constructor
|
||||
|
||||
/// <summary>
|
||||
/// Some code that is shared between the constructors.
|
||||
/// </summary>
|
||||
private void Init (AddressFamily family, EndPoint ep)
|
||||
{
|
||||
active = false;
|
||||
server = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
|
||||
savedEP = ep;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new TcpListener to listen on a specified port
|
||||
/// </summary>
|
||||
/// <param name="port">The port to listen on, e.g. 80 if you
|
||||
/// are a web server</param>
|
||||
[Obsolete ("Use TcpListener (IPAddress address, int port) instead")]
|
||||
public TcpListener (int port)
|
||||
{
|
||||
if (port < 0 || port > 65535)
|
||||
throw new ArgumentOutOfRangeException ("port");
|
||||
|
||||
Init (AddressFamily.InterNetwork, new IPEndPoint (IPAddress.Any, port));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new TcpListener with a specified local endpoint
|
||||
/// </summary>
|
||||
/// <param name="local_end_point">The endpoint</param>
|
||||
public TcpListener (IPEndPoint localEP)
|
||||
{
|
||||
if (localEP == null)
|
||||
throw new ArgumentNullException ("localEP");
|
||||
|
||||
Init (localEP.AddressFamily, localEP);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new TcpListener, listening on a specified port
|
||||
/// and IP (for use on a multi-homed machine)
|
||||
/// </summary>
|
||||
/// <param name="listen_ip">The IP to listen on</param>
|
||||
/// <param name="port">The port to listen on</param>
|
||||
public TcpListener (IPAddress localaddr, int port)
|
||||
{
|
||||
if (localaddr == null)
|
||||
throw new ArgumentNullException ("localaddr");
|
||||
|
||||
if (port < 0 || port > 65535)
|
||||
throw new ArgumentOutOfRangeException ("port");
|
||||
|
||||
Init (localaddr.AddressFamily, new IPEndPoint (localaddr, port));
|
||||
}
|
||||
|
||||
|
||||
// properties
|
||||
|
||||
/// <summary>
|
||||
/// A flag that is 'true' if the TcpListener is listening,
|
||||
/// or 'false' if it is not listening
|
||||
/// </summary>
|
||||
protected bool Active
|
||||
{
|
||||
get { return active; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The local end point
|
||||
/// </summary>
|
||||
public EndPoint LocalEndpoint
|
||||
{
|
||||
get {
|
||||
if (active)
|
||||
return server.LocalEndPoint;
|
||||
|
||||
return savedEP;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The listening socket
|
||||
/// </summary>
|
||||
public Socket Server
|
||||
{
|
||||
get { return server; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies whether the TcpListener allows only one
|
||||
/// underlying socket to listen to a specific port
|
||||
/// </summary>
|
||||
public bool ExclusiveAddressUse
|
||||
{
|
||||
get {
|
||||
if (server == null) {
|
||||
throw new ObjectDisposedException (GetType ().ToString ());
|
||||
}
|
||||
if (active) {
|
||||
throw new InvalidOperationException ("The TcpListener has been started");
|
||||
}
|
||||
|
||||
return(server.ExclusiveAddressUse);
|
||||
}
|
||||
set {
|
||||
if (server == null) {
|
||||
throw new ObjectDisposedException (GetType ().ToString ());
|
||||
}
|
||||
if (active) {
|
||||
throw new InvalidOperationException ("The TcpListener has been started");
|
||||
}
|
||||
|
||||
server.ExclusiveAddressUse = value;
|
||||
}
|
||||
}
|
||||
|
||||
// methods
|
||||
|
||||
/// <summary>
|
||||
/// Accepts a pending connection
|
||||
/// </summary>
|
||||
/// <returns>A Socket object for the new connection</returns>
|
||||
public Socket AcceptSocket ()
|
||||
{
|
||||
if (!active)
|
||||
throw new InvalidOperationException ("Socket is not listening");
|
||||
|
||||
return server.Accept();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accepts a pending connection
|
||||
/// </summary>
|
||||
/// <returns>A TcpClient
|
||||
/// object made from the new socket.</returns>
|
||||
public TcpClient AcceptTcpClient ()
|
||||
{
|
||||
if (!active)
|
||||
throw new InvalidOperationException ("Socket is not listening");
|
||||
|
||||
Socket clientSocket = server.Accept ();
|
||||
|
||||
TcpClient client = new TcpClient(clientSocket);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
public void AllowNatTraversal (bool allowed)
|
||||
{
|
||||
if (active)
|
||||
throw new InvalidOperationException (SR.GetString (SR.net_tcplistener_mustbestopped));
|
||||
|
||||
if (allowed)
|
||||
server.SetIPProtectionLevel (IPProtectionLevel.Unrestricted);
|
||||
else
|
||||
server.SetIPProtectionLevel (IPProtectionLevel.EdgeRestricted);
|
||||
}
|
||||
|
||||
public static TcpListener Create (int port)
|
||||
{
|
||||
if (port < 0 || port > 65535)
|
||||
throw new ArgumentOutOfRangeException ("port");
|
||||
|
||||
TcpListener listener = new TcpListener (IPAddress.IPv6Any, port);
|
||||
listener.Server.DualMode = true;
|
||||
|
||||
return listener;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructor - stops the listener listening
|
||||
/// </summary>
|
||||
~TcpListener ()
|
||||
{
|
||||
if (active)
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// Returns 'true' if there is a connection waiting to be accepted
|
||||
/// with AcceptSocket() or AcceptTcpClient().
|
||||
/// </returns>
|
||||
public bool Pending ()
|
||||
{
|
||||
if (!active)
|
||||
throw new InvalidOperationException ("Socket is not listening");
|
||||
|
||||
return server.Poll(0, SelectMode.SelectRead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the TcpListener to start listening.
|
||||
/// </summary>
|
||||
public void Start ()
|
||||
{
|
||||
// MS: sets Listen to Int32.MaxValue
|
||||
this.Start (5);
|
||||
// According to the man page some BSD and BSD-derived
|
||||
// systems limit the backlog to 5. This should really be
|
||||
// configurable though
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the TcpListener to start listening for max number
|
||||
/// of pending connections.
|
||||
/// </summary>
|
||||
|
||||
public void Start (int backlog)
|
||||
{
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
if (server == null) {
|
||||
throw new InvalidOperationException ("Invalid server socket");
|
||||
}
|
||||
|
||||
server.Bind (savedEP);
|
||||
server.Listen (backlog);
|
||||
active = true;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginAcceptSocket (AsyncCallback callback,
|
||||
object state)
|
||||
{
|
||||
if (server == null) {
|
||||
throw new ObjectDisposedException (GetType ().ToString ());
|
||||
}
|
||||
|
||||
return(server.BeginAccept (callback, state));
|
||||
}
|
||||
|
||||
public IAsyncResult BeginAcceptTcpClient (AsyncCallback callback, object state)
|
||||
{
|
||||
if (server == null) {
|
||||
throw new ObjectDisposedException (GetType ().ToString ());
|
||||
}
|
||||
|
||||
return(server.BeginAccept (callback, state));
|
||||
}
|
||||
|
||||
public Socket EndAcceptSocket (IAsyncResult asyncResult)
|
||||
{
|
||||
return(server.EndAccept (asyncResult));
|
||||
}
|
||||
|
||||
public TcpClient EndAcceptTcpClient (IAsyncResult asyncResult)
|
||||
{
|
||||
Socket clientSocket = server.EndAccept (asyncResult);
|
||||
TcpClient client = new TcpClient (clientSocket);
|
||||
|
||||
return(client);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the TcpListener to stop listening and dispose
|
||||
/// of all managed resources.
|
||||
/// </summary>
|
||||
public void Stop ()
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
server.Close ();
|
||||
server = null;
|
||||
}
|
||||
|
||||
Init (AddressFamily.InterNetwork, savedEP);
|
||||
}
|
||||
|
||||
public Task<Socket> AcceptSocketAsync ()
|
||||
{
|
||||
return Task<Socket>.Factory.FromAsync (BeginAcceptSocket, EndAcceptSocket, null);
|
||||
}
|
||||
|
||||
public Task<TcpClient> AcceptTcpClientAsync ()
|
||||
{
|
||||
return Task<TcpClient>.Factory.FromAsync (BeginAcceptTcpClient, EndAcceptTcpClient, null);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user