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

2023-10-30

本项目使用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");
        }

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

    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#创建TCP服务器与客户端互传消息实例 的相关文章

随机推荐

  • 如何巧妙拒绝别人,搭配Online有小妙招

    相信很多人都会有拒绝别人的烦恼 一旦开口拒绝 难免会得罪人 如果答应下来 自己又无力帮助 这时往往存在矛盾冲突关系 那么如何解决这个问题呢 搭配Online提醒您要注意巧妙拒绝方面的技巧啦 1 耐心倾听对方的请求 即使心里清楚自己最后要拒绝
  • 新榜

    在过去的一个月中 淄博烧烤的相关话题霸屏网络 这些媒介话题里承载了多少受众的向往与想象 根据2022年淄博市文旅局公开年报 去年 淄博官方就着力融媒体 在抖音 快手等平台创新使用 淄博到底有多牛 主题形式 通过视频内容和文案策划 长效推广淄
  • Simpsons’ Hidden Talents【KMP模板题】

    Homer Marge I just figured out a way to discover some of the talents we weren t aware we had Marge Yeah what is it Homer
  • 区块链的数据是存储在链上,还是在数据库中?(答案是这个问题并不成立,来一起了解一下吧)

    很多人都想了解区块链的数据到底什么时候是存储在链上 什么时候又储存在相应节点的数据库中间呢 今天我们就来解决这个有趣的问题 首先我们必须了解清楚两个概念 区块链数据 链上数据 首先 区块链数据包括区块数据和状态数据两者 区块数据描述的实际是
  • hive分区表详细介绍

    一 什么是分区表以及作用 数据分区的概念以及存在很久了 通常使用分区来水平分散压力 将数据从物理上移到和使用最频繁的用户更近的地方 以及实现其目的 hive中有分区表的概念 我们可以看到分区具重要性能优势 而且分区表还可以将数据以一种符合逻
  • Datalore安装使用教程

    发现一个jetbrain出的好东西 使用体验完爆jupyter notebook以及jupyter lab的软件 就是安装有点复杂 官网写得有点不清楚 这里简单介绍一下 首先他只能在linux运行 其他环境暂时不支持 首先 去https w
  • react简要分析

    一 简介 前段时间看到一个用33行代码就实现了一个非常基本的react代码 感觉还是蛮有趣的 代码如下 其主要实现了两大功能 生成虚拟DOM 根据虚拟DOM渲染出真实的DOM 无注释版 https github com leontrolsk
  • linux下查看物理CPU个数、核数、逻辑CPU个数

    cat proc cpuinfo中的信息 processor 逻辑处理器的id physical id 物理封装的处理器的id core id 每个核心的id cpu cores 位于相同物理封装的处理器中的内核数量 siblings 位于
  • 消息队列中间件 - 详解RabbitMQ6种模式

    RabbitMQ 6种工作模式 对RabbitMQ 6种工作模式 简单模式 工作模式 订阅模式 路由模式 主题模式 RPC模式 进行场景和参数进行讲解 PHP代码作为实例 安装 客户端实现 添加扩展 执行composer phar inst
  • 《计算机网络—自顶向下方法》 Wireshark实验(七):以太网与ARP协议分析

    1 以太网 1 1 介绍 以太网是现实世界中最普遍的一种计算机网络 以太网有两类 第一类是经典以太网 第二类是交换式以太网 使用了一种称为交换机的设备连接不同的计算机 经典以太网 是以太网的原始形式 运行速度从 3 10 Mbps 不等 交
  • 51单片机实战 1 --四个独立按键控制四位数码管

    本文基于普中51开发板 在其例程代码稍加改动而成的 单片机的入门小项目也很益智 启动单片机 四位数码管显示0000 按下s1并松开 显示1000 再按下s1并松开显示2000 连续10次按下并松开s2 数码管显示2100 2200 2300
  • WSL安装图形界面

    效果如下 1 下载并安装VcXsrv 链接如下 https sourceforge net projects vcxsrv 下载完安装一路next即可 或者自行选择安装路径 2 安装桌面环境 安装xfce4 terminalsudo apt
  • mysql的锁

    锁 锁机制用于管理对共享资源的并发访问 用来实现事务的隔离级别 锁类型 共享锁和排他锁都是行级锁 MySQL当中事务采用的是粒度锁 针对表 B 树 页 B 树叶子 节点 行 B 树叶子节点当中某一段记录行 三种粒度加锁 共享锁 S 可理解为
  • Python进阶-----面向对象2.0(特有属性和方法与私有属性和方法)

    目录 前言 1 添加特有属性 方法 示例1 添加特有属性 示例2 添加特有方法 2 私有属性 方法 1 私有化示例 2 私有化属性 方法可以在类的内部使用 3 强制访问私有化属性 方法 4 property装饰器去操作私有属性 方法 总结
  • 【测试入门】测试用例经典设计方法 —— 因果图法

    01 因果图设计测试用例的步骤 1 分析需求 阅读需求文档 如果User Case很复杂 尽量将它分解成若干个简单的部分 这样做的好处是 不必在一次处理过程中考虑所有的原因 没有固定的流程说明究竟分解到何种程度才算简单 需要测试人员根据自己
  • 【LeetCode-面试经典150题-day24】

    目录 35 搜索插入位置 74 搜索二维矩阵 162 寻找峰值 33 搜索旋转排序数组 35 搜索插入位置 题意 给定一个排序数组和一个目标值 在数组中找到目标值 并返回其索引 如果目标值不存在于数组中 返回它将会被按顺序插入的位置 请必须
  • 详解UART、I2C、SPI常用通信协议(全是细节)

    前言 UART I2C和SPI是我们在嵌入式开发中比较常见的通信协议了 没有最好的通信协议 每个通信协议都有自己的优缺点 如果想要通信速度快 SPI 将是理想的选择 如果用户想要连接多个设备而不是过于复杂 I2C 将是理想的选择 因为它最多
  • Java fail-fast与fail-safe

    fail fast和fail safe比较 java util包下面的所有的集合类都是快速失败的 而java util concurrent包下面的所有的类都是安全失败的 快速失败的迭代器会抛出ConcurrentModificationE
  • mac如何添加新的字体格式(以word中仿宋_GB2312为例)

    注意 字体中必须出现GB 2312格式的选项 才算成功
  • C#创建TCP服务器与客户端互传消息实例

    本项目使用C 语言建立一个TCP通讯实例 并可以互相传递消息 传送一下传智播客赵老师的视频课程 关键词解释 1 TCP协议 一种可以用于网络通信的数据传输协议 传输安全可靠不会有信息丢失 重点理解三次握手与四次分手 2 线程Thread 我