C#--Winform创建TCP服务器与客户端互传消息实例

本项目使用C#语言建立一个TCP通讯实例,并可以互相传递消息:
在这里插入图片描述
传送一下传智播客赵老师的视频课程

  1. 关键词解释:
    (1)TCP协议
    一种可以用于网络通信的数据传输协议,传输安全可靠不会有信息丢失,重点理解三次握手与四次分手。
    (2)线程Thread
    我们的主程序是一个线程,若是不开启多线程我们便无法在程序中执行特定的动作。
    Thread th = new Thread(Receive);
    th.IsBackground = true; //线程转为后台运行
    th.Start(socketSend); //开启线程
    (3)套接字Socket
    (连结是一位点击20w的博主写的,十分通俗易懂,包括UDP/TCP等)

客户端与服务端通信步骤
(客户端与服务器端Socket运行步骤)
服务器端:

第一步:创建一个用于监听连接的Socket对像;

第二步:用指定的端口号和服务器的ip建立一个EndPoint对像;

第三步:用socket对像的Bind()方法绑定EndPoint;

第四步:用socket对像的Listen()方法开始监听;

第五步:接收到客户端的连接,用socket对像的Accept()方法创建一个新的用于和客户端进行通信的socket对像;

第六步:通信结束后一定记得关闭socket;

客户端:

第一步:建立一个Socket对像;

第二步:用指定的端口号和服务器的ip建立一个EndPoint对像;

第三步:用socket对像的Connect()方法以上面建立的EndPoint对像做为参数,向服务器发出连接请求;

第四步:如果连接成功,就用socket对像的Send()方法向服务器发送信息;

第五步:用socket对像的Receive()方法接受服务器发来的信息 ;

第六步:通信结束后一定记得关闭socket;
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
(徐泽IP4网络连结模式,当进行TCP通讯时要选择流传输Stream,传输类型为Tcp)
socketSend.Receive(buffer);//程序运行到这一步会暂停,直到接收到客户端传递的消息;
buffer为字节数组,因为TCP通过二进制计算机语言交流,因此记得要转译出来;
socketSend.Send(buffer); //用于发送消息,传递的内容一样为字节数组。
2. 服务器搭建:
新建winform项目,拖入Textbox、button、textlog等控件:
在这里插入图片描述
监听按钮代码:
在这里建立socket连结:

 private void button6_Click(object sender, EventArgs e)
        {
            try   //开启网络连结的地方,建议都加上try
            {
                //创建一个负责监听的socket
                Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //创建IP地址与端口号
                IPAddress ip = IPAddress.Any;//IPAddress.Parse(textServer.Text);
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textport.Text));
                //让负责监听的Socket绑定IP地址跟端口号
                socketWatch.Bind(point);
                ShowMsg("监听成功");
                //设置监听队列
                socketWatch.Listen(10);
                Thread th = new Thread(Listen);
                th.IsBackground = true;
                th.Start(socketWatch);
            }
            catch
            { }
        }

服务器绑定得IP地址为IPAdress.Any,意味着可以接收任意IP的客户端;

完整代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Server01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
        }
        /// <summary>
        /// 监听按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            try   //开启网络连结的地方,建议都加上try
            {
                //创建一个负责监听的socket
                Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //创建IP地址与端口号
                IPAddress ip = IPAddress.Any;//IPAddress.Parse(textServer.Text);
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textport.Text));
                //让负责监听的Socket绑定IP地址跟端口号
                socketWatch.Bind(point);
                ShowMsg("监听成功");
                //设置监听队列
                socketWatch.Listen(10);
                Thread th = new Thread(Listen);
                th.IsBackground = true;
                th.Start(socketWatch);
            }
            catch
            { }
        }
        /// <summary>
        /// 等待客户端的连结,并且创建一个与之对应的Socket
        /// 线程中函数可以无参数,若有必须是obbject类型;
        /// </summary>
        Socket socketSend;
        void Listen(object o)
        {
            Socket socketWatch = o as Socket;//将object转化为Socket
            //创建一个负责通信的Socket,用于接收客户端的连结
            while (true)
            {
                try  
                {
                    socketSend = socketWatch.Accept();
                    ShowMsg(socketSend.RemoteEndPoint.ToString() + "连结成功");
                    //开启一个新的线程,不停的接收客户端发来的消息
                    Thread th = new Thread(Receive);
                    th.IsBackground = true;
                    th.Start(socketSend);
                }
                catch
                { }
            }
        }
        /// <summary>
        /// 服务器不停的接收客户端发来的消息
        /// </summary>
        /// <param name="ob"></param>
        void Receive(object ob)
        {
            Socket socketSend = ob as Socket;
            while (true)
            {
                try
                {
                    //客户端连结成功后,服务器应该接受客户端发来的消息
                    byte[] buffer = new byte[1024 * 1024 * 2];
                    //实际接收到的有效字节数
                    int r = socketSend.Receive(buffer);
                    //当不接受数据的时候,则跳出
                    if (r == 0)
                    {
                        break;
                    }
                    string str = Encoding.UTF8.GetString(buffer, 0, r);//从0开始解码到r个
                    ShowMsg(socketSend.RemoteEndPoint + ":" + str);
                }
                catch
                { }
            }
        }
        /// <summary>
        /// 服务器给客户端发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            string str = textMsg.Text;
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
            socketSend.Send(buffer);
        }
        void ShowMsg(string str)
        {
            textLog.AppendText(str + "\r\n");
        }
        /// <summary>
        /// 关闭线程检测
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        
    }
}

  1. 客户端:
    另外新建一个winform项目,并拖入控件:
    在这里插入图片描述
    与服务器不同的是,客户端要指定需要连结服务器的IP地址,并且主动使用socket.Connect( )进行连结;
    完整代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Client01
{
    public partial class Form1 : Form
    {
        Socket socketSend;
        public Form1()
        {
            InitializeComponent();
        }
        ~Form1()
        {

        }
        /// <summary>
        /// 客户端消息发送按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            string str = textMsg.Text.Trim();
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
            socketSend.Send(buffer);
        }
        /// <summary>
        /// 连结服务器按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                //创建负责通信的Socket
                socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //客户端要连结服务器
                IPAddress ip = IPAddress.Parse(textServer.Text);
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textport.Text));
                //获得要连结的远程服务器应用程序的IP地址和端口号
                socketSend.Connect(point);
                ShowMsg("连结成功");
                Thread thread = new Thread(Receive);
                thread.IsBackground = true;
                thread.Start();
            }
            catch
            {  }
        }
        /// <summary>
        /// 不停的接收服务端发来的消息
        /// </summary>
        void Receive()
        {
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[1024 * 1024 * 2];
                    int r = socketSend.Receive(buffer);
                    if (r == 0)
                    {
                        break;
                    }
                    string s = Encoding.UTF8.GetString(buffer, 0, r);
                    ShowMsg(socketSend.RemoteEndPoint + ":" + s);
                }
                catch
                { }
            }
        }
        void ShowMsg(string str)
        {
            //textLog.AppendText(str + "\r\n");
            this.Invoke(new Action(() =>
            {
                //this.textLog.Items.Add(serwe);
                //textBox1.Text = "";
                textLog.AppendText(str + "\r\n");
            }));
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        #region
        #endregion 

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值