第十二周学习笔记
第十二周学习笔记
知识点总结
OSI七层模型和TCP/IP五层模型
- OSI七层模型与 TCP/IP 五层模型都是用于描述通信过程的多层协议模型,其中 OSI 七层模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层;而 TCP/IP 五层模型包括物理层、数据链路层、网络层、传输层和应用层。
IP协议
- IP 协议是 TCP/IP 体系结构中的网络层协议,它用于寻址和路由数据包,实现数据包从源到目的的传输。
TCP协议
- TCP 协议是 TCP/IP 体系结构中的传输层协议之一,它提供可靠的数据传输,通过建立连接、排序、确认和重新传输丢失的数据包来保证数据的可靠传输。
UDP协议
- UDP 协议也是 TCP/IP 体系结构中的传输层协议之一,它提供不可靠的数据传输,数据包可能会丢失或乱序,但相比 TCP 协议,它更容易实现、运行更快,并且适用于实时应用程序。
Socket编程
- Socket 编程是指使用套接字(socket)接口进行编程,实现网络通信的方法。套接字包括一个 IP 地址和一个端口号,其中 IP 地址表示网络上的一台主机,端口号表示该主机上的某个网络应用程序。
HTTP协议
- HTTP 协议是应用层协议,它规定了 Web 客户端如何向 Web 服务器请求数据,以及服务器如何响应客户端请求。
网络编程基础
- IP 地址和子网掩码:IP 地址是用于在网络上唯一标识设备的地址,子网掩码用于确定网络中 IP 地址的网络部分和主机部分。
- 端口号:端口号用于标识网络应用程序,常用的有一些固定的端口号,例如 HTTP 的端口号是 80,HTTPS 的端口号是 443。
- DNS 服务:DNS(域名系统)服务是将域名解析成 IP 地址的服务,使得用户可以使用易记的域名来访问网站,而不需要记住对应的 IP 地址。
- ARP 协议:ARP(地址解析协议)用于将 IP 地址解析为对应的物理 MAC 地址,以便实现数据包在网络中的传输。
- TCP/IP 中的重要协议和机制
- HTTP 和 HTTPS:HTTP 是超文本传输协议,用于在 Web 上传输数据。HTTPS 在 HTTP 的基础上增加了加密层,用于保护数据的安全性。
- FTP:FTP(文件传输协议)用于在网络上进行文件传输,包括上传和下载文件。
- SMTP 和 POP3/IMAP:SMTP(简单邮件传输协议)用于发送电子邮件,而 POP3(邮局协议3)和 IMAP(互联网邮件访问协议)用于接收电子邮件。
- NAT:NAT(网络地址转换)是一种将私有 IP 地址映射到公共 IP 地址的技术,用于解决 IP 地址不足的问题。
网络安全和防火墙
- 防火墙:防火墙用于保护网络不受未经授权的访问和攻击,它通过过滤网络流量和监视网络连接来实现。
- VPN:虚拟私有网络(VPN)通过在公共网络上创建加密的隧道,实现远程用户安全访问私有网络资源。
- 加密与身份验证:在网络通信中,加密用于保护数据的安全性,而身份验证用于验证用户的身份,确保只有授权的用户可以获取资源。
- DOS/DDoS 攻击:DOS(拒绝服务)和 DDoS(分布式拒绝服务)攻击是以消耗目标服务器资源为目的的攻击行为,让服务不可用。
苏格拉底挑战
问题及解决方式
1.连接问题:
- 问题描述: 连接无法建立,或者连接时出现超时。
- 解决方式: 检查网络配置,确保目标主机可达。确认端口是否正确打开,防火墙设置是否允许连接。使用工具如ping和telnet来测试网络可达性。
2.数据传输问题:
- 问题描述: 数据传输不稳定,可能出现丢包或乱序。
- 解决方式: 考虑调整TCP窗口大小、使用更稳定的传输协议,或者实现数据确认和重传机制。检查网络拓扑,避免潜在的网络拥塞问题。
3.协议问题:
- 问题描述: 遇到与TCP/IP协议相关的问题,例如不同版本之间的兼容性。
- 解决方式: 确保使用的协议版本是兼容的。检查文档和规范,了解协议的特性和限制。及时更新应用程序以适应新的协议标准。
4.安全性问题:
- 问题描述: 面临网络攻击、数据泄露等安全问题。
- 解决方式: 使用安全套接字层(SSL)或传输层安全性(TLS)来保护数据传输。实施身份验证和授权机制,以确保只有授权用户能够访问敏感信息。定期审查和更新安全策略。
5.性能问题:
- 问题描述: 网络性能不佳,延迟高,吞吐量低。
- 解决方式: 优化代码以提高效率,使用多线程或异步编程来提高并发性。考虑负载均衡和缓存机制,以减轻服务器压力。利用性能监测工具进行定位和优化。
6.网络拓扑问题:
- 问题描述: 系统部署在复杂的网络拓扑中,可能导致路由问题或跨网络通信困难。
- 解决方式: 仔细规划和测试网络拓扑,确保系统组件能够正确地进行路由。使用虚拟专用云(VPC)或其他网络隔离技术来确保不同组件之间的安全和有效通信。
7.并发和同步问题:
- 问题描述: 多个并发连接可能导致同步问题或资源竞争。
- 解决方式: 使用线程同步机制,如互斥锁或信号量,来确保多线程环境中的数据安全。考虑使用异步编程模型,以降低同步问题的发生概率。
8.跨平台兼容性问题:
- 问题描述: 在不同操作系统或硬件平台上运行时出现问题。
- 解决方式: 编写可移植的代码,尽量避免平台相关的调用。进行充分的测试,确保应用程序在目标平台上的稳定性和性能。
实践
服务器端:
客户端:
客户端代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h> // Added inclusion of arpa/inet.h for bzero function
#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");
// 1. Create a TCP socket
printf("1 : create a TCP socket\n");
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket call failed");
exit(1);
}
// 2. Fill server_addr with server's IP and PORT#
printf("2 : fill server_addr with server's IP and PORT#\n");
memset((char*)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Use localhost
server_addr.sin_port = htons(SERVER_PORT);
// 3. Connect to server
printf("3 : connecting to server ...\n");
r = connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (r < 0) {
perror("connect failed");
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); // Zero out line[]
fgets(line, MAX, stdin); // Get a line from stdin
line[strlen(line) - 1] = '\0'; // Kill \n at end
if (line[0] == '\0') // Exit if NULL line
exit(0);
// Send line to server
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);
}
return 0;
}
服务器端代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> // Added inclusion of unistd.h for close function
#define MAX 256
#define SERVER_HOST "localhost"
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 1234 // Defined SERVER_PORT here
struct sockaddr_in server_addr, client_addr;
int mysock, csock;
void server_init() {
printf("================ server init =================\n");
// 1. Create a TCP socket
printf("1 : create a TCP socket\n");
mysock = socket(AF_INET, SOCK_STREAM, 0);
if (mysock < 0) {
perror("socket call failed");
exit(1);
}
// 2. Fill server_addr with server's IP and PORT#
printf("2 : fill server_addr with server's IP and PORT#\n");
memset((char*)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Use localhost
server_addr.sin_port = htons(SERVER_PORT);
// 3. Bind socket to server address
printf("3 : bind socket to server address\n");
int r = bind(mysock, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (r < 0) {
perror("bind failed");
exit(3);
}
printf("hostname = %s port = %d\n", SERVER_HOST, SERVER_PORT);
printf("4 : server is listening ....\n");
// 4. Listen for incoming connections
listen(mysock, 5); // Queue length = 5
printf("================== init done ===============\n");
}
int main() {
int n;
char line[MAX];
server_init();
while (1) {
// Try to accept a client request
printf("server: accepting new connection ....\n");
socklen_t len = sizeof(client_addr);
csock = accept(mysock, (struct sockaddr*)&client_addr, &len);
if (csock < 0) {
perror("server: accept error");
exit(1);
}
printf("server: accepted a client connection from\n");
printf("Client: IP=%s port=%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// Processing loop: client_sock <== data ==> client
while (1) {
n = recv(csock, line, MAX, 0);
if (n <= 0) {
printf("server: client closed the connection, server loops\n");
close(csock);
break;
}
// Show the received line string
printf("server: received n=%d bytes; line=%s\n", n, line);
// Echo line to client
n = send(csock, line, n, 0);
printf("server: sent n=%d bytes; echo=%s\n", n, line);
}
}
return 0;
}