教材知识点总结
Unix/Linux系统编程中的网络编程是指利用网络协议在Unix/Linux系统上进行程序开发,实现网络通信和数据传输。网络编程涉及许多重要概念和技术,包括TCP/IP协议、IP地址、UDP、TCP、套接字编程、Web编程等。
-
TCP/IP协议
TCP/IP协议是互联网所使用的通信协议。它由两个部分组成:传输控制协议(TCP)和因特网协议(IP)。TCP负责数据的可靠传输,而IP则负责数据的路由和分组交换。TCP/IP协议是一个分层协议,包括物理层、数据链路层、网络层、传输层和应用层。 -
IP主机和IP地址
IP主机是指连接到因特网的设备,每个IP主机都有一个唯一的IP地址,用于在网络上标识和定位设备。IP地址分为IPv4和IPv6两种格式,其中IPv4地址由32位二进制数表示,而IPv6地址由128位二进制数表示。 -
IP协议
IP协议是因特网的核心协议,它负责将数据包从源主机传输到目标主机。IP协议定义了数据包的格式和路由规则。 -
IP数据包格式
IP数据包由首部和数据两部分组成。首部包含了版本、首部长度、服务类型、总长度、标识、标志、片偏移、生存时间、协议、首部校验和、源IP地址和目标IP地址等字段。 -
路由器
路由器是连接不同网络的设备,它负责在网络之间转发数据包,实现数据的路由和转发。 -
UDP和TCP
UDP(用户数据报协议)是一种无连接的、不可靠的传输协议,适用于实时性要求高的应用。而TCP(传输控制协议)是一种面向连接的、可靠的传输协议,适用于对数据可靠性要求高的应用。 -
端口编号
端口是为了区分同一主机上不同应用程序而使用的标识符。在TCP/IP协议中,端口号是一个16位的整数,范围从0到65535,其中0到1023是系统保留端口,用于常见的网络服务。 -
网络和主机字节序
网络字节序是指TCP/IP协议规定的大端字节序,而主机字节序是指不同计算机体系结构所使用的字节序。在网络编程中,需要进行网络字节序和主机字节序之间的转换。 -
TCP/IP网络中的数据流
TCP/IP网络中的数据流是指通过TCP协议传输的数据流。TCP协议提供了可靠的、面向连接的数据流传输服务,确保数据的完整性和顺序性。 -
网络编程
网络编程是指利用网络协议在计算机之间进行通信和数据传输的程序开发。它涉及到服务器-客户机计算模型,以及套接字编程等技术。 -
套接字编程
套接字是网络编程中的核心概念,它是实现网络通信的接口。套接字编程涉及套接字地址、套接字API等内容。 -
UDP回显服务器-客户机程序
UDP回显服务器-客户机程序是一个简单的网络应用,客户端发送数据包到服务器,服务器将接收到的数据包原样返回给客户端。 -
TCP回显服务器-客户机程序
TCP回显服务器-客户机程序也是一个简单的网络应用,客户端与服务器建立TCP连接后,发送数据给服务器,服务器将接收到的数据原样返回给客户端。 -
主机名和IP地址
主机名是指计算机在网络上的名称,而IP地址则是计算机在网络上的标识符。主机名和IP地址之间通过DNS进行映射。 -
Web和CGI编程
Web编程涉及HTTP编程模型、Web页面、托管Web页面、为Web页面配置HTTPD、动态Web页面、PHP、CGI编程、配置CGI的HTTPD等内容,用于开发Web应用和网站。
拓展知识点:
- 网络安全:包括加密通信、防火墙、网络攻击和防御等内容。
- Socket编程:深入了解套接字编程,包括TCP和UDP的Socket编程实践。
- HTTP协议:深入了解HTTP协议的请求、响应格式,状态码和头部字段等内容。
- RESTful API:了解基于HTTP协议设计的RESTful API,以及相关的API开发和设计原则。
- WebSocket:深入了解WebSocket协议,实现实时双向通信。
- CGI脚本语言:了解CGI脚本语言的使用和原理,如Perl、Python等。
- 网络性能优化:包括网络传输优化、负载均衡、CDN加速等内容。
苏格拉底挑战
实践
server.txt代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX 256
#define SERVER_HOST "localhost"
#define SERVER_PORT 1234
struct sockaddr_in server_addr, client_addr;
int mysock, csock;
socklen_t len, n;
int server_init() {
printf("================== server init ======================\n");
// create a TCP socket by socket() syscall
printf("1: create a TCP STREAM socket\n");
mysock = socket(AF_INET, SOCK_STREAM, 0);
if (mysock < 0) {
perror("socket");
exit(1);
}
// initialize the server addr structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
printf("2: bind socket to server address\n");
if (bind(mysock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("bind");
fprintf(stderr, "Bind failed. Try using a different port or check permissions.\n");
exit(3);
}
printf("hostname=%s port = %d\n", SERVER_HOST, SERVER_PORT);
printf("3: listen for incoming connections\n");
if (listen(mysock, 5) < 0) {
perror("listen");
exit(4);
}
printf("=================== init done =======================\n");
}
int main() {
char line[MAX];
server_init();
while (1) {
// Try to accept a client request
printf("server: accepting new connection ....\n");
// Try to accept a client connection as descriptor newsock
len = sizeof(client_addr);
csock = accept(mysock, (struct sockaddr*)&client_addr, &len);
if (csock < 0) {
perror("accept");
exit(2);
}
char clientAddrStr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(client_addr.sin_addr), clientAddrStr, INET_ADDRSTRLEN);
printf("server: accepted a client connection from\n");
printf("--------------------------------------------\n");
printf("Client: IP=%s port=%d\n",
clientAddrStr,
ntohs(client_addr.sin_port));
printf("----------------------------------------------\n");
// Processing loop: client_sock <== data ==> client
while (1) {
n = read(csock, line, MAX);
if (n <= 0) {
if (n == 0) {
printf("server: client disconnected\n");
} else {
perror("read");
}
close(csock);
break;
}
// show the line string
printf("server: read n=%d bytes; line=%s\n", n, line);
// echo line to client
if (write(csock, line, n) < 0) {
perror("write");
close(csock);
break;
}
printf("server: wrote n=%d bytes; ECHO=%s\n", n, line);
printf("server: ready for next request\n");
}
}
return 0;
}
client.txt代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX 256
#define SERVER_HOST "localhost"
#define SERVER_PORT 1234
struct sockaddr_in server_addr;
int sock, r;
int client_init() {
printf("======= client init ==========\n");
printf("1: create a TCP socket\n");
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf("socket call failed\n");
exit(1);
}
printf("2: fill server_addr with server's IP and PORT#\n");
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // localhost
server_addr.sin_port = htons(SERVER_PORT); // server port number
printf("3: connecting to server ....\n");
r = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (r < 0) {
printf("connect failed\n");
exit(3);
}
printf("4: connected OK to\n");
printf("-----------\n");
printf("Server hostname=%s PORT=%d\n", SERVER_HOST, SERVER_PORT);
printf("---------------------------------------------------\n");
printf("========= init done==========\n");
}
int main() {
int n;
char line[MAX], ans[MAX];
client_init();
printf("******** processing loop ********\n");
while (1) {
printf("input a line: ");
bzero(line, MAX);
fgets(line, MAX, stdin);
line[strlen(line) - 1] = 0; // kill \n at end
if (line[0] == 0)
exit(0);
n = write(sock, line, MAX);
printf("client: wrote n=%d bytes; line=%s\n", n, line);
// Read a line from sock and show it
n = read(sock, ans, MAX);
printf("client: read n=%d bytes; echo=%s\n", n, ans);
}
}