<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>网络编程 on Leanku 的博客</title><link>https://www.leanku.com/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/</link><description>Recent content in 网络编程 on Leanku 的博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 16 Sep 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://www.leanku.com/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>WebSocket 详解：实时双向通信是如何实现的？</title><link>https://www.leanku.com/post/computerscience/websocket-real-time-communication/</link><pubDate>Sat, 16 Sep 2023 00:00:00 +0000</pubDate><guid>https://www.leanku.com/post/computerscience/websocket-real-time-communication/</guid><description>&lt;h1 id="websocket-详解实时双向通信是如何实现的"&gt;WebSocket 详解：实时双向通信是如何实现的？&lt;/h1&gt;&#10;&lt;p&gt;前面几篇分别介绍了 TCP/IP、Socket、HTTP 和 HTTPS。&lt;/p&gt;&#10;&lt;p&gt;到这里，一个问题自然出现了：&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;HTTP 已经可以完成客户端和服务器之间的通信，为什么还需要 WebSocket？&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;因为传统 HTTP 的基本模型是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Request&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Server&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Response&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果服务器想主动通知客户端，就比较麻烦。&lt;/p&gt;&#10;&lt;p&gt;例如：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户收到新消息&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;订单状态发生变化&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;股票价格发生变化&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;游戏状态发生变化&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;服务器有数据更新，但客户端没有主动发请求。&lt;/p&gt;&#10;&lt;p&gt;传统方案只能不断：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client → Server：有新消息吗？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Server → Client：没有&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client → Server：有新消息吗？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Server → Client：没有&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client → Server：有新消息吗？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Server → Client：有&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这就是&lt;strong&gt;轮询&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;WebSocket 的目标就是解决这类问题：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client ⇄ Server&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;建立连接之后，双方都可以主动发送数据。&lt;/p&gt;&#10;&lt;p&gt;RFC 6455 将 WebSocket 定义为一种基于 TCP 的双向通信协议，协议由连接建立握手和数据帧传输两部分组成。&lt;/p&gt;</description></item><item><title>Socket 详解：应用程序如何进行网络通信</title><link>https://www.leanku.com/post/computerscience/socket-network-communication/</link><pubDate>Tue, 18 Jul 2023 00:00:00 +0000</pubDate><guid>https://www.leanku.com/post/computerscience/socket-network-communication/</guid><description>&lt;h1 id="socket-详解应用程序如何进行网络通信"&gt;Socket 详解：应用程序如何进行网络通信&lt;/h1&gt;&#10;&lt;p&gt;上一篇&lt;a href="https://www.leanku.com/post/computerscience/tcp-ip-network-communication"&gt;《TCP/IP 详解：理解互联网通信的基础》&lt;/a&gt;文章介绍了 TCP/IP。&lt;/p&gt;&#10;&lt;p&gt;我们知道：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;应用层&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TCP / UDP&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;IP&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;网络&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TCP/IP 负责完成网络通信，但应用程序并不会直接操作 TCP 报文或者 IP 数据包。&lt;/p&gt;&#10;&lt;p&gt;应用程序通常通过操作系统提供的 &lt;strong&gt;Socket API&lt;/strong&gt; 来使用网络能力。&lt;/p&gt;&#10;&lt;p&gt;因此，如果 TCP/IP 是网络通信的基础，那么 Socket 就是：&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;&lt;strong&gt;应用程序进入网络世界的接口。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;对于后端开发来说，理解 Socket 非常重要。&lt;/p&gt;&#10;&lt;p&gt;HTTP Server、MySQL、Redis、RPC、WebSocket，以及各种 TCP 长连接服务，底层都离不开 Socket。&lt;/p&gt;&#10;&lt;h2 id="1-socket-到底是什么"&gt;1. Socket 到底是什么？&lt;/h2&gt;&#10;&lt;p&gt;Socket 通常翻译为“套接字”。&lt;/p&gt;&#10;&lt;p&gt;它不是一个网络协议，而是一种&lt;strong&gt;网络通信接口和抽象&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;应用程序可以通过 Socket：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;创建通信端点&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;绑定地址&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;建立连接&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;发送数据&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;接收数据&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;关闭连接&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;例如 TCP 服务端的典型流程：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;socket()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bind()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;listen()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;accept()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;read() / write()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;close()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;客户端则通常是：&lt;/p&gt;</description></item></channel></rss>