*NIX & Hacking —— 第9期

做一本我感兴趣的杂志,就这么简单!

Assembler

Assembler relaxation

GDB

GDB dashboard

Go

Best practices for a new Go developer
On Go, Portability, and System Interfaces

Kernel

A Toure of Bootloading
GRUB 2 bootloader – Full tutorial
How I ended up writing new real-time kernel
Kernel bypass
Linux Kernel Crash Book

Network

TCP in 30 instructions

RMS

Interviews: RMS Answers Your Questions

Rust

Why Rust?

Tracing

Dynamic Tracing with DTrace & SystemTap

*NIX & Hacking —— 第8期

做一本我感兴趣的杂志,就这么简单!

C

C Programming Substance Guidelines
The International Obfuscated C Code Contest

Docker

A Beginners Guide to Docker and Containers

Gcc

About GCC printf optimization

Git

Git Cheat Sheet
Git Tips

Hardware

Interfacing the Serial / RS232 Port

Kernel

Porting Linux to a new processor architecture, part 1: The basics
The newbie’s guide to hacking the Linux kernel
Writing a Linux Kernel Module — Part 1: Introduction

Lua

Embedding LuaJIT in 30 minutes (or so)

Network

Mobile TCP optimization – lessons learned in production

Unix

The First Port Of Unix

*NIX & Hacking —— 第5期

做一本我感兴趣的杂志,就这么简单!

C

Integer Overflow

Golang

breaking out of a select statement when all channels are closed

Kernel

Feature: High Memory In The Linux Kernel
What’s Next for Containers? User Namespaces

Network

Recent advancements in Linux TCP congestion control
SO_REUSEPORT – Scaling Techniques for Servers with High Connection Rates

Rust

Rust in Detail: Writing Scalable Chat Service from Scratch

Shell

fish shell

Easter egg

Announcing the first Art of Computer Programming eBooks
Goodbye Moto
Intel DDIO, LLC cache, buffer alignment, prefetching, shared locks and packet rates
Jokes
List of freely available Programming Books
Mandelbrot Set with SIMD Intrinsics

*NIX & Hacking —— 第4期

做一本我感兴趣的杂志,就这么简单!

Compiler

Notes on How Parsers and Compilers Work

Golang

GopherCon 2015 live blog
Testing in Go
Why does adding parentheses in if condition results in compile error?

Kernel

Choosing a Linux Tracer (2015)
Debugging by printing
Learning Kernel Programming
LTTng Packages now Available for Red Hat Enterprise Linux 7

Lua

Cloning a function in Lua

Network

Unit testing a TCP stack

Unix

Where the Unix philosophy breaks down

Easter egg

Starting from scratch: How do you build a world-class research lab?
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

客户端—服务器通信模型浅析

客户端—服务器(Client-Server)是我们平时最常见的通信方式,本文就对这一通信模型做个简单介绍。

(一)TCP连接方式:短连接方式?长连接方式

目前,多数的客户端—服务器选择TCP做为传输层协议,也有少数选择UDP或SCTP协议的。而TCP连接有两种工作方式:短连接方式(Short-Live Connection)和长连接方式(Long-Live Connection)。

(1)短连接方式:

当客户端有请求时,会建立一个TCP连接,接收到服务器响应后,就断开连接。下次有请求时,再建立连接,收到响应后,再断开。如此循环。这种方式主要有两个缺点:

a)建立TCP连接需要3次“握手”,拆除TCP连接需要4次“挥手”,这就需要7个数据包。如果请求和响应各占1个数据包,那么一次短连接的交互过程,有效的传输仅占2/9,这个利用率太低了。

b)主动断开TCP连接的一端,TCP状态机会进入TIME_WAIT状态。如果频繁地使用短连接方式,就有可能使客户端的机器产生大量的处于TIME_WAIT状态TCP连接(UNIX系统下,可以使用netstat命令来查看)。

(2)长连接方式:

客户端和服务器建立TCP连接后,会一直使用这条连接进行数据交互,直到没有数据传输或异常断开。在空闲期间,通常会使用心跳数据包(Keep-Alive)保持链路不断开。目前长连接方式应用范围比较广泛。

(二)消息交互方式

(1)一个请求,一个响应

这种消息交互方式如下图所示:


当客户端发出请求后,程序就阻塞在那里,直到收到服务器的响应或者超时。很多对数据库的访问方式都是这样的(像Redis的C程序客户端hiredis)。

(2)多个请求,多个响应

这种消息交互方式如下图所示:


这种方式下,客户端一次可以发送多个请求,而每个请求会带有一个消息标示(Message ID)。这样在客户端收到响应后,就可以根据响应的消息标示,和请求对应起来。