.NET高级面试指南专题七【SocketWebSocket】

news2024/11/28 4:47:53

在这里插入图片描述

Socket(套接字)是一种在计算机网络中实现通信的一种机制,它提供了一种标准的接口,使不同计算机上的程序能够通过网络进行数据交换。Socket允许在网络中的不同设备之间建立连接,进行双向的数据传输。
Socket通常用于实现客户端-服务器模型,其中一个程序充当服务器,等待其他程序(客户端)连接并进行通信。这种模型是许多网络应用的基础,如网页浏览器与服务器之间的通信、即时通讯软件等。

一般来说,Socket通信的基本流程如下:

服务器程序创建一个Socket并绑定到一个特定的端口,然后开始监听客户端的连接请求。
客户端程序创建一个Socket,并尝试连接到服务器的IP地址和端口。 一旦连接建立,数据可以在服务器和客户端之间进行双向传输。

在这里插入图片描述
Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。

在这里插入图片描述
一个简单的C# Socket代码示例
展示了一个基本的服务器和客户端通信。这个例子使用了同步的阻塞方式,真实的应用中可能需要考虑使用异步编程以提高性能。

服务器端代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class Server
{
    static void Main()
    {
        TcpListener server = null;

        try
        {
            // 设置IP地址和端口
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            int port = 12345;

            // 创建TcpListener对象
            server = new TcpListener(ipAddress, port);

            // 开始监听
            server.Start();
            Console.WriteLine("等待客户端连接...");

            // 接受连接请求
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("客户端已连接");

            // 获取网络流
            NetworkStream stream = client.GetStream();

            // 发送和接收数据
            byte[] data = new byte[256];
            int bytesRead;

            while ((bytesRead = stream.Read(data, 0, data.Length)) != 0)
            {
                string message = Encoding.ASCII.GetString(data, 0, bytesRead);
                Console.WriteLine($"接收到消息: {message}");

                // 回复客户端
                string response = "服务器已收到消息";
                byte[] responseData = Encoding.ASCII.GetBytes(response);
                stream.Write(responseData, 0, responseData.Length);
            }

            // 关闭连接
            client.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生异常: {ex.Message}");
        }
        finally
        {
            // 停止监听
            server.Stop();
        }
    }
}

客户端代码:

using System;
using System.Net.Sockets;
using System.Text;

class Client
{
    static void Main()
    {
        try
        {
            // 设置服务器的IP地址和端口
            TcpClient client = new TcpClient("127.0.0.1", 12345);
            Console.WriteLine("连接到服务器");

            // 获取网络流
            NetworkStream stream = client.GetStream();

            // 发送数据
            string message = "Hello, server!";
            byte[] data = Encoding.ASCII.GetBytes(message);
            stream.Write(data, 0, data.Length);
            Console.WriteLine($"发送消息: {message}");

            // 接收服务器的响应
            data = new byte[256];
            int bytesRead = stream.Read(data, 0, data.Length);
            string response = Encoding.ASCII.GetString(data, 0, bytesRead);
            Console.WriteLine($"服务器响应: {response}");

            // 关闭连接
            client.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生异常: {ex.Message}");
        }
    }
}

WebSocket

WebSocket是一种在单个TCP连接上进行全双工通信的通信协议,它使得客户端和服务器之间可以实时地进行双向数据传输。WebSocket通常用于实现实时的Web应用程序,如在线聊天、实时协作编辑和实时通知等。

WebSocket出现的原因,哪些因素触发产生WebSocket

以前网站上的即时通讯是很常见的,比如网页的QQ,聊天系统等。按照以往的技术能力通常是采用轮询、Comet技术解决。
HTTP协议是非持久化的,单向的网络协议,在建立连接后只允许浏览器向服务器发出请求后,服务器才能返回相应的数据。当需要即时通讯时,通过轮询在特定的时间间隔(如1秒),由浏览器向服务器发送Request请求,然后将最新的数据返回给浏览器。这样的方法最明显的缺点就是需要不断的发送请求,而且通常HTTP
request的Header是非常长的,为了传输一个很小的数据 需要付出巨大的代价,是很不合算的,占用了很多的宽带。

下面是WebSocket的一些关键特点和工作原理:

特点:

  • 全双工通信: WebSocket允许客户端和服务器之间进行双向实时通信,而不需要每次通信都创建新的连接。

  • 低延迟: 由于使用了单个TCP连接,WebSocket相对于一些传统的轮询技术来说,具有更低的延迟。

  • 轻量级: WebSocket协议相对简单,数据帧的头部开销小,降低了通信的开销。

  • 协议标准化: WebSocket协议已经被标准化,有相关的RFC文档(RFC 6455),这使得不同平台和语言之间能够进行兼容性的实现。

工作原理:

  • 握手阶段: 在建立WebSocket连接之前,客户端首先通过HTTP发送一个特殊的请求,包含WebSocket版本信息和一些其他头部信息。服务器在接收到这个请求后,如果支持WebSocket,就会响应一个类似的包含协议升级请求的HTTP响应。

  • 建立连接: 客户端和服务器之间的握手成功后,连接从HTTP协议升级到WebSocket协议。此时,客户端和服务器可以在同一个TCP连接上发送和接收WebSocket数据帧。

  • 双向数据传输: 一旦连接建立,客户端和服务器可以在任何时候通过发送WebSocket数据帧来实时交换信息。数据帧可以是文本、二进制等。

  • 关闭连接: 当通信结束时,任何一方都可以发送一个特殊的帧(Close Frame)来关闭WebSocket连接。另一方接收到该帧后也发送一个带有关闭码的响应帧,然后双方都关闭连接。

WebSocket在实时性要求较高的应用场景中非常有用,因为它提供了一种高效、低延迟的双向通信方式,适用于Web应用中需要实时性和即时通信的各种情境。

在C#中,可以使用.NET Core的System.Net.WebSockets库来实现WebSocket通信。以下是一个简单的C# WebSocket服务器和客户端的代码示例:
服务器端代码:

using System;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

class WebSocketServer
{
    public static async Task StartServerAsync(string ipAddress, int port)
    {
        HttpListener listener = new HttpListener();
        listener.Prefixes.Add($"http://{ipAddress}:{port}/");
        listener.Start();
        Console.WriteLine($"WebSocket server listening on http://{ipAddress}:{port}/");

        while (true)
        {
            HttpListenerContext context = await listener.GetContextAsync();
            if (context.Request.IsWebSocketRequest)
            {
                ProcessWebSocketRequest(context);
            }
            else
            {
                context.Response.StatusCode = 400;
                context.Response.Close();
            }
        }
    }

    private static async void ProcessWebSocketRequest(HttpListenerContext context)
    {
        WebSocket webSocket = await context.AcceptWebSocketAsync(null);

        Console.WriteLine("WebSocket connection established");

        byte[] buffer = new byte[1024];
        WebSocketReceiveResult result;

        do
        {
            result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

            if (result.MessageType == WebSocketMessageType.Text)
            {
                string receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);
                Console.WriteLine($"Received message: {receivedMessage}");

                // Echo the message back to the client
                await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), WebSocketMessageType.Text, true, CancellationToken.None);
            }
        }
        while (!result.CloseStatus.HasValue);

        await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
        Console.WriteLine("WebSocket connection closed");
    }

    static void Main()
    {
        StartServerAsync("127.0.0.1", 8080).Wait();
    }
}

客户端代码:

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

class WebSocketClient
{
    public static async Task StartClientAsync(string serverUri)
    {
        using (ClientWebSocket webSocket = new ClientWebSocket())
        {
            await webSocket.ConnectAsync(new Uri(serverUri), CancellationToken.None);
            Console.WriteLine("Connected to WebSocket server");

            Task receiveTask = ReceiveMessageAsync(webSocket);

            // Sending a sample message
            string message = "Hello, server!";
            byte[] messageBytes = Encoding.UTF8.GetBytes(message);
            await webSocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None);

            // Keep the application running
            Console.ReadLine();
        }
    }

    private static async Task ReceiveMessageAsync(ClientWebSocket webSocket)
    {
        byte[] buffer = new byte[1024];

        while (webSocket.State == WebSocketState.Open)
        {
            WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

            if (result.MessageType == WebSocketMessageType.Text)
            {
                string receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);
                Console.WriteLine($"Received message: {receivedMessage}");
            }
        }
    }

    static void Main()
    {
        StartClientAsync("ws://127.0.0.1:8080").Wait();
    }
}

WebSocket 和Socket的区别
WebSocket和Socket是两种不同的通信机制,有一些关键的区别:

  1. 协议层次: WebSocket: 是一种在应用层实现的协议,建立在HTTP协议之上。它通过HTTP协议的握手阶段升级到WebSocket协议,实现了全双工通信。
    Socket: 是一种通用的套接字编程接口,可以在应用层之下的传输层(通常是TCP或UDP)直接进行数据交换。
  2. 双向通信: WebSocket: 支持全双工通信,允许客户端和服务器之间同时进行数据的发送和接收。 Socket: 也支持全双工通信,但需要在编程中明确实现。
  3. 协议解析: WebSocket: 使用标准的WebSocket协议,帧格式和握手机制都被协议规范明确定义。 Socket: 在传输层(TCP或UDP)上,应用程序需要自行定义通信协议和数据格式。
  4. 通信开销: WebSocket: 握手阶段的开销相对较大,但一旦建立连接,数据帧的头部相对较小,通信开销较低。 Socket: 不需要握手,但需要应用程序自行管理通信协议,可能会有较大的通信开销。
  5. 应用场景: WebSocket: 适用于Web应用中需要实时性和即时通信的场景,如在线聊天、实时协作编辑等。 Socket: 更通用,适用于各种应用场景,包括文件传输、远程控制等。
  6. 跨域支持:
    WebSocket: 由于WebSocket协议是在HTTP协议上升级而来,因此支持跨域通信。
    Socket: 在一些环境中可能需要专门的处理来支持跨域通信。

总体而言,WebSocket是一种高层次的通信协议,针对实时性和双向通信进行了优化,适用于Web应用中。Socket是一种通用的套接字编程接口,可以灵活地实现各种通信需求,但需要应用程序自行管理通信协议。选择WebSocket还是Socket取决于具体的应用需求和环境。

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

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

相关文章

C语言学习day13:for循环练习(生成随机数)

题目&#xff1a; 通过程序随机一个1-100的数&#xff0c;用户通过键盘输入数字 看是否匹配&#xff0c;匹配成功则跳出循环&#xff0c;失败则继续循环。 思路&#xff1a; 然后生成一个随机数需要写成死循环&#xff0c;同时需要有其他的出口可以写一个提示&#xff0c;比…

猫头虎分享已解决Bug || 任务调度失败(Cron Job Failure):CronJobError, ScheduledTaskFailure

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

炫酷3D按钮

一.预览 该样式有一种3D变换的高级感&#xff0c;大家可以合理利用这些样式到自己的按钮上 二.代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice…

URL编码算法:解决特殊字符在URL中的烦恼

引言&#xff1a; URL编码算法是一种将URL中的特殊字符转换为特定格式的编码方式。它在网络传输中起到了保护数据安全与完整性的重要作用。本文将深入探讨URL编码算法的优点与缺点&#xff0c;并介绍它在Web开发、网络安全等方面的应用。 URL编码解码 | 一个覆盖广泛主题工具…

Decian 12.x基于LNMP安装phpIPAM(IP管理系统)

phpipam是一个开源Web IP地址管理应用程序&#xff08;IPAM&#xff09;。其目标是提供轻便&#xff0c;且有用的IP地址管理系统。它是基于PHP的应用程序&#xff0c;具有MySQL数据库后端&#xff0c;使用jQuery库&#xff0c;ajax和HTML5 / CSS3功能。 在Debian 12中&…

20240212请问如何将B站下载的软字幕转换成为SRT格式?

20240212请问如何将B站下载的软字幕转换成为SRT格式&#xff1f; 2024/2/12 12:47 百度搜索&#xff1a;字幕 json 转 srt json srt https://blog.csdn.net/a_wh_white/article/details/120687363?share_token2640663e-f468-4737-9b55-73c808f5dcf0 https://blog.csdn.net/a_w…

PHP开发日志 ━━ 深入理解三元操作与一般条件语句的不同

概况 三元运算符的功能与“if…else”流程语句一致。 在一般情况下&#xff0c;三元操作替换if条件语句可以精简代码&#xff0c;并且更为直观&#xff0c;但是在下面的情况中使用三元操作将会返回警告。 借图&#xff1a; 案例 比如原代码&#xff1a; class classA{publ…

Vue3.0(六):VueX 4.x详解

Vuex4状态管理 什么是状态管理 在开发中&#xff0c;我们的应用程序需要处理各种各样的数据&#xff0c;这些数据需要保存在应用程序的某一个位置&#xff0c;对于这些数据的管理&#xff0c;就是 状态管理目前前端项目越来越复杂&#xff0c;多组件共享同一数据的状态很常见…

高校危化试剂管理:Java与SpringBoot的革新

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

机器学习2---逻辑回归(基础准备)

逻辑回归是基于线性回归是直线分的也可以做多分类 ## 数学基础 import numpy as np np.pi # 三角函数 np.sin() np.cos() np.tan() # 指数 y3**x # 对数 np.log10(10) np.log2(2) np.e np.log(np.e) #ln(e)# 对数运算 # log(AB) log(A) logB np.log(3*4)np.log(3)np.log(4) #…

HTML5+CSS3+移动web——HTML 基础

目录 一、标签语法 HTML的基本框架 1. 标题标签 2. 段落标签 3. 换行和水平线 4. 文本格式化标签 5. 图像标签 6. 路径 相对路径 绝对路径 7. 超链接标签 8. 音频 9. 视频 10. 注释 二、标签结构 一、标签语法 HTML 超文本标记语言——HyperText Markup Langua…

【大数据Hive】hive 表设计常用优化策略

目录 一、前言 二、hive 普通表查询原理 2.1 操作演示说明 2.1.1 创建一张表&#xff0c;并加载数据 2.1.2 统计3月24号的登录人数 2.1.3 查询原理过程总结 2.2 普通表结构带来的问题 三、hive分区表设计 3.1 区表结构 - 分区设计思想 3.2 操作演示 3.2.1 创建分区表…

如何使用六图一表七种武器

六图一表七种武器用于质量管理&#xff1a; 描述当遇到问题时应该用那张图来解决&#xff1a; 一、如果题目说出了质量问题需要找原因&#xff1f; 解&#xff1a;用因果图&#xff0c;因果图也称石川图或鱼骨图 二、如果要判断过程是否稳定受控&#xff1f; 解&#xff1a…

谷歌浏览器,如何将常用打开的网站创建快捷方式到电脑桌面?

打开谷歌浏览器&#xff0c;打开想要创建的快捷方式的网页 点击浏览器右上角的三个点&#xff1a; 点击选择【更多工具】 选择【创建快捷方式】 然后&#xff0c;在浏览器上方会弹出一个框&#xff0c;让命名此创建的快捷方式的名称 命名好之后&#xff0c;再点击【创…

Python-web自动化-Playwright的学习

Python-web自动化-Playwright的学习 1. 安装playwright2. 界面等待3. 自动化代码助手4. 定位元素1. css selector定位2. xpath定位3. get_by_XXX定位 5. 操作元素1. 单选框、复选框2. select下拉框3. 网页操作4. 框架页 frame5. 窗口切换6. 截屏 1. 安装playwright pip命令 pi…

【Windows】常用快捷键

文章目录 文本编辑相关快捷键窗口管理和操作系统快捷键浏览器快捷键其他常用快捷键系统无响应快捷键 快捷键&#xff1a;shortcut key、keyboard shortcuts。 文本编辑相关快捷键 这部分是非常常用的内容&#xff0c;在很多编辑器中都适用的&#xff0c;比如csdn的markdown和t…

Python 数据分析库之polars使用详解

概要 数据分析是现代应用程序和业务决策的关键组成部分。Python 作为一门强大的编程语言,拥有丰富的数据处理库和工具,其中之一就是 Polars。Polars 是一个现代化的数据操作和分析库,它提供了高性能的数据操作功能,支持链式方法调用,并且兼容 Pandas 和 Arrow 格式。本文…

每日一练——月落乌啼算钱

题目&#xff1a; 举例&#xff1a; 输入&#xff1a;6&#xff0c;输出&#xff1a;8.00 最开始看到这道题还有点蒙&#xff0c;但是看到他的公式想起了斐波那契数列 1,1,2,3,5,8...... 由前两个数相加得到第三个数&#xff0c;为An2An1An。 可以得出这个题目中所给的通项就…

Hive的Join连接、谓词下推

前言 Hive-3.1.2版本支持6种join语法。分别是&#xff1a;inner join&#xff08;内连接&#xff09;、left join&#xff08;左连接&#xff09;、right join&#xff08;右连接&#xff09;、full outer join&#xff08;全外连接&#xff09;、left semi join&#xff08;左…

猫头虎分享:localhost和127.0.0.1的区别是什么?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …