✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
1. 本质与内核
1.1 网络编程定义
网络编程是指使用编程语言来实现计算机之间通过网络进行通信和数据交换的过程。
通过网络编程,可以让不同的计算机程序在网络环境中相互协作、共享信息和资源。它涉及到对网络协议(如 TCP/IP 等)的理解和运用,以及使用编程语言提供的相关接口和库来实现诸如建立连接、发送和接收数据、处理错误、实现并发等功能。
1.2 常见的网络编程应用
- 客户端 - 服务器应用:如 Web 服务器和浏览器之间的交互,邮件客户端和邮件服务器之间的通信。
- 分布式系统:多个计算机协同工作完成一个共同的任务,通过网络进行通信和协调。
- 即时通讯应用:如聊天软件。
- 文件共享和下载应用。
- 网络游戏:多个玩家通过网络连接进行互动。
1.3 Scoket 套接字
- 基本概念:Socket 是通信的基石,是支持 TCP/IP 协议的网络通信的基本操作单元,在网络通信过程中端点的一种抽象表示。网络中使用 Socket 传输数据是一种特殊的网络 I/O。
- 工作模式:打开(open)-> 读写(write/read)-> 关闭(close)
- 五种信息:socket 包括了数据传输必须的五元组,分别为源 IP、源端口、目的 IP、目的端口和协议号
- 通信机制:基于流(stream)或者基于数据报(datagram)
- python 中使用:
python
from socket import *
scoket(...)
2. UDP 实现
2.1 UDP 实现原理
- 服务端和客户端初始化 socket,得到文件描述符;
- 服务端调用 bind,将 socket 绑定在指定的 IP 地址和端口;
- 客户端调用 sendto 写入数据;服务端调用 recvfrom 读取数据;
- 客户端断开连接时,会调用 close,那么服务端 recvfrom 读取数据的时候,就会读取到了 EOF,待处理完数据后,服务端调用 close,表示连接关闭。
2.2 UDP 服务端
python
import datetime
from socket import *
# 创建 UDP 套接字
server_socket = socket(AF_INET, SOCK_DGRAM)
# 绑定服务器的 IP 和端口
server_address = ('127.0.0.1', 5000)
server_socket.bind(server_address)
print("开启 UDP 服务,等待接收数据...")
while True:
# 接收客户端数据
data, client_address = server_socket.recvfrom(1024)
print(f"在{datetime.datetime.now()},从 {client_address} 接收到: {data.decode('gbk')}")
if data.decode('gbk') == "exit":
print("聊天到此结束")
break
# 发送响应
response = "已收到你的消息!"
server_socket.sendto(response.encode('gbk'), client_address)
2.3 UDP 客户端
python
from socket import *
# 创建 UDP 套接字
client_socket = socket(AF_INET, SOCK_DGRAM)
while True:
data = input("请输入内容:")
server_address = ('127.0.0.1', 5000) # 服务器的 IP 和端口
client_socket.sendto(data.encode('gbk'), server_address)
if data == "exit":
print("聊天结束...")
break
data, server = client_socket.recvfrom(1024) # 接收服务器的响应
print(f"从服务器接收到: {data.decode('gbk')}")
# 关闭套接字
client_socket.close()
2.4 运行结果
- 先运行服务端代码
- 再运行客户端代码,并发送内容
- 回到服务端,可以发现接收到了客户端发送的信息
- 在客户端输入 exit 退出程序
- 服务端收到客户端退出指令,同样也退出程序
3. TCP 实现
3.1 TCP 实现原理
下面主要是讲 TCP 的实现原理,在 Python 具体实现的时候,将下面的 write 和 read 函数分别替换成 send 和 recv 函数即可。
- 服务端和客户端初始化 socket,得到文件描述符;
- 服务端调用 bind,将 socket 绑定在指定的 IP 地址和端口;
- 服务端调用 listen,进行监听;
- 服务端调用 accept,等待客户端连接;
- 客户端调用 connect,向服务端的地址和端口发起连接请求;
- 服务端 accept 返回用于传输的 socket 的文件描述符;
- 客户端调用 write 写入数据;服务端调用 read 读取数据;
- 客户端断开连接时,会调用 close,那么服务端 read 读取数据的时候,就会读取到了 EOF,待处理完数据后,服务端调用 close,表示连接关闭。
这里需要注意的是,服务端调用 accept 时,连接成功了会返回一个已完成连接的 socket,后续用来传输数据。
所以,监听的 socket 和真正用来传送数据的 socket,是「两个」 socket,一个叫作监听 socket,一个叫作已完成连接 socket。
成功连接建立之后,双方开始通过 read 和 write 函数来读写数据,就像往一个文件流里面写东西一样。
3.2 TCP 服务端
python
from socket import *
# 创建一个 TCP 套接字
server_socket = socket(AF_INET, SOCK_STREAM)
# 绑定服务器的 IP 和端口
server_address = ('127.0.0.1', 5001)
server_socket.bind(server_address)
# 开始监听连接,允许最多 5 个未处理的连接请求在队列中等待
server_socket.listen(5)
print("TCP 服务器正在监听...")
while True:
# 等待客户端连接
client_socket, client_address = server_socket.accept()
print(f"与客户端 {client_address} 建立连接")
# 接收客户端发送的数据
data = client_socket.recv(1024)
print(f"从客户端收到: {data.decode('utf-8')}")
# 向客户端发送响应
response = "已收到你的消息!"
client_socket.send(response.encode('utf-8'))
# 关闭与客户端的连接
client_socket.close()
3.3 UDP 客户端
python
import socket
# 创建一个 TCP 套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 服务器的 IP 和端口
server_address = ('127.0.0.1', 5001) # 请确保与服务器端的端口一致
# 连接到服务器
client_socket.connect(server_address)
# 要发送的数据
message = "Hello, TCP Server!"
client_socket.send(message.encode('utf-8'))
# 接收服务器的响应
data = client_socket.recv(1024)
print(f"从服务器接收到: {data.decode('utf-8')}")
# 关闭套接字
client_socket.close()
3.4 运行结果
- 先启动服务端,然后再启动两个客户端并向服务端发送信息
- 在服务端就可以接收到客户端发送来的信息