Fundamentals 28 min read

Fundamentals of Computer Networks, Network Programming, and Asynchronous I/O

This article provides a comprehensive overview of computer networking fundamentals, including C/S and B/S architectures, OSI layers, TCP/UDP protocols, socket programming, code examples, and the concepts of synchronous, asynchronous, blocking, and non‑blocking I/O in Linux.

Deepin Linux
Deepin Linux
Deepin Linux
Fundamentals of Computer Networks, Network Programming, and Asynchronous I/O

1. Software Development Architecture

Before writing a project, follow code‑level conventions such as execution steps and processes.

C/S Architecture

c:client 客户端
s:server 服务端
计算机或手机下载的各类app本质上就是客户端
优势是:下载对应的客户端,可以在客户端体验高度定制服务
劣势是:使用必须下载!!

B/S Architecture

b:broswer 浏览器
s:server 服务器
通过浏览器来充当各个服务器的客户端,用于想要体验服务又不用下载客户端
劣势是:网页的各种功能花里胡哨,观看效果不佳

Architecture Development Trend

1.统一接口原则(可以通过一个接口去往其他程序)
2.cs和bs交叉使用,避免各自的劣势

2. Network Programming

Writing code based on a network enables remote data interaction.

2.1 Origin of Network Programming

目的:为了解决计算机之间远程数据交互
网络编程的意义:学习完就可以编写cs架构
网络编程的起源:任何先进的技术一般都来源于军事
网络编程的要求:计算机之间想要实现远程数据交互,首要条件就是要有物理连接介质

2.2 Elements of Network Communication

信双方的地址:
ip
端口号
192.168.XXX.XXX :端口
规则:网络通信协议

OSI Seven‑Layer Model

规定了计算机涉及到远程交互的时候必须要经过相同的流程
数据发送出去的时候 是从上往下走
数据接收回来的时候 是从下往上走

Application Layer

主要是程序员自己编写代码的地方,有什么协议和规范取决于程序员自己
常见协议有:HTTP, HTTPS 等等

Port Protocol

端口协议:规定了一台计算机上的每一个正在运行的app都必须要有一个端口号
端口号范围:0-65535
0-1024:系统内部使用
1024-8000:常见软件已使用
8000+:自定义服务
IP:标识全世界任意一台接入互联网的计算机
PORT:标识一台计算机上的某个app
URL 本质就是 IP+PORT

TCP Protocol

Three‑Way Handshake (Connection Establishment)

1.三次握手 建立双向通道
第一次握手:客户端向服务端发送请求
第二次握手:服务端确认并发送可以建立连接的信号(此时单向)
第三次握手:客户端确认,双方可以互相发送数据

Four‑Way Handshake (Connection Termination)

第一次挥手:客户端请求断开
第二次挥手:服务端确认,仍可向客户端发送数据
第三次挥手:服务端请求断开
第四次挥手:客户端确认,双方不再通信

UDP Protocol

服务端代码
import socket

res = socket.socket(type=socket.SOCK_DGRAM)
res.bind(('127.0.0.1',8080))

msg,address = res.recvfrom(1024)
print('msg>>>%s'%msg.decode('utf8'))
print('address>>>>:',address)
res.sendto('服务端'.encode('utf8'),address)

客户端代码
import socket

c = socket.socket(type=socket.SOCK_DGRAM)
server_address = ('127.0.0.1',8080)
c.sendto('客户端'.encode('utf8'),server_address)
msg,address = c.recvfrom(1024)
print('msg>>>"%s'%msg.decode('utf8'))
print('address>>>>>:',address)

2.3 Network Layer

ip协议:规定任何接入互联网的计算机都必须有IP地址
IPV4:点分十进制,范围0.0.0.0‑255.255.255.255
IPV6:128位,可为地球上每粒沙子分配唯一地址

InetAddress Class (Java)

package com.taodou;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestInetAddress {
    public static void main(String[] args) {
        try {
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            InetAddress inetAddress2 = InetAddress.getByName("LocalHost");
            InetAddress inetAddress3 = InetAddress.getLocalHost();
            System.out.println(inetAddress1);
            System.out.println(inetAddress2);
            System.out.println(inetAddress3);
            System.out.println("------------------------------------");
            InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress4);
            System.out.println(inetAddress4.getCanonicalHostName());
            System.out.println(inetAddress4.getHostAddress());
            System.out.println(inetAddress4.getHostName());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

Port Numbers

不同的进程有不同的端口号
端口号 0~65536,分为公有端口(0‑1023)、注册端口(1024‑49151)和私有端口(49152‑65535)
常见例子:HTTP 80、HTTPS 443、FTP 21、Tomcat 8080、MySQL 3306

3. Socket (套接字)

Sockets act as an interface between the software layer and the application layer; without them, developers would need to manually handle each layer.

3.1 History

1.最初套接字用于同一台主机上进程间通信(IPC),有两类:AF_UNIX(文件型)和 AF_INET(网络型)

Socket Example

# 服务端
import socket
server = socket.socket()
server.bind(('192.168.1.169',8080))
server.listen(5)
sock,address = server.accept()
print(sock,address)
sock.send(b'hello')
res=sock.recv(1024)
print(res)
sock.close()
server.close()

# 客户端
import socket
client = socket.socket()
client.connect(('192.168.1.169', 8080))
res = client.recv(1024)
print(res)
client.send(b'hei')
client.close()

3.2 Half‑Connection Pool

server.listen(5)  # 参数表示最多等待的客户端数量,避免无效等待

3.3 Sticky‑Packet Problem

Cause

1.TCP 流式特性会把小数据块合并
2.recv 不知道要接收的数据量

Code Demonstration

# 服务端
import socket
s = socket.socket()
s.bind(('192.168.1.169',8080))
s.listen(5)
sock,address =s.accept()
sock.send(b'hello')
sock.send(b'hai')
sock.send(b'hahaha')

# 客户端
import socket
res = socket.socket()
res.connect(('192.168.1.169', 8080))
print(res.recv(1024).decode('utf8'))
print(res.recv(1024).decode('utf8'))
print(res.recv(1024).decode('utf8'))
# 输出出现粘包:hello\nhaihahaha

3.4 struct Module

struct can pack variable‑length data into a fixed‑length header, which can later be unpacked to retrieve the original length.

Solution to Sticky‑Packet

# 服务端
1.先将真实数据长度打包成固定 4 字节的报头
2.发送报头
3.发送真实数据

# 客户端
1.先接收 4 字节报头
2.解析出真实长度
3.根据长度接收真实数据

4. Why Asynchronous I/O?

Asynchronous I/O does not block the program; the caller is notified via signals or callbacks after the kernel finishes the operation.

4.1 Signal‑Driven I/O

Enable non‑blocking I/O with O_NONBLOCK , then enable asynchronous I/O with O_ASYNC . Set the owning process with fcntl(fd, F_SETOWN, getpid()) and register a handler for SIGIO (or a real‑time signal).

int flag;
flag = fcntl(fd,F_GETFL);
flag |= O_ASYNC;
fcntl(fd,F_SETFL,flag);

Register the handler:

static void sigio_handler(int sig) {
    if (sig != SIGIO) return;
    // read data …
}
signal(SIGIO, sigio_handler);

4.2 Linux Native AIO

Native AIO uses the libaio library. Install with sudo apt install libaio-dev . Typical workflow: io_setup → io_submit → io_getevents .

#define _GNU_SOURCE
#include
...
int fd = open("./aio.txt", O_CREAT|O_RDWR|O_DIRECT, 0644);
io_setup(10, &context);
io_prep_pwrite(&io[0], fd, wbuf, wbuflen, 0);
io_submit(context, 1, &p[0]);
io_getevents(context, 1, 1, e, &timeout);

4.3 Sync vs Async, Blocking vs Non‑Blocking

An I/O operation consists of two steps: issuing the request and performing the actual I/O. Synchronous I/O blocks on the second step; asynchronous I/O does not. Blocking vs non‑blocking refers to whether the first step itself blocks.

Four models:

Synchronous Blocking (traditional I/O)

Synchronous Non‑Blocking (polling, e.g., Java NIO)

Asynchronous Blocking (kernel notifies via signals)

Asynchronous Non‑Blocking (e.g., Linux AIO with eventfd/epoll)

Diagrams illustrating each model are included in the original article.

TCPnetwork protocolsSocket ProgrammingUDPasynchronous I/OOSI modelComputer Networks
Deepin Linux
Written by

Deepin Linux

Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.