本例采用System.Threading实现多线程监听,
这样会一直保持连接除非客户端主动断开连接,非常好用~~~
private string _ip;//IP
private int _port;//端口
//客户端集合
public static List<TcpClientModel> clients = new List<TcpClientModel>
private static byte[] bytes = new byte[1024 * 100];
/// <summary>
/// 用于存储客户端
/// </summary>
public class TcpClientModel
{
/// <summary>
/// IP:Port
/// </summary>
public string RemoteEndPoint { get; set; }
/// <summary>
/// 客户端链接对象
/// </summary>
public TcpClient TcpClient { get; set; }
}
启动监听:
///启动监听
void Init()
{
try
{
IPAddress ip = IPAddress.Parse(_ip);
int port = _port;
TcpListener listener = new TcpListener(ip, port);
//启动监听
listener.Start();
tb_console.AppendText($"Listener...\r\n");
//异步接收 递归循环接收多个客户端
listener.BeginAcceptTcpClient(new AsyncCallback(GetAcceptTcpclient), listener);
}
catch (Exception ex)
{
}
}
接收客户端:
private void GetAcceptTcpclient(IAsyncResult State)
{
//处理多个客户端接入
TcpListener listener = (TcpListener)State.AsyncState;
//接收到客户端请求
TcpClient client = listener.EndAcceptTcpClient(State);
//保存到客户端集合中
clients.Add(new TcpClientModel() { TcpClient = client, RemoteEndPoint = client.Client.RemoteEndPoint.ToString() });
//开启线程用来持续接收来自客户端的数据
Thread myThread = new Thread(() =>
{
ReceiveMsgFromClient(client);
});
myThread.Start();
if (!threadLive)
{
myThread.Abort();
}
listener.BeginAcceptTcpClient(new AsyncCallback(GetAcceptTcpclient), listener);
}
接收消息并响应客户端:
private void ReceiveMsgFromClient(object reciveClient)
{
TcpClient client = reciveClient as TcpClient;
if (client == null)
{
return;
}
while (true)
{
try
{
NetworkStream stream = client.GetStream();
int num = stream.Read(bytes, 0, bytes.Length); //将数据读到result中,并返回字符长度
if (num != 0)
{
//把字节数组中流存储的数据以字符串方式赋值给str
//这里就是接收到的客户端消息
string str = Encoding.UTF8.GetString(bytes, 0, num);
//给客户端返回一个消息
string msg = "Your message has been received by the server[" + str + "]";
bool result = TCPHelper.SendToClient(client, msg, out msg);
if (!result)
{
//发送失败
}
}
else
{
//这里需要注意 当num=0时表明客户端已经断开连接,需要结束循环,不然会死循环一直卡住
break;
}
}
catch (Exception ex)
{
//链接失败 从集合中移除出错客户端
if (client?.Client.Connected==true)
{
clients.Remove(clients.FirstOrDefault(m => m.RemoteEndPoint == client?.Client?.RemoteEndPoint?.ToString()));
}
break;
}
}
}
从服务器向客户端发送消息的工具类:
public static class TCPHelper
{
public static bool SendToClient(TcpClient client, string message,out string errorMsg)
{
try
{
byte[] bytes = new byte[1024 * 100];
bytes = Encoding.UTF8.GetBytes(message);
NetworkStream stream = client.GetStream();
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
errorMsg = "";
return true;
}
catch (Exception ex)
{
errorMsg = ex.Message;
return false;
}
}
}
评论 (0)