socket
SKILL.md
仓颉语言 Socket 编程
1. 网络概述
1.1 分层
- 传输层(
std.net包):TCP(TcpSocket)、UDP(UdpSocket)、Unix Domain Socket - 安全层(
stdx.net.tls包):TLS 1.2/1.3 加密传输
1.2 关键规则
- 网络操作在仓颉线程级别是阻塞的,但不阻塞 OS 线程(仓颉线程让出)
- 所有 Socket 均实现
Resource,可使用try-with-resource自动清理资源
1.3 地址类型
SocketAddress(抽象基类)→IPSocketAddress(IP+端口)、UnixSocketAddress(文件路径)IPAddress(抽象)→IPv4Address、IPv6AddressIPAddress.parse(str)/IPAddress.tryParse(str)— 解析地址IPAddress.resolve(hostname)— DNS 解析- 常用判断:
isLoopback()、isPrivate()、isMulticast()
2. TCP 编程
2.1 服务端
TcpServerSocket(bindAt: port)→bind()→accept()(阻塞等待连接)accept(timeout)— 带超时的接受连接- 属性:
backlogSize、reuseAddress、reusePort、receiveBufferSize、sendBufferSize
2.2 客户端
TcpSocket(host, port)→connect()→read()/write()connect(timeout)— 带超时连接- 超时配置:
readTimeout、writeTimeout(Duration类型) - TCP 调优:
noDelay(TCP_NODELAY)、keepAlive(SocketKeepAliveConfig)、linger
2.3 完整示例
import std.net.*
import std.sync.*
let SERVER_PORT: UInt16 = 33333
let ready = SyncCounter(1)
func runServer() {
try (server = TcpServerSocket(bindAt: SERVER_PORT)) {
server.bind()
ready.dec()
try (client = server.accept()) {
let buf = Array<Byte>(10, repeat: 0)
let n = client.read(buf)
println("Server read ${n} bytes: ${buf}")
}
}
}
main(): Int64 {
let fut = spawn { runServer() }
ready.waitUntilZero()
try (socket = TcpSocket("127.0.0.1", SERVER_PORT)) {
socket.connect()
socket.write([1, 2, 3])
}
fut.get()
return 0
}
3. UDP 编程
UdpSocket(bindAt: port)→bind()- 发送:
sendTo(IPSocketAddress, data)或连接后send(data) - 接收:
receiveFrom(buffer)→(SocketAddress, count),或连接后receive(buffer) - 可选
connect(addr)锁定远端地址(之后可用send/receive) disconnect()— 解除连接- 限制:单包最大 64KB
- 超时:
receiveTimeout、sendTimeout
import std.net.*
import std.sync.*
import std.time.*
let SERVER_PORT: UInt16 = 33333
let barrier = Barrier(2)
func runUdpServer() {
try (server = UdpSocket(bindAt: SERVER_PORT)) {
server.bind()
barrier.wait()
let buf = Array<Byte>(3, repeat: 0)
let (addr, n) = server.receiveFrom(buf)
println("Received ${n} bytes: ${buf}")
}
}
main(): Int64 {
let fut = spawn { runUdpServer() }
barrier.wait()
try (sock = UdpSocket(bindAt: 0)) {
sock.sendTimeout = Duration.second * 2
sock.bind()
sock.sendTo(IPSocketAddress("127.0.0.1", SERVER_PORT), [1, 2, 3])
}
fut.get()
return 0
}
4. Socket 选项
4.1 通用选项
| 属性 | 说明 |
|---|---|
readTimeout / writeTimeout |
读写超时(Duration 类型),超时抛 SocketTimeoutException |
reuseAddress / reusePort |
地址/端口复用 |
receiveBufferSize / sendBufferSize |
收发缓冲区大小 |
4.2 TCP 专有
| 属性 | 说明 |
|---|---|
noDelay |
禁用 Nagle 算法(降低延迟) |
keepAlive |
SocketKeepAliveConfig(interval, count) — TCP 保活配置 |
linger |
SO_LINGER — 关闭时等待数据发送完毕 |
4.3 底层选项访问
getSocketOptionIntNative(level, name)/setSocketOptionIntNative(level, name, value)OptionLevel:TCP、SOCKET等SocketOptions:TCP_NODELAY、SO_KEEPALIVE、SO_REUSEADDR等常量
import std.net.*
import std.time.*
main() {
try (sock = TcpSocket("127.0.0.1", 80)) {
sock.readTimeout = Duration.second
sock.noDelay = true
sock.linger = Duration.minute
sock.keepAlive = SocketKeepAliveConfig(
interval: Duration.second * 7,
count: 15
)
}
}
5. Unix Domain Socket
- 基于文件路径的进程间通信(IPC),不经过网络栈
- 路径最大 108 字节
- 不支持 Windows
- 流式:
UnixServerSocket(bindAt: path)+UnixSocket(path) - 数据报式:
UnixDatagramSocket(bindAt: path) - 使用后需手动
remove(path)清理 socket 文件
import std.net.*
import std.sync.*
import std.fs.*
let SOCK_PATH = "/tmp/cj_demo.sock"
let barrier = Barrier(2)
func runServer() {
try (server = UnixServerSocket(bindAt: SOCK_PATH)) {
server.bind()
barrier.wait()
try (client = server.accept()) {
client.write("hello".toArray())
}
}
}
main(): Int64 {
let fut = spawn { runServer() }
barrier.wait()
try (sock = UnixSocket(SOCK_PATH)) {
sock.connect()
let buf = Array<Byte>(5, repeat: 0)
sock.read(buf)
println(String.fromUtf8(buf)) // "hello"
}
fut.get()
remove(SOCK_PATH)
return 0
}
6. 异常类型
| 异常 | 说明 |
|---|---|
SocketException |
通用 Socket 错误 |
SocketTimeoutException |
Socket 操作超时 |
7. 关键规则速查
- 所有 Socket/Server 使用
try-with-resource自动清理 - TCP 服务端模式:
TcpServerSocket→bind()→ 循环accept() - UDP 单包最大 64KB
- TLS 需要先建立 TCP 连接,再在其上创建
TlsSocket并handshake()
Weekly Installs
3
Repository
kong-baiming/cangjie-devFirst Seen
4 days ago
Security Audits
Installed on
opencode2
gemini-cli2
claude-code2
github-copilot2
codex2
kimi-cli2