Socket(套接字)是计算机网络中的一个抽象层,它允许应用程序通过网络进行通信。套接字用于跨网络的不同主机上的应用程序之间的数据交换。在互联网中,套接字通常基于 TCP(传输控制协议)或 UDP(用户数据报协议)来实现数据的可靠传输或快速传输。应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。它是一组用于网络通信的API,包括了一系列的函数和数据结构,它提供了一种标准的网络编程接口,使得应用程序可以在网络中进行数据传输。Socket本身并不是一个具体的实现,而是一个抽象的概念。不同的操作系统和编程语言可以通过不同的方式来实现Socket API。
通信协议可分为TCP、UDP。 TCP(Transmission Control Protocol传输控制协议)是一种面向连接的,可靠的,基于字节流的传输通信协议。UDP(User Data Protocol,用户数据报协议)是无连接的,即发送数据之前不需要建立连接,类似于发短信,我只管发,能不能接收到跟我关系不大。
Socket 基于UDP实现客户端与服务端通信
UDP 服务端 :
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8888))
print('UDP服务端已经启动了')
while True:
data,client = server.recvfrom(1024)
print('接收到客户端发来的消息:', data.decode(('utf-8')))
server.sendto('我是服务端'.encode('utf-8'),client)
UDP客户端 :
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client.sendto('我是客户端'.encode('utf-8'),('127.0.0.1',8888))
data,server = client.recvfrom(1024)
print(data.decode('utf-8'))
client.close()
启动通信后,服务端和客户端各自收到信息
Socket 基于TCP实现客户端与服务端通信
TCP 服务端 :
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8db77a519ad74f7b9d7bc5ab75fd0512.png)
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 8888))
server.listen(5)
print("服务端已经启动,等待客户端连接======》")
client, address = server.accept()
print("已经建立连接")
while True:
recv = client.recv(1024)
msg = recv.decode("utf-8")
if msg == "close":
print("服务端关闭=======》")
server.close()
break
print("客户端发送的内容:", msg)
print("请输入回复内容:")
client.send(input().encode("utf-8"))
TCP 客户端 :
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8888))
while True:
print("请输入内容:")
send_data = input()
client.send(send_data.encode("utf-8"))
if send_data == "close":
client.close()
print("关闭连接")
break
data = client.recv(1024).decode("utf-8")
print("接收到服务端响应:", data)
启动通信后,服务端和客户端各自收到信息
Socket 发送数据请求,对API 返回服务器响应数据校检
服务器返回响应的结果和网页响应的结果一样,但通过 Socket 发送请求数据,在 Python 3.7 开始被淘汰,这方法不太稳定。还是建议用 requests module 实现 API 测试。
import socket
import ssl
socket = ssl.wrap_socket(socket.socket())
socket.connect(('cache.video.iqiyi.com',443))
socket.send(b'GET /dash?tvid=4597713829135000&bid=600&vid=&src=01010031010000000000&vt=0&rs=1&uid=&ori=pcw&ps=0&k_uid=f1537f4b540b36ae037319d96057892e&pt=0&d=0&s=&lid=0&cf=0&ct=0&authKey=b29751afde35506a135a284bb3948662&k_tag=1&dfp=a156c252dc52ca492495717f29b16891db84c5deb50ec59a40abd7c7e43ab41d2b&locale=zh_cn&pck=&up=&sr=1&apdl=1&qd_v=a1&tm=1730953737580&ppt=0&k_ft1=704237197590532&k_ft4=1161221785001988&k_ft5=137573171201&k_ft7=4&fr_1020=120_120_120_120_120_120&fr_800=120_120_120_120_120_120&fr_600=120_120_120_120_120_120&fr_500=120_120_120_120_120_120&fr_300=120_120_120_120_120_120&bop=%7B%22version%22%3A%2210.0%22%2C%22dfp%22%3A%22a156c252dc52ca492495717f29b16891db84c5deb50ec59a40abd7c7e43ab41d2b%22%2C%22b_ft1%22%3A24%7D&ut=0&vf=cce71ada467c905cd37b0f9b20a5bccd\r\nHTTP/1.1\r\nAccept: application/json, text/javascript\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nConnection: keep-alive\r\nCookie: PD005=rtlyy1rxbollcqa6ts2x30n50emiwnom; QC005=f1537f4b540b36ae037319d96057892e; T00404=ef9fe59fc32ae4ea19888e7de5001342; QC234=c33ce7207a12eb1d51b4909f7fe5da68; QC006=a8e0e4ab15b3349a39989270647b135c; QP0030=1; QC235=3a17828e79024c448c1f320cabc11e3f; QP0037=0; QP0035=4; QP0034=%7B%22v%22%3A17%2C%22dp%22%3A1%2C%22dm%22%3A%7B%22wv%22%3A1%7D%2C%22m%22%3A%7B%22wm-vp9%22%3A1%2C%22wm-av1%22%3A1%7D%2C%22hvc%22%3Afalse%7D; QC173=0; QC191=; QC008=1729398080.1729398080.1730951272.2; nu=0; TQC030=1; QC010=190827388; curDeviceState=width%3D304%3BconduitId%3D%3Bscale%3D100%3Bbrightness%3Ddark%3BisLowPerformPC%3D0%3Bos%3Dbrowser%3Bosv%3D10.0.19044; QC007=DIRECT; QP0027=4; QP0036=2024117%7C16.414; QP007=116340; __dfp=a156c252dc52ca492495717f29b16891db84c5deb50ec59a40abd7c7e43ab41d2b@1732208864278@1730912865278; IMS=IggQABj_x7O5BiomCiAyM2YyODcxMTVmYzA0ZmI2YWIxMjMyMmM2NGY0NDNjYhAAIgByJAogMjNmMjg3MTE1ZmMwNGZiNmFiMTIzMjJjNjRmNDQzY2IQAIIBBCICEBWKASQKIgogMjNmMjg3MTE1ZmMwNGZiNmFiMTIzMjJjNjRmNDQzY2I\r\nHost: cache.video.iqiyi.com\r\nOrigin: https://www.iqiyi.com\r\nReferer: https://www.iqiyi.com/\r\nSec-Fetch-Dest: empty\r\nSec-Fetch-Mode: cors\r\nSec-Fetch-Site: same-site\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36\r\nsec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: "Windows"')
buffer_lst = []
while True:
data = socket.recv(1024)
if data:
buffer_lst.append(data)
else:
break
data = b''.join(buffer_lst)
socket.close()
print(data.decode('utf-8'))
WebSocket 是一种网络通信协议,它实现了客户端与服务器之间的全双工通信,是 HTML5 一种新的协议。与传统的 HTTP 协议不同,WebSocket 允许服务器主动向客户端发送消息,这对于实时应用(如在线聊天、游戏等)来说非常重要。
WebSocket 的工作原理(连接过程 ---- 握手过程) 如下:
- 浏览器、服务器建立TCP连接,三次握手。这是通信的基础,传输控制层,若 失败后续都不执行。
- TCP连接成功后,浏览器通过HTTP协议向服务器传送WebSocket支持的版本号等信息。(开始前的HTTP握手)
- 服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据。
- 当收到了连接成功的消息后,通过TCP通道进行传输通信。
WebSocket 相比 HTTP 协议有以下优点:
- 实时性:服务器可以主动向客户端发送消息,实现实时通信。
- 双向通信:客户端和服务器之间可以同时发送和接收数据。
- 性能:WebSocket 连接建立后,数据传输效率更高,减少了 HTTP 请求的次数。
- 兼容性:WebSocket 协议在大多数浏览器中得到了支持,无需额外插件。
实现 WebSocket 通信通常需要使用 JavaScript 和后端语言(例如 Node.js、Python、Java 等)。一个简单的 WebSocket 实现示例:
客户端 - JavaScript
const socket = new WebSocket('ws://localhost:8888');
socket.onopen = function(event) {
console.log('连接成功');
};
socket.onmessage = function(event) {
console.log('收到消息:', event.data);
};
socket.onclose = function(event) {
console.log('连接关闭');
};
socket.onerror = function(error) {
console.log('连接出错:', error);
};
function sendMessage(msg) {
socket.send(msg);
}
服务器端 - Node.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function(socket) {
console.log('新连接');
socket.on('message', function(msg) {
console.log('收到消息:', msg);
});
function sendMessageToClient(msg) {
socket.send(msg);
}
setInterval(() => {
sendMessageToClient('服务器消息');
}, 1000);
});
再写一个简单的在线聊天示例 :
客户端 - JavaScript
const socket = new WebSocket('ws://localhost:8888');
socket.onopen = function(event) {
console.log('连接成功');
};
socket.onmessage = function(event) {
const msg = document.createElement('div');
msg.textContent = '服务器:' + event.data;
document.body.appendChild(msg);
};
socket.onclose = function(event) {
console.log('连接关闭');
};
socket.onerror = function(error) {
console.log('连接出错:', error);
};
function sendMessage(msg) {
socket.send(msg);
}
const input = document.createElement('input');
input.type = 'text';
input.placeholder = '输入消息';
input.addEventListener('input', function(event) {
sendMessage(event.target.value);
});
document.body.appendChild(input);
服务器端 - Node.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8888});
wss.on('connection', function(socket) {
console.log('新连接');
socket.on('message', function(msg) {
console.log('收到消息:', msg);
wss.clients.forEach(function each(client) {
if (client !== socket && client.readyState === WebSocket.OPEN) {
client.send(msg);
}
});
});
function sendMessageToClient(msg) {
socket.send(msg);
}
setInterval(() => {
sendMessageToClient('服务器消息');
}, 1000);
});