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);         }     }  ‍

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

相关内容

热门资讯

5分钟规律!大亨互娱辅助,小闲... 5分钟规律!大亨互娱辅助,小闲昭通棋牌有挂吗(其实一直都是有挂);1)小闲昭通棋牌有挂吗辅助挂:进一...
实测分享!奥云长岭麻将有挂吗,... 实测分享!奥云长岭麻将有挂吗,宝宝浙江游戏辅助有人在用吗,雀神微信小程序辅助器下载ios(详细教程)...
八分钟辅助挂!星星武汉麻将有老... 八分钟辅助挂!星星武汉麻将有老千吗,上海哈灵的确是有挂的,线上教程(有挂脚本)1、星星武汉麻将有老千...
实测发现!wpk数据分析,逗娱... 实测发现!wpk数据分析,逗娱碰胡外 挂,2025教程(有挂介绍)1.逗娱碰胡外 挂 ai辅助创建新...
两分钟攻略!老友圈手机麻将输赢... 两分钟攻略!老友圈手机麻将输赢规律,哈哈贵阳捉鸡手机麻将有挂吗(原来真的有挂)1、起透看视 哈哈贵阳...
推荐一款!途乐竞技有挂吗,桂林... 推荐一款!途乐竞技有挂吗,桂林字牌十打九赢的方法,广东雀神麻雀辅助软件(详细教程)1、途乐竞技有挂吗...
推荐一款!!微扑克可以用模拟器... 推荐一款!!微扑克可以用模拟器,白金岛自创房有外 挂怎么破,微扑克教程(有挂规律)1、白金岛自创房有...
六分钟辅助挂!蜀山四川麻将输赢... 六分钟辅助挂!蜀山四川麻将输赢规律技巧,欢乐龙城3欢乐斗牛都是真的有挂,必赢方法(有挂辅助)暗藏猫腻...
3分钟技巧!邳州友友麻将有假吗... 3分钟技巧!邳州友友麻将有假吗,微信闽南漳浦麻将有挂吗(其实总是有挂)该软件可以轻松地帮助玩家将微信...
专业讨论!!wpk微扑克最新辅... 专业讨论!!wpk微扑克最新辅助,悠闲麻将川南版有假吗,可靠技巧(有挂工具)1、超多福利:超高返利,...