The First Encounter With Socket
date
Oct 4, 2017
slug
first-meet-socket
status
Published
tags
Socket
summary
type
Post
网络基础 TCP/IP
在讨论 Socket 之前,我们得先追本溯源,看看 TCP/IP 是什么。
计算机与网络设备之间的通信,就如大国之间的外交一样,需要一种规则。这种规则就成称为协议(protocol)。计算机网络协议中存在各种各样的内容:从电缆规格到 IP 地址的选定方法、双方建立通信的顺序,以及 Web 页面显示需要处理的步骤,等等。
而与互联网相关联的协议集合总称为 TCP/IP。
TCP/IP 的分层
TCP/IP 按层次分为4层:应用层、传输层、网络层和数据链路层。
TCP/IP 通信传输流
利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信,发送端从应用层往下走,接收端则从应用层往上走。
Socket 的基本概念
Socket 是对 TCP/IP 协议族的一种封装,是应用层与TCP/IP协议族通信的中间软件抽象层。它把复杂的 TCP/IP 协议族隐藏在 Socket API 后面,对用户来说,一组简单的接口就是全部,让 Socket 去组织数据,以符合指定的协议。也就是说, TCP/IP 提供给程序员做网络开发所用的接口就是 Socket 编程接口。
利用 Socket 建立网络连接的步骤与基本操作
利用 Socket 建立网络至少需要一对 Socket,其中一个运行于客户端,称为 ClientSocket ,运行于服务端的称为 ServerSocket。
套接字(Socket 的译名)之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。
常用的三种 Socket 类型
- 流式 Socket(SOCK_STREAM):流式是一种面向连接的 Socket,针对于面向连接的 TCP服务应用
- 数据报式 Socket(SOCK_DGRAM):数据报式 Socket 是一种无连接的 Socket,对应于无连接的UDP 服务应用。
- Unix 域 Socket (Unix Domain Socket):Socket API原本是为网络通讯设计的,但后来在Socket 的框架上发展出一种IPC机制,就是Unix Domain Socket,用于同一台主机的进程间通讯。虽然网络socket也可用于同一台主机的进程间通讯(通过 loopback 地址127.0.0.1),但是Unix Domain Socket更有效率,不需要经过网络协议栈,只是将应用层数据从一个进程拷贝到另一个进程。
Socket 实践——在 Nodejs 中使用 TCP 套接字编程
服务端代码:
// server.js
const net = require("net");
const host = "127.0.0.1";
const port = 3001;
const server = net
.createServer(c => {
console.log(`客户端${c.remoteAddress}:${c.remotePort}已连接`);
// "data" 事件处理函数
c.on("data", data => {
console.log(`来自客户端${c.remoteAddress}:${c.remotePort}的数据:${data}`);
c.write(`已收到你的数据`);
});
c.on("end", () => {
console.log(`客户端${c.remoteAddress}:${c.remotePort}断开连接`);
});
})
.listen(port, host);
客户端代码:
// client.js
const net = require("net");
const host = "127.0.0.1";
const port = 3001;
const client = new net.Socket();
client.connect(port, host, () => {
console.log(`连接至${host}:${port}`);
// 向服务端发送数据
client.write(`Hello!World!`);
// "data" 事件处理函数
client.on("data", data => {
console.log(`服务器发回: ${data}`);
client.destroy();
});
});
client.on("close", function() {
console.log(`断开连接`);
});
参考
- 《图解 HTTP》