C# TcpListener的编程要点

时间:2023-03-09 15:11:36
C# TcpListener的编程要点
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms; namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listener = new TcpListener(IPAddress.Any, );// 端口根据需要确定
listener.Start(); // 后台线程1:用于接收tcp连接请求,并将网络流加入列表。随主线程的退出而退出。
new Thread(() =>
{
while (true)
{
Thread.Sleep();// 可以根据需要设置时间
if (!listener.Pending())
{
continue;
}
var client = listener.AcceptTcpClient();
// 下面属性根据需要进行设置
// client.ReceiveBufferSize
// client.ReceiveTimeout
// client.SendBufferSize
// client.SendTimeout
if (!client.Connected)
{
continue;
}
streams.Add(client.GetStream());
}
}) { IsBackground = true }.Start(); // 后台线程2:用于接收请求,并作出响应。随主线程的退出而退出。
new Thread(() =>
{
while (true)
{
Thread.Sleep();// 可以根据需要设置时间
if (streams == null || streams.Count == )
{
continue;
}
streams = streams.Where(s => s.CanRead && s.CanWrite).ToList();
foreach (var stream in streams.Where(stream => stream.CanRead && stream.CanWrite))
{
AsyncReceiveBytes(stream,
s =>
{
// todo:对result进行解码
// todo:对收到指令进行逻辑判断,得出待响应的C#对象
AsyncSendBytes(s, new byte[]); // todo:将待响应的C#对象转换成字节数组,替换new byte[0]。
});
}
}
}) { IsBackground = true }.Start();
} // 发送事件和目标的入口
public void SendEventAndTarget()
{
if (streams == null || streams.Count == )
{
return;
}
streams = streams.Where(s => s.CanRead && s.CanWrite).ToList();
foreach (var stream in streams.TakeWhile(stream => stream.CanWrite))
{
AsyncSendBytes(stream, new byte[]);// todo:这里将待发送的C#对象转换的字节数组替换new byte[0]。
}
} private static void AsyncReceiveBytes(NetworkStream stream,
Action<NetworkStream> callback)
{
// 短时后台线程:用于处理网络流的读操作,处理完成后即归还线程池。
// 每个网络流都会分配一个线程。
//ThreadPool.SetMaxThreads();根据需要设置。
ThreadPool.QueueUserWorkItem(delegate
{
var buffer = new byte[];// 1024:根据需要进行设置。
var result = new byte[];
do
{
var a = stream.Read(buffer, , buffer.Length);
result = result.Concat(buffer.Take(a)).ToArray();
} while (stream.DataAvailable);
callback(stream);
});
}
private static void AsyncSendBytes(NetworkStream stream, byte[] bytes)
{
// 短时后台线程:用于处理网络流的写操作,处理完成后即归还线程池。
// 每个网络流都会分配一个线程。
//ThreadPool.SetMaxThreads();根据需要设置。
ThreadPool.QueueUserWorkItem(delegate
{
try
{
stream.Write(bytes, , bytes.Count());
}
catch (Exception)
{
MessageBox.Show("远程主机主动断开此连接!");// 也可以做其它处理。
}
});
} private readonly TcpListener listener;
// 网络流列表
private List<NetworkStream> streams = new List<NetworkStream>();
}
}

找时间在项目中应用后,再总结一下。