在winform客户端界面就四个控件,两个按钮、一个TextBox、一个Label
这是客户端界面:
代码如下:
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 客户端
{
public partial class Form1 : Form
{
// 用于取消任务的令牌源
CancellationTokenSource cts;
// 表示客户端的 TcpClient 对象
TcpClient client;
public Form1()
{
InitializeComponent();
// 在构造函数中初始化 TcpClient 对象
client = new TcpClient();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
// 使用 Task.Run 在后台线程中执行发送数据的操作
Task.Run(() =>
{
// 获取客户端的网络流
var stream = client.GetStream();
// 获取文本框中的输入内容作为要发送的消息
string message = textBox1.Text;
// 将消息转换为字节数组
byte[] buffer = Encoding.UTF8.GetBytes(message);
// 将字节数组写入网络流,发送给服务器
stream.Write(buffer, 0, buffer.Length);
});
}
catch (Exception ex)
{
// 如果出现异常,打印错误信息到控制台
Console.WriteLine($"错误:{ex.Message}");
}
}
private void button2_Click(object sender, EventArgs e)
{
// 点击按钮时尝试连接到指定的服务器
client.Connect("192.168.205.238", 8888);
// 创建一个新的取消令牌源
cts = new CancellationTokenSource();
Task.Run(() =>
{
while (!cts.IsCancellationRequested)
{
// 获取客户端的网络流
var stream = client.GetStream();
if (client.Available > 0)
{
// 创建一个字节数组,大小为当前可读取的字节数
byte[] buffer = new byte[client.Available];
// 从网络流中读取数据到字节数组
stream.Read(buffer, 0, buffer.Length);
// 在 UI 线程中更新标签的文本内容
Invoke(new Action(() =>
{
label1.Text = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
}));
}
}
});
}
}
}
在winform服务器界面就三个控件,两个按钮、一个Label
服务器界面:
服务器代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace tcp多人视觉检测
{
public partial class Form1 : Form
{
// 用于取消任务的令牌源
CancellationTokenSource cts;
// 用于监听客户端连接的 TcpListener 对象
TcpListener tcpListener;
// 用于保存连接的客户端,如果需要多个连接可创建一个列表
TcpClient client;
public Form1()
{
InitializeComponent();
// 在构造函数中初始化 TcpListener,监听所有可用 IP 地址的 8888 端口
tcpListener = new TcpListener(IPAddress.Any, 8888);
}
public void button1_Click(object sender, EventArgs e)
{
// 当按钮文本为"开始监听"时执行以下代码
if (button1.Text == "开始监听")
{
// 改变按钮文本为"断开监听"
button1.Text = "断开监听";
// 启动 TcpListener 开始监听客户端连接
tcpListener.Start();
// 创建新的取消令牌源
cts = new CancellationTokenSource();
// 在后台线程中执行任务
Task.Run(() =>
{
while (!cts.IsCancellationRequested)
{
// 判断是否有等待接受的连接请求
if (tcpListener.Pending())
{
// 接受一个客户端连接,并将其保存到 client 变量中
client = tcpListener.AcceptTcpClient();
// 在另一个后台线程中处理已连接的客户端
Task.Run(() =>
{
while (!cts.IsCancellationRequested)
{
// 获取客户端的网络流
NetworkStream stream = client.GetStream();
// 判断网络流中是否有可用数据
if (stream.DataAvailable)
{
// 创建一个字节数组,大小为当前可读取的字节数
byte[] buffer = new byte[client.Available];
// 从网络流中读取数据到字节数组
stream.Read(buffer, 0, buffer.Length);
// 将字节数组转换为字符串表示的接收到的消息
string receivedMessage = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
if (true)
{
// 在 UI 线程中更新标签的文本内容为接收到的消息
Invoke(new Action(() =>
{
label1.Text = receivedMessage;
}));
}
//下方是在客户端给服务器发信息后,服务器进行回应。就好像发一个信息,回到收到一样。
//string responseMessage = "服务器收到你的消息了。";
//byte[] responseBuffer = Encoding.UTF8.GetBytes(responseMessage);
//stream.Write(responseBuffer, 0, responseBuffer.Length);
}
}
});
}
}
});
}
else
{
// 当按钮文本为"断开监听"时执行以下代码
button1.Text = "开始监听";
// 取消所有相关任务
cts.Cancel();
// 停止 TcpListener 的监听
tcpListener.Stop();
}
}
private void button2_Click(object sender, EventArgs e)
{
// 在后台线程中执行发送消息的任务
Task.Run(new Action(() =>
{
// 获取已连接客户端的网络流
NetworkStream stream = client.GetStream();
// 定义要发送的消息内容
string responseMessage = "服务器发过去的消息";
// 将消息转换为字节数组
byte[] responseBuffer = Encoding.UTF8.GetBytes(responseMessage);
// 将字节数组写入网络流,发送给客户端
stream.Write(responseBuffer, 0, responseBuffer.Length);
}));
}
}
}