You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
5.6 KiB
135 lines
5.6 KiB
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
|
|
namespace Apewer.Network
|
|
{
|
|
|
|
/// <summary>TCP 客户端。</summary>
|
|
public class TcpClient : IDisposable
|
|
{
|
|
|
|
Socket _socket = null;
|
|
|
|
/// <summary>套接字实例。</summary>
|
|
public Socket Socket { get => _socket; }
|
|
|
|
/// <summary>在线。</summary>
|
|
public bool Online { get => NetworkUtility.Online(_socket); }
|
|
|
|
/// <summary>本地终结点。</summary>
|
|
public IPEndPoint LocalEndPoint { get; private set; }
|
|
|
|
/// <summary>远程终结点。</summary>
|
|
public IPEndPoint RemoteEndPoint { get; private set; }
|
|
|
|
/// <summary>启动客户端,并连接到服务端。</summary>
|
|
/// <param name="ip">远程 IP 地址。</param>
|
|
/// <param name="port">远程端口号。</param>
|
|
/// <exception cref="ArgumentOutOfRangeException" />
|
|
/// <exception cref="FormatException" />
|
|
/// <exception cref="SocketException" />
|
|
public TcpClient(string ip, int port) : this(new IPEndPoint(IPAddress.Parse(ip), port), 0) { }
|
|
|
|
/// <summary>启动客户端,并连接到服务端。</summary>
|
|
/// <param name="ip">远程 IP 地址。</param>
|
|
/// <param name="port">远程端口号。</param>
|
|
/// <param name="timeout">连接超时毫秒数。当达到指定时长,或达到系统默认时长时,将会发生超时异常。</param>
|
|
/// <exception cref="ArgumentOutOfRangeException" />
|
|
/// <exception cref="FormatException" />
|
|
/// <exception cref="SocketException" />
|
|
public TcpClient(string ip, int port, int timeout) : this(new IPEndPoint(IPAddress.Parse(ip), port), timeout) { }
|
|
|
|
/// <summary>启动客户端,并连接到服务端。</summary>
|
|
/// <param name="ip">远程 IP 地址。</param>
|
|
/// <param name="port">远程端口号。</param>
|
|
/// <exception cref="ArgumentNullException" />
|
|
/// <exception cref="ArgumentOutOfRangeException" />
|
|
/// <exception cref="SocketException" />
|
|
public TcpClient(IPAddress ip, int port) : this(new IPEndPoint(ip, port), 0) { }
|
|
|
|
/// <summary>启动客户端,并连接到服务端。</summary>
|
|
/// <param name="ip">远程 IP 地址。</param>
|
|
/// <param name="port">远程端口号。</param>
|
|
/// <param name="timeout">连接超时毫秒数。当达到指定时长,或达到系统默认时长时,将会发生超时异常。</param>
|
|
/// <exception cref="ArgumentNullException" />
|
|
/// <exception cref="ArgumentOutOfRangeException" />
|
|
/// <exception cref="SocketException" />
|
|
public TcpClient(IPAddress ip, int port, int timeout) : this(new IPEndPoint(ip, port), timeout) { }
|
|
|
|
/// <summary>启动客户端,并连接到服务端。</summary>
|
|
public TcpClient(IPEndPoint endpoint) : this(endpoint, 0) { }
|
|
|
|
/// <summary>启动客户端,并连接到服务端。</summary>
|
|
/// <param name="endpoint">远程终结点。</param>
|
|
/// <param name="timeout">连接超时毫秒数。当达到指定时长,或达到系统默认时长时,将会发生超时异常。</param>
|
|
/// <exception cref="ArgumentNullException" />
|
|
/// <exception cref="ArgumentOutOfRangeException" />
|
|
/// <exception cref="SocketException" />
|
|
public TcpClient(IPEndPoint endpoint, int timeout)
|
|
{
|
|
if (endpoint == null) throw new ArgumentNullException(nameof(endpoint));
|
|
if (timeout < 1) throw new ArgumentOutOfRangeException(nameof(timeout));
|
|
|
|
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
if (timeout > 0)
|
|
{
|
|
RuntimeUtility.InBackground(timeout, () =>
|
|
{
|
|
if (!_socket.Connected)
|
|
{
|
|
_socket.Close();
|
|
#if !NET20
|
|
_socket.Dispose();
|
|
#endif
|
|
}
|
|
}, true);
|
|
}
|
|
try
|
|
{
|
|
_socket.Connect(endpoint);
|
|
_socket.SendTimeout = 5000;
|
|
LocalEndPoint = _socket.LocalEndPoint as IPEndPoint;
|
|
RemoteEndPoint = endpoint;
|
|
}
|
|
catch (SocketException ex)
|
|
{
|
|
if (ex.SocketErrorCode == SocketError.NotSocket)
|
|
{
|
|
throw new SocketException((int)SocketError.TimedOut);
|
|
}
|
|
throw new Exception($"{ex.ErrorCode} {ex.SocketErrorCode}: {ex.Message}");
|
|
}
|
|
catch
|
|
{
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>关闭连接,释放系统资源。</summary>
|
|
public void Dispose()
|
|
{
|
|
try { _socket.Disconnect(false); } catch { }
|
|
try { _socket.Close(100); } catch { }
|
|
#if !NET20
|
|
try { _socket.Dispose(); } catch { }
|
|
#endif
|
|
}
|
|
|
|
/// <summary>接收。</summary>
|
|
/// <exception cref="ArgumentNullException"></exception>
|
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
/// <exception cref="SocketException"></exception>
|
|
/// <exception cref="ObjectDisposedException"></exception>
|
|
/// <exception cref="System.Security.SecurityException"></exception>
|
|
public byte[] Receive(int maxLength = 1024) => _socket.Receive(maxLength);
|
|
|
|
/// <summary>发送。</summary>
|
|
/// <exception cref="ArgumentNullException" />
|
|
/// <exception cref="SocketException" />
|
|
/// <exception cref="ObjectDisposedException" />
|
|
public void Send(byte[] data) => _socket.Send(data);
|
|
|
|
}
|
|
|
|
}
|
|
|