目录
TcpListener和TcpClient
在C#中实现TCP通信,你可以使用 System,Net.Sockets 命名空间中的 TcpListener 和
Tcpclient 类。
若要使用传输控制协议(TCP),有两个选项:使用 Socket以获得最大控制和性能,或使用 Icpclient 和IcpListener 帮助程序类。Icpclien 和 IcpListener 是在System.Net.Sockets.Socket 类的基础上建立的,并负责传输数据的详细信息以便于使用。
TcpListener和TcpClient的使用
连接到服务器
`TcpClient` 中的所有 `Connect`、`ConnectAsync`、`BeginConnect` 和 `EndConnect` 重载在功能上都等效于相应的 `Socket` 方法。
请考虑以下 TCP 客户端代码:
var client = new TcpClient(); client.Connect("www.example.com", 80);
上述 `TcpClient` 代码等效于以下套接字代码:
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); socket.Connect("www.example.com", 80);
创建服务器套接字
就像与原始 `Socket` 对应项功能等效的 `TcpClient` 实例一样,本部分将 `TcpListener` 构造函数映射到其相应的套接字代码。 要考虑的第一个构造函数是 `TcpListener(IPAddress localaddr, int port)`。
var listener = new TcpListener(IPAddress.Loopback, 5000);
前面的 TCP 侦听器代码在功能上等效于下面的套接字代码:
var ep = new IPEndPoint(IPAddress.Loopback, 5000); var socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
开始侦听服务器
Start()方法是组合 socket 的 Bind 和 Listen() 功能的包装器
var listener = new TcpListener(IPAddress.Loopback, 5000); listener.Start(10);
前面的 TCP 侦听器代码在功能上等效于下面的套接字代码:
var endPoint = new IPEndPoint(IPAddress.Loopback, 5000); var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Bind(endPoint); socket.Listen(10);
接收服务器连接
在后台,传入的TCP 连接在接受时始终会创建新的套接字。 TcpListener 可以直接接受 socket实例(通过 Acceptsocketl)或 AceptsocketAsymc),也可以接受 IcpClient(通过AcceptTcpClient()和AcceptTcpClientAsync())。
var listener = new TcpListener(IPAddress.Loopback, 5000); var acceptedSocket = await listener.AcceptSocketAsync();
前面的 TCP 侦听器代码在功能上等效于下面的套接字代码:
var endPoint = new IPEndPoint(IPAddress.Loopback, 5000); var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); var acceptedSocket = await socket.AcceptAsync();
创建 `NetworkStream` 以发送和接收数据
使用 Tcpclient 时,需要使用 Getstream()方法实例化NetworkStream,以便能够发送和接收数据。使用socket 时,必须手动创建 Networkstream
var client = new TcpClient(); NetworkStream stream = client.GetStream();
等效于以下套接字代码:
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); var stream = new NetworkStream(socket, ownsSocket: true);
如果代码不需要使用 stream 实例,则可以直接依赖 scket 的发送/接收方法(Send、SendAsync、Receive和 ReceveAsync),而不是创建 Networkstream.
关闭连接
使用 `TcpClient` 时,需要使用 Close()方法关闭连接,
var client = new TcpClient(); client.Close();
使用TcpListener搭建Tcp服务器
TcpListener listener; Dictionary<string, TcpClient> clientList = new Dictionary<string, TcpClient>(); private void button1_Click(object sender, EventArgs e) { // 按钮状态 openBtn.Enabled = false; closeBtn.Enabled = true; // 1.创建监听对象 listener = new TcpListener(IPAddress.Any, 3030); // 2.开始监听(backlog:链接最大的挂起数) listener.Start(100); startListener(listener); } private void startListener(TcpListener lis) { // 3.等待链接(接收挂起的连接请求) Task.Run(() => { while (true) { try { TcpClient client = lis.AcceptTcpClient(); string ip = client.Client.RemoteEndPoint.ToString(); // 获取连接客户的IP clientList.Add(ip, client); startReceive(client.GetStream(), ip); addRichTextBox($"{ip}已经连接到服务器"); } catch (Exception ex) { lis.Stop(); break; } } }); } private void startReceive(NetworkStream stream, string ip) { Task.Run(() => { while (true) { try { byte[] buffer = new byte[1024]; // 大小按情况而定 int length = stream.Read(buffer, 0, buffer.Length); // 返回本次接收数据的字节数 if (length == 0) { throw new Exception($"客户端{ip}断开连接"); } else { string value = Encoding.Default.GetString(buffer, 0, length); addRichTextBox($"接收到{ip}发送的消息:{value}\r\n"); } } catch { // 从字典中移除当前连接 clientList.Remove(ip); addRichTextBox($"{ip}连接已断开\r\n"); break; } } }); } // 发送信息给客户端 private void sendBtn_Click(object sender, EventArgs e) { byte[] bytes = Encoding.Default.GetBytes(msgTextbox.Text); // 循环所有的客户端发送数据(也可以根据IP选择给谁发送) foreach (var item in clientList) { item.Value.GetStream().Write(bytes, 0, bytes.Length); } } // 关闭按钮点击 private void closeBtn_Click(object sender, EventArgs e) { // 控制按钮状态 closeBtn.Enabled = false; openBtn.Enabled = true; foreach (var item in clientList) { TcpClient client = item.Value; client.Close(); } listener.Stop(); } private void addRichTextBox(string text) { richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(text); // 让rich滚动到最下面 richTextBox1.SelectionStart = richTextBox1.Text.Length; richTextBox1.ScrollToCaret(); })); }
TcpClient用于客户端和服务器连接
简单代码示例如下
private TcpClient tcpClient; private void button1_Click(object sender, EventArgs e) { // 1.创建客户端对象 tcpClient = new TcpClient(); // 2.开始链接 tcpClient.Connect(IPAddress.Parse("127.0.0.1"),3030); // 3.获取数据流 Stream(读read 和 写write) NetworkStream stream = tcpClient.GetStream(); // 4. 开启分线程 Thread thread = new Thread(ClientThread); thread.Start(stream); } // 开分线程,收发消息 private void ClientThread(object obj) { NetworkStream stream = obj as NetworkStream; while (true) { // 5.向服务器发送消息(自定义一个带输入框的对话框) string info = "张三发送的消息"; byte[] bytes = Encoding.UTF8.GetBytes(info); stream.Write(bytes,0,bytes.Length); // 6.接收来自服务器的消息 byte[] buffer = new byte[1024]; int length = stream.Read(buffer,0,buffer.Length); string msg = Encoding.UTF8.GetString(buffer,0,length); MessageBox.Show(msg); } }
本篇文章部分参考于网络,如有侵权请联系本人删除!!!