TCP/IP协议——使用TcpListener和Tcpclient类实现通信
创始人
2024-09-26 02:51:05
0

目录

TcpListener和TcpClient

TcpListener和TcpClient的使用

连接到服务器

创建服务器套接字

接收服务器连接

创建 `NetworkStream`​​ 以发送和接收数据

关闭连接

使用TcpListener搭建Tcp服务器

TcpClient用于客户端和服务器连接


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 clientList = new Dictionary();          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);         }     }  ‍

本篇文章部分参考于网络,如有侵权请联系本人删除!!!

相关内容

热门资讯

透明透视!德州nzt软件,德扑... 透明透视!德州nzt软件,德扑人工智能软件,德扑之星创建房间设置;德扑之星创建软件透明挂是一个全新上...
2分钟了解(新闲游龙岩麻将外挂... 《新闲游龙岩麻将软件透明挂》是一款多人竞技的新闲游龙岩麻将辅助透视游戏,你将微扑克对手来到同一个战场...
七分钟了解(闲逸游戏)外挂透视... 七分钟了解(闲逸游戏)外挂透视工具(必胜教程)外挂辅助软件(哔哩哔哩);闲逸游戏软件透明挂作为一款闲...
5分钟了解(中至麻将)其实是真... 5分钟了解(中至麻将)其实是真的有挂(2023已更新方法)外挂透视辅助脚本(哔哩哔哩);亲,有的,a...
一分钟了解!天天摸麻将app有... 您好,多乐跑得快私人场这款游戏可以开挂的,确实是有挂的,需要了解加微【136704302】很多玩家在...
透明有挂!Aapoker透明挂... 透明有挂!Aapoker透明挂辅助安装(透视辅助)WPK程序辅助工具(有挂脚本)-哔哩哔哩是一款可以...
九分钟了解(多乐保皇随意选牌)... 您好,多乐保皇随意选牌这款游戏可以开挂的,确实是有挂的,需要了解加微【757446909】很多玩家在...
5分钟了解(同城搓麻将外挂透视... 5分钟了解(同城搓麻将外挂透视辅助工具,透视技巧)辅助安卓(2021已更新)(哔哩哔哩);同城搓麻将...
透明新版!Wepoke ios... 透明新版!Wepoke ios透明挂辅助脚本(透视)WPK识别辅助免费(有挂开发)-哔哩哔哩;超受欢...
1分钟了解(桂林老k字牌)外挂... 自定义新版桂林老k字牌系统规律,只需要输入自己想要的开挂功能,一键便可以生成出桂林老k字牌专用辅助器...