C#实现TCP通信---使用VS的Windows窗体应用

一、UI界面的设置

在这里插入图片描述
1.三个button控件,使用了Click()事件。
2.三个GroupBox控件,能够在一定区域显示字符,如:服务器。
3.两个RichTextBox控件,用于显示输入和接收的数据。
4.一个Timer定时器控件,用于接收数据的处理

二、服务器实现代码

1.相关变量

//定义的类内变量
        private TcpListener Listener;
        private Socket SocketClient;
        private NetworkStream NetStream;
        private StreamReader ServerReader;
        private StreamWriter ServerWriter;
        private Thread Thread;

2.核心代码

2.1运行的线程函数

public void TCPListener()
{
   //在这里填入你的ip地址
   this.Listener = new TcpListener(IPAddress.Parse("192.168.31.62"), 8000);
   Listener.Start();
   button1.Enabled = false;
   this.Text = "服务器正在运行中。。。";
   while (true)
   {
       try
       {
           SocketClient = Listener.AcceptSocket();         //等待客户端的socket
           NetStream = new NetworkStream(SocketClient);    //有客户端连接成功后,创建网络流
           ServerReader = new StreamReader(NetStream);     //读数据
           ServerWriter = new StreamWriter(NetStream);     //写数据
           
       }
       catch
       {

       }
   }
}

 该函数为线程的执行函数,不断地等待客户端的socket连接,并接收数据。
 该函数在按键按下之后赋予一个新的线程,并且按键在按下后就已经锁定了,即服务器只需运行一个线程即可,而客户端可以有多个线程运行连接至服务器。

2.2 接收函数

public void GetMessage()
{
     //网络流不为空并且有可用数据
     if (NetStream != null && NetStream.DataAvailable)
     {
         richTextBox1.AppendText(DateTime.Now.ToString());//显示时间
         richTextBox1.AppendText("  客户端说:\n");
         richTextBox1.AppendText(ServerReader.ReadLine() + "\n");
         //设置下拉框
         richTextBox1.SelectionStart = richTextBox1.Text.Length;
         richTextBox1.Focus();
         richTextBox2.Focus();
     }
 }

 该函数在定时器的中断触发函数中运行,在网络流中有数据时将其打印在接收框控件中。

3.按键触发函数

3.1 连接服务器

private void button1_Click(object sender, EventArgs e)
{
    this.Thread = new Thread(new ThreadStart(TCPListener));
    this.Thread.Start();
}

 开启线程,线程运行函数设置为TCPListener(),具体函数在2.1

3.2 发送数据

private void button3_Click(object sender, EventArgs e)
{
    try
    {
        if (richTextBox2.Text.Trim() != "")
        {
            //信息写入流
            ServerWriter.WriteLine(richTextBox2.Text);
            ServerWriter.Flush();
            //显示在文本框上。
            richTextBox1.AppendText(DateTime.Now.ToString());
            richTextBox1.AppendText("  服务器说:\n");
            richTextBox1.AppendText(richTextBox2.Text + "\n");
            richTextBox2.Clear();
            //滚动条
            richTextBox1.SelectionStart = richTextBox1.Text.Length;
            richTextBox1.Focus();
            richTextBox2.Focus();
        }
        else
        {
            MessageBox.Show("信息不能为空!", "服务器消息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            richTextBox2.Focus();
            return;
        }
    }
    catch
    {
        MessageBox.Show("客户端连接失败……", "服务器消息", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
}

 用户单击发送时,根据输入在文本框中的数据,发送至客户端,并在信息接收框中显示。

3.3 清空数据

private void button2_Click(object sender, EventArgs e)
{
     richTextBox1.Clear();
 }

 清空接收框中的数据。

4.其他模块

4.1构造函数

public Form1()
 {
     InitializeComponent();
     CheckForIllegalCrossThreadCalls = false;
 }

4.2窗体相关事件

private void Form1_Load(object sender, EventArgs e)
 {
     this.richTextBox1.ReadOnly = true;  //只读
     this.timer1.Enabled = true;         //定时器使能
 }

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 {
     DialogResult dr = MessageBox.Show("关闭服务器将无法接收到来自客户端的数据,你确定要关闭吗?", "服务器信息", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
     if (dr == DialogResult.Yes)
     {
         Listener.Stop();
         this.Thread.Abort();
         e.Cancel = false;
     }
     else
     {
         e.Cancel = true;
     }
 }

 在窗体的事件函数中,可以做一些初始化的操作,并且在关闭窗体时关闭套接字和线程,否则将出现异常错误。
具体可以查看我的一篇博客

4.3定时器事件

private void timer1_Tick(object sender, EventArgs e)
{
     //接收数据,处理数据
     GetMessage();
 }

 调用数据接收函数GetMessage(),不断处理接收到的数据。

三、客户端实现代码

1.阐述

 客户端代码实现和服务器类似,不过需要选择连接服务器的IP和port。
**PS:该服务器和客户端代码运行在同一局域网下,即使用相同的路由器或者热点,使用ipconfig在控制台查看IP,填入相关位置即可。

2.核心代码

public void GetConn()
{
    CheckForIllegalCrossThreadCalls = false;
    while (true)
    {
        try
        {
            TcpClient = new TcpClient(textBox1.Text.Trim(), Convert.ToInt32(textBox2.Text.Trim()));
            Stream = TcpClient.GetStream();
            //创建读写流
            ClientReader = new StreamReader(Stream);
            ClientWriter = new StreamWriter(Stream);
            textBox1.Enabled = false;
            button1.Enabled = false;
            this.Text = "客户端   " + "与" + textBox1.Text.Trim() + "连接成功!";
            return;
        }
        catch (Exception e)
        {
            textBox1.Enabled = true;
            button1.Enabled = true;
            MessageBox.Show(e.ToString());
            return;
            //MessageBox.Show("连接失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

 该函数为客户端的线程执行函数,使用TcpClient类。
 其余大致和服务器相同,了解了服务器后再编写客户端其实就是按图索骥的过程里。
 如果你还不明白,可以点击这里,这里有我上传的资源,完整的工程。

祝诸位学习愉快!

猜你喜欢

转载自blog.csdn.net/aruewds/article/details/109262823