Socket Websocket 客户端和服务端实现

news2024/10/3 10:34:12

最近在写一个上位机,用到了Websocket,这里就整理一下,顺便把Socket的东西也整理的了,方便以后查阅。

Socket Websocket 客户端和服务端实现

  • Socket客户端和服务端实现
    • Socket客户端
    • Socket服务端
    • 实现效果
  • Websocket 客户端和服务端实现
    • Websocket 客户端
    • Websocket 服务端
    • 实现效果
    • 参考资料

Socket客户端和服务端实现

Socket客户端

//创建负责通信的socket
Socket socketSend;
private void btnConnect_Click(object sender, EventArgs e)
{
    btnConnect.Enabled = false;
    btnStop.Enabled = true;
    try
    {
        //创建负责通信的socket
        socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//AddressFamily.InterNetwork表示ipv4
        IPAddress iPAddress = IPAddress.Parse(tbxIP.Text);//IP地址
        IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, Convert.ToInt32(tbxPort.Text));//端口号
        //获得要连接的远程服务器的IP和端口号;
        socketSend.Connect(iPEndPoint);
        ShowMess("连接成功");
        Thread th = new Thread(RecData);
        th.IsBackground = true;
        th.Start(socketSend);
    }
    catch (Exception ex)
    {
        ShowMess(Convert.ToString(ex));
    }
}

void RecData(object o)
{
    Socket socketSend = o as Socket;
    try
    {
        while (true)
        {
            byte[] buffer = new byte[1021 * 1021 * 2];
            int r = socketSend.Receive(buffer);
            if (r == 0) break;
            string str = Encoding.UTF8.GetString(buffer, 0, r);
            ShowMess(socketSend.RemoteEndPoint.ToString() + ":" + str);
        }
    }
    catch (Exception ex)
    {
        ShowMess(Convert.ToString(ex));
    }
}

void ShowMess(string str)
{
    tbxAppend.AppendText(str + "\r\n");
}

/// <summary>
/// 客户端给服务器发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
    try
    {
        string str = tbxSend.Text.Trim();
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
        socketSend.Send(buffer);
    }
    catch (Exception ex)
    {
        ShowMess(Convert.ToString(ex));
    }
}

private void Form1_Load(object sender, EventArgs e)
{
    Control.CheckForIllegalCrossThreadCalls = false;
    btnStop.Enabled = false;
}

private void btnStop_Click(object sender, EventArgs e)
{
    btnConnect.Enabled = true;
    btnStop.Enabled = false;
    socketSend.Close();
    ShowMess("断开连接  " + DateTime.Now);
}

在这里插入图片描述

Socket服务端

Socket socketWatch;
/// <summary>
/// 点击开始监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click(object sender, EventArgs e)
{
    btnStart.Enabled = false;
    btnStop.Enabled = true;
    try
    {
        //当点击开始时,服务器创建一个负责监听IP地址和端口号的socket;
        socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPAddress ip = IPAddress.Parse(tbxIP.Text);
        IPEndPoint port = new IPEndPoint(ip, Convert.ToInt32(tbxPort.Text));//创建端口号对象
        //监听,绑定监听端口
        socketWatch.Bind(port);
        ShowMess("监听成功 时间:" + DateTime.Now);
        //设定监听队列数量socket处于监听状态
        socketWatch.Listen(10);
        Thread th = new Thread(Listen);//accept方法会阻碍主线程,所以开启新的线程;
        th.IsBackground = true;//将线程设置为后台线程
        th.Start(socketWatch);//线程等待cpu处理
    }
    catch(Exception ex)
    {
        //ShowMess(Convert.ToString(ex));
    }
}

Socket socketSend;//等待客户端的连接并创建一个负责通信的socket
/// <summary>
/// 等待客户端的连接并创建一个负责通信的socket
/// </summary>
void Listen(object o)//object 线程参数必须为object
{
    Socket socketWatch = o as Socket;
    while (true)
    {
        try
        {
            //等待客户端的连接并创建一个负责通信的socket
            socketSend = socketWatch.Accept();
            //将远程的客户端的IP和socket存入合集;
            dicsocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
            //下拉框添加ip地址
            cbxIP.Items.Add(socketSend.RemoteEndPoint.ToString());
            ShowMess(socketSend.RemoteEndPoint.ToString() + ":连接成功");
            //开启一个新的线程不停接受客户端发送的数据;
            Thread th = new Thread(RecData);
            th.IsBackground = true;
            th.Start(socketSend);
        }
        catch (Exception ex)
        {
            //ShowMess(Convert.ToString(ex));
        }
    }
}

//将远程的客户端的IP和socket存入合集;
Dictionary<string, Socket> dicsocket = new Dictionary<string, Socket>();
/// <summary>
/// 服务器不停的接受客户端发来的数据
/// </summary>
/// <param name="o"></param>
void RecData(object o)
{
    Socket socketSend = o 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);
            ShowMess(socketSend.RemoteEndPoint.ToString() + ":" + str);
        }
        catch (Exception ex)
        {
            //ShowMess(Convert.ToString(ex));
        }
    }
}



/// <summary>
/// 信息显示
/// </summary>
/// <param name="str"></param>
void ShowMess(string str)
{
    tbxAppend.AppendText(str + "\r\n");
}

private void Form1_Load(object sender, EventArgs e)
{
    //允许跨线程访问
    Control.CheckForIllegalCrossThreadCalls = false;
    btnStop.Enabled = false;
}

/// <summary>
/// 服务器给客户端发送数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
    try
    {
        string str = tbxSend.Text.Trim();
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
        //获取下拉框的IP地址;
        string ip = cbxIP.SelectedItem.ToString();
        //socketSend.Send(buffer);
        dicsocket[ip].Send(buffer);
    }
    catch (Exception ex)
    {
        ShowMess(Convert.ToString(ex));
    }
}

private void btnStop_Click(object sender, EventArgs e)
{
    btnStart.Enabled = true;
    btnStop.Enabled = false;
    //socketWatch.Close();
    socketSend.Close();

    cbxIP.Items.Clear();
    ShowMess("停止成功 时间:" + DateTime.Now);
}

在这里插入图片描述

实现效果

在这里插入图片描述

相关工程代码我放在了CSDN资源里:《Socket-Sever-Client》

Websocket 客户端和服务端实现

Websocket 客户端

工具 —>Nuget包管理 —>管理解决方案的Nuget程序包 —>搜索 WebSocket4Net ,选择WebSocket4Net,点击右侧 安装,等待安装完成,安装完成以后,项目会多出很多引用库,如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

private void Form1_Load(object sender, EventArgs e)
{

}

public static WebSocket webSocket4Net = null;
public void websocketClient()
{
    textBox4.AppendText("我是客户端" + "\r\n");//打印相关消息

    webSocket4Net = new WebSocket("ws://" + textBox1.Text.ToString() + ":" + textBox2.Text.ToString());
    webSocket4Net.Opened += WebSocket4Net_Opened;
    webSocket4Net.Error += websocket_Error;
    webSocket4Net.Closed += new EventHandler(websocket_Closed);
    webSocket4Net.MessageReceived += WebSocket4Net_MessageReceived;
    webSocket4Net.Open();
}

private void WebSocket4Net_MessageReceived(object sender, MessageReceivedEventArgs e)
{
    textBox4.AppendText("服务端回复的数据:" + e.Message + "\r\n");//打印相关消息
}

private void WebSocket4Net_Opened(object sender, EventArgs e)
{
    textBox4.AppendText("客户端连接成功!发送数据中..." + "\r\n");//打印相关消息
    webSocket4Net.Send("来自客户端,准备发送数据!" + "\r\n");//向服务端发送数据
}

private void websocket_Error(object sender, EventArgs e)//webSocket错误响应
{
    textBox4.AppendText("WebSocket错误" + "\r\n");
    Thread.Sleep(5000);//等待一段时间后重新连接
    if (webSocket4Net.State != WebSocketState.Open && webSocket4Net.State != WebSocketState.Connecting)
    {
        websocketClient();
    }
}

private void websocket_Closed(object sender, EventArgs e)//webSocket关闭响应
{
    textBox4.AppendText("WebSocket已关闭" + "\r\n");
    Thread.Sleep(5000);//等待一段时间后重新连接
    if (webSocket4Net.State != WebSocketState.Open && webSocket4Net.State != WebSocketState.Connecting)
    {
        websocketClient();
    }
}

private void button2_Click(object sender, EventArgs e)//发送按钮
{
    webSocket4Net.Send(textBox3.Text.ToString());
}

private void button1_Click(object sender, EventArgs e)//连接按钮
{
    websocketClient();
}

在这里插入图片描述

Websocket 服务端

工具 —>Nuget包管理 —>管理解决方案的Nuget程序包 —>搜索 SuperWebSocket ,选择SuperWebSocketNETServer,点击右侧 安装,等待安装完成,安装完成以后,项目会多出很多引用库,如下
在这里插入图片描述

public Form1()
{
    InitializeComponent();
}

private void websocketServer()
{
    textBox1.AppendText("我是服务端" + "\r\n");//打印相关消息

    WebSocketServer webSocketServer = new WebSocketServer();
    webSocketServer.NewSessionConnected += WebSocketServer_NewSessionConnected;
    webSocketServer.NewMessageReceived += WebSocketServer_NewMessageReceived;
    webSocketServer.SessionClosed += WebSocketServer_SessionClosed;

    if (!webSocketServer.Setup("127.0.0.1", 1234))
    {
        textBox1.AppendText("设置服务监听失败!" + "\r\n");
    }
    if (!webSocketServer.Start())
    {
        textBox1.AppendText("启动服务监听失败!" + "\r\n");
    }
    textBox1.AppendText("启动服务监听成功!" + "\r\n");
}

private void WebSocketServer_NewSessionConnected(WebSocketSession session)
{
    textBox1.AppendText("欢迎客户端: 加入" + "\r\n");
    //SendToAll(session, msg);
}

private void WebSocketServer_NewMessageReceived(WebSocketSession session, string value)
{
    textBox1.AppendText("服务端收到客户端的数据 ==》" + value + "\r\n");
    //SendToAll(session, value);
}

private void WebSocketServer_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value)
{
    textBox1.AppendText("客户端:关闭,原因:" + "\r\n");
    //SendToAll(session, msg);
}

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

在这里插入图片描述

实现效果

在这里插入图片描述

相关工程代码我放在了CSDN资源里:《C# 实现的WebSocket服务端和客户端》

参考资料

【计算机网络 13】使用C#实现websocket服务端与客户端通信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/95062.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT Linux环境搭建——VM虚拟机和Ubuntu的安装

1、从ubuntu官网上下载iso镜像文件&#xff0c;该镜像文件用于安装linux操作系统&#xff0c;以下微官网链接 Enterprise Open Source and Linux | Ubuntu 选择一个最新的稳定版本下载即可&#xff08;好处是&#xff0c;不需要像一些别的网站&#xff0c;必须要注册&#xff…

基于java+springmvc+mybatis+vue+mysql的远程家庭健康监测管理系统小程序

项目介绍 本系统采用java语言开发&#xff0c;后端采用ssm框架&#xff0c;前端采用vue技术&#xff0c;数据库采用mysql进行数据存储。 前台&#xff1a; 登录注册、查看个人信息、留言反馈、查看健康信息、查看百科、社区交流 后台&#xff1a; 首页、个人中心、用户管理、…

陈天老师的Rust培训(2)学习笔记

所有权&#xff1a; Rust中的每一个值都有一个被称为其 所有者&#xff08;owner&#xff09;的变量值在任一时刻有且只有一个所有者。当所有者(变量)离开作用域的时候&#xff0c;这个值将被丢弃。 Copy的类型&#xff1a; 所有整数类型&#xff0c;比如u32。布尔类型所有浮…

本地springboot jar 部署到云服务器linux [安装jdk 安装msyql]

A). 安装jdk 参考博客CentOS 8 安装 JAVA 三种方式(yum / rpm / tar.gz) [rootiZt4ned91xzjstx1s6ftjvZ local]# rpm -qa |grep java [rootiZt4ned91xzjstx1s6ftjvZ local]# rpm -qa |grep jdk [rootiZt4ned91xzjstx1s6ftjvZ local]# rpm -qa |grep jre [rootiZt4ned91xzjstx…

bug:解决java.security.InvalidKeyException: Illegal key size or default parameters

bug:解决java.security.InvalidKeyException: Illegal key size or default parameters 1 复现 今天对接外链需要使用AES加密的时候&#xff0c;对方使用的是AES&#xff1a;AES/ECB/PKCS7Padding&#xff0c;但是在加密过程中&#xff0c;发现报错 报错信息&#xff1a;java.…

Spark Shell 的使用

Spark Shell 的使用 Spark shell 作为一个强大的交互式数据分析工具&#xff0c;提供了一个简单的方式学习 API。它可以使用 Scala&#xff08;在Java 虚拟机上运行现有的Java库的一个很好方式&#xff09;或 Python。 Spark Shell 命令 启动 Spark Shell 的时候我们可以指定…

JavaIO

CPU指令与内核态、用户态 在操作系统中&#xff0c;CPU负责执行指令,这些指令有些来自应用程序&#xff0c;有些是来自底层系统。 有些指令是非常危险的&#xff0c;如清除内存&#xff0c;网络连接等等&#xff0c;如果错误调用的话有可能导致系统崩溃。 因而CPU将指令分为特…

Excel表格的打开密码如何设置和取消?

给Excel表格设置“打开密码”是保护表格的其中一种方法&#xff0c;这样只有输入正确的密码才能打开表格。 那Excel表格的打开密码如何设置和取消呢&#xff1f; 首先&#xff0c;打开Excel表格&#xff0c;点击菜单栏的【文件】选项&#xff0c;然后依次选择【信息】-【保护…

java项目-第175期ssm高校校园点餐系统-java毕业设计

java项目-第175期ssm高校校园点餐系统-java毕业设计 【源码请到下载专栏下载】 今天分享的项目是《ssm高校校园点餐系统》 该项目分为2个角色&#xff0c;管理员、用户和食堂。 用户可以浏览前台,查看菜品&#xff0c;并进行预约和选座&#xff1b; 同时可以跳转到后台查看自己…

基于jsp+mysql+ssm矿场仓储管理系统-计算机毕业设计

项目介绍 本系统采用了BS架构&#xff0c;利用web技术实现了矿场信息的后台管理&#xff0c;针对矿物质的相关信息&#xff0c;销售情况进行管理。是一款后台信息管理系统&#xff0c;具有管理员和员工两个用户权限&#xff0c;系统设计简单&#xff0c;主要是学习资源&#x…

[R语言]正态分布

目录 分布 连续型变量的分布 正态分布 正态分布的推导 正态分布密度曲线 dnorm 正态分布的概率计算 正态分布累积曲线 总体分位数和尾概率 正态分布案例之一 R语言正态分布函数 正态分布相应的概率计算 正态分布的检验 shapiro.test()函数 Kolmogorov-Smirnov连续…

5.3 10篇美食类小红书爆文拆解【玩赚小红书】

案例一&#xff1a;金牌保姆分享12个万能做饭小技巧 ​ 标题&#xff1a; 万能做饭小技巧这个词可以看的出这个方法都是偏向技巧类&#xff0c;对于人人都有做饭的需求来说&#xff0c;也忍不住让人想看看到底是什么内容。“金牌保姆”四个字可谓是将“万能”这2个字完美诠释&…

首次曝光,Alibaba大佬手撸堪称神级的SpringSecurity全彩手册

有人调侃我们说&#xff1a; 程序员不如送外卖。送外卖是搬运食物&#xff0c;自己是搬运代码&#xff0c;都不产出新的东西……透支体力&#xff0c;又消耗健康&#xff0c;可替代性极强&#xff0c;30岁之后就要面临被优化的危险……想跳槽&#xff0c;但是更高的平台难进&a…

2023年你应该了解的五大采购管理趋势

采购的未来看起来非常具有前景。随着新技术的出现&#xff0c;采购专业人员有许多新的机会来简化他们的工作并节省企业的资金。 以下是一些你应该了解的2023年采购领域趋势。 1、自动化 采购的最大趋势之一是各种任务的自动化。这可以是任何事情&#xff0c;从自动化询价&am…

STC15 - C51 - 操作寄存器时, 不要操作不相关的位

文章目录STC15 - C51 - 操作寄存器时, 不要操作不相关的位概述笔记生成.i文件的选项编译工程后, 查看.list文件和.i文件.c文件相关内容.list文件.i文件通过.i文件(预处理文件), 就可以看到最终实现代码有啥区别了不好使的代码好使的代码总结ENDSTC15 - C51 - 操作寄存器时, 不要…

分布式系统(故障、恢复)

文章目录故障模型可靠组播基于基本组播基于 IP 组播协定问题ConsensusByzantine generalsInteractive Consistency一些重要结论分布式恢复后向恢复Checkpointing AlgorithmCoordinated CheckpointingIndependent CheckpointingMessage Logging AlgorithmPessimistic message lo…

[附源码]Node.js计算机毕业设计高校运动会管理系统 Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

95.(leaflet之家)leaflet态势标绘-进攻方向采集(燕尾)

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html> <

快速传输大文件,怎么通过网络传大文件给对方(1G以上)

在生活和工作中&#xff0c;我们总是要发送一些比较大的文件给别人&#xff0c;或者在自己的设备之间。在互联网日益发达的今天&#xff0c;我们可以用什么方法通过互联网快速传输大文件&#xff0c;发送1G以上的文件&#xff1f; 一、使用QQ传 在电脑上打开QQ&#xff0c;选…

【技术评论】大数据时代,区块链如何解决数据安全和隐私问题

发表时间&#xff1a;2022年6月23日 信息来源&#xff1a;bsvblockchain.org 在这个时代&#xff0c;像GDPR和HIPAA这样的措施为消费者带来了前所未有的数据保护水平&#xff0c;人们理所当然地想知道&#xff0c;由区块链驱动的数据解决方案如何能够符合这些法规的要求。 (全…