“保姆级别”从零开始的C#TCP网络通信教程

“保姆级别”从零开始的C#TCP网络通信教程

经过几日的原理学习和扒码之后,终于七七八八搞明白tcp的通信是怎么进行的了。
注:源码为《C#开源虚拟仪器技术》实例

文章目录

    • “保姆级别”从零开始的C#TCP网络通信教程
  • 前言
  • 一、什么是tcp通信
  • 二、如何实现tcp通信
    • 1.建立连接
    • 2.传输数据
    • 3.断开连接
  • 三、窗体设计
    • 服务端client
    • 客户端server
  • 四、tcp代码实现(注:源码为《C#开源虚拟仪器技术》实例)
    • 客户端client代码
    • 服务端server代码


前言

本文主要给大家提供从零开始做一个包含客户端和服务端的tcp通信窗体应用的教程,并在此基础上理解TCP通信的原理,理解使用socket套接字进行通信的概念和实际运用,全文包含从原理到例程的详细操作,保证简单易上手


一、什么是tcp通信

首先,TCP是计算机实现网络通信的一种方式,全称是传输控制协议,计算机通信需要知道计算机的地址,互联网使用IP地址来标识计算机的网络地址,IP协议层往上是传输层,它提供了TCP和UDP这两种可选的协议,之所以选择TCP协议进行计算机的网络通信,是因为它的好处是能够检测和恢复IP层提供的主机到主机的信道可能发生的报文丢失、重复及其他错误,而socket处于TCP这类具体协议层上,它是进行网络通信最基本的操作单元,可以看做是两台主机进行通讯的端点。TCP通信,依靠的就是IP地址到socket套接字这样的由宏观到微观的这样一个过程。(或者直接使用已经封装好的Tcplistener类和TcpClient类来实现) 通过TCP/IP可实现单个网络内部或互联网间的通信,同时可提供简单的用户界面,有较高的网络通信的可靠性。所以本文主要倾向于如何进行用户界面即客户端和服务端的设计以及相关代码的实现。

二、如何实现tcp通信

TCP的工作过程可分为三个重要的阶段,一是建立连接,二是传输数据,二是断开连接

1.建立连接

建立连接最关键的一步就是进行3次握手,这一步主要关注三个“硬性指标”,分别是

  1. ACK,tcp报头的控制位之一,用于表示确认号是否有效,若有效则置1(确认号:用于告诉数据发送端发送过来的序列号之前的数据都已经接收到了)
  2. SYN,同步序列号,如果TCP建立连接成功则置1
  3. FIN,发送端完成发送任务位,当TCP完成了数据传输的任务,想要断开连接之后,该位置1

详细过程:(同步通信方式)假定服务端向客户端发送信息

  1. 服务端向客户端发送一个含有SYN的数据段给客户端,并请求连接
  2. 客户端收到服务端收到请求后,用含有ACK和SYN的数据段响应服务端
  3. 服务端收到客户端发来的数据段后,再发送一个ACK,确认收到数据段,至此建立连接成功。

注:握手的步骤在协议内部协议实现的,不体现在具体的上位机代码中。理解握手过程即可

2.传输数据

建立连接之后,就可以通过通信信道进行传输数据的任务了,但是需要注意的是TCP协议中的数据是以字节流的形式存在的,发送端需要将的数据转换为字节流,然后才可以发送。通常是字符集转换为字节序列,这其中就涉及到编码和解码的问题了。

3.断开连接

断开连接主要是关闭读写流。至于是服务端先断开连接还是客户端先断开连接,有时需要进行异常处理。


三、窗体设计

这一步主要使用工具箱中的按钮button和文本框text控件,点击相应控件即可查看代码。Label控件用于标识文本框。

服务端client

“保姆级别”从零开始的C#TCP网络通信教程_第1张图片

客户端server

“保姆级别”从零开始的C#TCP网络通信教程_第2张图片
注意事项:
这里需要注意的是要确保按钮的命名,以及其事件的名称,如客户端的发送按钮,要确保正确。示例如下:

客户端发送按钮
“保姆级别”从零开始的C#TCP网络通信教程_第3张图片
按钮的命名
命名
按钮事件即操作的命名
“保姆级别”从零开始的C#TCP网络通信教程_第4张图片
这一步的命名操作十分关键,关系到实际代码中的运行。以此类推。

四、tcp代码实现(注:源码为《C#开源虚拟仪器技术》实例)

为使编程变得简洁,这里使用类库Tcplistener类和TcpClient类实现Tcp通信(已经包含Socket套接字方法),并且服务端server只负责接收信息,客户端只负责发送信息。
如果要实现全双工通信,加入多线程thread,对每个tcp开两个线程,一个线程用来处理发送数据,一个线程用来处理接收数据即可。推荐使用异步通讯方式,无阻塞现象。

客户端client代码

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace _13._2._3._1
{
    public partial class TCPClient : Form
    {
        #region 变量
        private TcpClient tcpClient = null;
        private NetworkStream networkStream = null;
        private BinaryWriter writer;
        private const int Port = 51388;
        private IPAddress ipAddress = IPAddress.Loopback;
        private byte[] buffer;
        private string messageSend;

        #endregion 
        public TCPClient()
        {
            InitializeComponent();     
           
            textBox_clientIP.Text = ipAddress.ToString();
            textBox_port.Text = Port.ToString();
        }

        private void button_connect_Click(object sender, EventArgs e)
        {
            try
            {
                tcpClient = new TcpClient();
                tcpClient.Connect(textBox_clientIP.Text, int.Parse(textBox_port.Text));
                if (tcpClient != null)
                {
                    MessageBox.Show("连接成功");
                    networkStream = tcpClient.GetStream();
                    writer = new BinaryWriter(networkStream);                 
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show("连接失败,请重试" + ex.Message);
            }
        }

        // 发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            messageSend = textBox_messageSend.Text;
            if (messageSend != string.Empty)
            {
                writer.Write(messageSend);
                Thread.Sleep(500);
                writer.Flush();
            }
            textBox_messageSend.Clear();
        }

        // 断开连接
        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            writer?.Close();
            tcpClient?.Close();
        }
    }
}

服务端server代码

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _13._2._3._2
{
    public partial class TCPServer : Form
    {
        private const int Port = 51388;
        private TcpListener tcpLister = null;//创建对象,对象和类的属性以及行为完全相同
        private TcpClient tcpClient = null;
        IPAddress ipAddress = IPAddress.Loopback;//将IPAddress类中的属性Loopback赋给对象ipAddress,即127.0.0.1
        private NetworkStream networkStream = null;
        private BinaryReader reader;
        private byte[] buffer = new byte[1024];
        private string messageReceived;

        public TCPServer()
        {
            InitializeComponent();
            textBox_serverIP.Text = ipAddress.ToString();//当前对象以字符串形式返回
            textBox_port.Text = Port.ToString();
        }

        // 开始监听
        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                tcpLister = new TcpListener(IPAddress.Parse(textBox_serverIP.Text), 
                    int.Parse(textBox_port.Text));
                tcpLister.Start();
                tcpClient = tcpLister.AcceptTcpClient();
                if (tcpClient != null)
                {
                    networkStream = tcpClient.GetStream(); //获取网络流对象
                    reader = new BinaryReader(networkStream); //从网络流中初始化读取对象
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button_receive_Click(object sender, EventArgs e)
        {
            messageReceived = reader.ReadString();
            listBox_messageReceived.Items.Add(messageReceived);
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            tcpLister?.Stop();
        }

        private void button_disconnect_Click(object sender, EventArgs e)
        {
            reader?.Close();//断开连接,关闭读写流
            tcpClient?.Close();
        }
    }
}

注:源码为《C#开源虚拟仪器技术》实例
参考资料链接:
《C#开源虚拟仪器技术》
https://blog.csdn.net/weixin_46594796/article/details/107881821
https://javaedge.blog.csdn.net/article/details/113784188
https://blog.csdn.net/qq_45060045/article/details/113360983
https://blog.csdn.net/weixin_38247439/article/details/88529909
https://blog.csdn.net/kevinfan2011/article/details/84660013

你可能感兴趣的:(C#项目实现,tcp/ip,c#,网络)