1使用说明
- 添加接受数据回调函数事件
方式1:通过有参构造函数添加
方式2:调用:public EventHandler<byte[]> AddEventToDataReceived
- 添加输出日志回调函数事件
方式1:通过有参构造函数添加
方式2:调用:public Action<EMessage, IPEndPoint, int, string> AddEventToOutLog
- 客户端接受数据线程的数据如何输出日志信息
方式:设置属性【OutputReceivedLog 】
类型:Null :不输出
Length:仅输出接受数据的长度信息
UTF8:UTF8-解析输出
ASCII:ASCII-解析输出
ByteToString:输出字节的字符串形式
- 获取当前客户端IP地址和端口号,获取属性【Client】的值;
- 获取当前客户端连接的服务器的IP地址和端口号,获取属性【Server】的值;
- 方法
连接服务器:bool ConnectServer(string ip, int port)
关闭客户端:void CloseClient()
连接状态:bool IsConnect { get; private set; }
发送消息:bool Send(byte[] array)
- 消息类型
2封装工具类
using System;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Tcp_Client
{
public class ClientModel
{
private TcpClient _client;
/// <summary>
/// 远程终端
/// </summary>
private IPEndPoint _remoteEP;
/// <summary>
/// 本地终端
/// </summary>
private IPEndPoint _localEP;
/// <summary>
/// 接受消息回调函数
/// </summary>
private EventHandler<byte[]> _callbackEventDataReceived;
/// <summary>
/// 日志信息回调函数
/// int:线程ID
/// </summary>
private Action<EMessage, IPEndPoint, int, string> _callbackEventOutLog;
/// <summary>
/// 客户端构造函数
/// </summary>
/// <param name="callbackEventDataReceived">接受消息回调函数</param>
/// <param name="callbackEventOutLog">日志信息回调函数;int:线程ID</param>
public ClientModel(EventHandler<byte[]> callbackEventDataReceived, Action<EMessage, IPEndPoint, int, string> callbackEventOutLog)
{
AddEventToDataReceived = callbackEventDataReceived;
AddEventToOutLog = callbackEventOutLog;
AddEventToDataReceived = DataReceived;
}
public ClientModel()
{
AddEventToDataReceived = DataReceived;
}
~ClientModel()
{
CloseClient();
}
/// <summary>
/// 连接服务器
/// </summary>
private void ConnectServer()
{
try
{
CloseClient();
// 创建一个 TCP 客户端,连接到服务器的 IP 地址和端口
_client = new TcpClient();
_client.Connect(_remoteEP);
AddLog(EMessage.State, "已连接到服务器。");
_localEP = (IPEndPoint)_client.Client.LocalEndPoint;
IsConnect = true;
// 客户端创建一个新的线程来处理通信
new Task(HandleClient).Start();
}
catch (Exception ex)
{
AddLog(EMessage.Exception, $"异常: {ex.Message}");
CloseClient();
}
}
private void HandleClient()
{
try
{
NetworkStream stream = _client.GetStream();
byte[] buffer = new byte[1024];
while (IsConnect)
{
// 异步读取客户端发送的消息
int bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
var received = new byte[bytesRead];
Array.Copy(buffer, 0, received, 0, bytesRead);
_callbackEventDataReceived?.Invoke(null, received);
}
}
catch (Exception ex)
{
AddLog(EMessage.Exception, "客户端接受数据线程异常:" + ex.Message);
}
}
private void DataReceived(object sensor, byte[] bytes)
{
string message;
switch (OutputReceivedLog)
{
case ETranscoding.Length:
message = bytes.Length.ToString();
break;
case ETranscoding.UTF8:
message = Encoding.UTF8.GetString(bytes);
break;
case ETranscoding.ASCII:
message = Encoding.ASCII.GetString(bytes);
break;
case ETranscoding.ByteToString:
var builder = new StringBuilder();
builder.Append("[ ");
foreach (var b in bytes)
{
builder.Append(Convert.ToString(b, 16).PadLeft(2, '0').ToUpper() + " ");
}
builder.Append("]");
message = builder.ToString();
break;
default:
return;
}
AddLog(EMessage.Receive, message);
}
private void AddLog(EMessage type, string message)
{
int threadId = Thread.CurrentThread.ManagedThreadId;
_callbackEventOutLog?.Invoke(type, _localEP, threadId, message);
}
/********隔离线********隔离线********隔离线********隔离线********隔离线********隔离线********隔离线********/
/// <summary>
/// 标识接受缓冲区获取到数据时输出日志信息的方式,默认:不输出
/// </summary>
public ETranscoding OutputReceivedLog { get; set; } = ETranscoding.Null;
public IPEndPoint Server => _remoteEP;
public IPEndPoint Client => _localEP;
public EventHandler<byte[]> AddEventToDataReceived
{
set
{
if (value != null) _callbackEventDataReceived += value;
}
}
public Action<EMessage, IPEndPoint, int, string> AddEventToOutLog
{
set
{
if (value != null) _callbackEventOutLog += value;
}
}
public bool ConnectServer(string ip, int port)
{
_remoteEP = new IPEndPoint(IPAddress.Parse(ip), port);
ConnectServer();
return IsConnect;
}
public void CloseClient()
{
if (IsConnect) _client.Close();
IsConnect = false;
try
{
if (_client != null)
{
_client.Dispose();
_client = null;
AddLog(EMessage.State, "断开服务器连接");
}
}
catch (Exception ex)
{
AddLog(EMessage.Exception, "断开服务器连接时异常:" + ex.Message);
}
}
public bool IsConnect { get; private set; }
public bool Send(byte[] array)
{
if (_client == null || _client.Connected == false)
{
AddLog(EMessage.Send, $"发送失败,请连接服务器!");
return false;
}
// 获取网络流
NetworkStream stream = _client.GetStream();
stream.Write(array, 0, array.Length);
return true;
}
public enum EMessage
{
[Description("状态信息")]
State = 1,
[Description("发送")]
Send = 3,
[Description("接受")]
Receive = 5,
[Description("异常")]
Exception = 7,
[Description("回复")]
Reply = 9,
}
/// <summary>
/// 接受缓冲区的字节码解析方式
/// </summary>
public enum ETranscoding
{
/// <summary>
/// 不输出
/// </summary>
Null = 101,
/// <summary>
/// 仅输出接受数据的长度信息
/// </summary>
Length,
/// <summary>
/// UTF8-解析输出
/// </summary>
UTF8,
/// <summary>
/// ASCII-解析输出
/// </summary>
ASCII,
/// <summary>
/// 输出字节的字符串形式
/// </summary>
ByteToString
}
}
}