1. 计算机网络中的 Socket 是什么?

想象一下电话系统:

  • 电话插座 (Socket): 是墙上的一个物理接口,它本身不是通话,但它是建立通话连接的端点。你需要把电话线插进插座才能打电话。
  • 通话 (Connection): 是两台电话机之间建立的实际通信通道。

在计算机网络中,Socket (套接字) 的概念非常类似:

  1. 通信端点: Socket 本质上是网络通信的端点。它是网络上两个程序(进程)之间进行双向数据交换的连接点
  2. 抽象概念: 它是一个抽象概念,由操作系统提供,用于表示一个网络连接的一端。
  3. 标识连接: 一个 Socket 通常由以下要素唯一标识(尤其是在 TCP/IP 协议栈中):
    • IP 地址: 标识网络上的主机(计算机)。
    • 端口号: 标识主机上的特定应用程序或服务(例如,Web 服务器通常用端口 80,SSH 用 22)。
    • 协议: 使用的传输层协议,主要是 TCP (可靠的、面向连接的) 或 UDP (不可靠的、面向数据报的)。
  4. 操作系统接口: 在操作系统层面,Socket 是提供给应用程序进行网络通信的编程接口 (API)。应用程序通过创建 Socket、绑定地址、监听连接、建立连接、发送/接收数据、关闭连接等操作来使用网络。

简单总结: Socket 是网络通信的基石。它代表了网络上一个特定程序(IP地址 + 端口号)使用特定协议(TCP/UDP)进行通信的“门户”或“连接点”。两台主机上的两个 Socket 连接起来,就形成了一条通信通道。

2. 编程语言中的 Socket 编程是什么?

Socket 编程指的是利用操作系统提供的 Socket API(或语言对其的封装)来编写网络应用程序的技术。

  • 核心任务: 使运行在不同计算机(或同一台计算机不同进程)上的程序能够通过网络交换数据。
  • 实现方式:
    • 编程语言通常提供标准库或模块(如 Python 的 socket, Java 的 java.net, C 的 sys/socket.h),这些库底层封装了操作系统的 Socket API。
    • 开发者使用这些库提供的函数/方法来创建 Socket、配置地址、建立连接、发送和接收数据、关闭连接。
  • 两种主要模式:
    • 面向连接 (TCP-like):
      • 通信前需要先建立稳定的连接(类似打电话前先拨号接通)。
      • 保证数据顺序、可靠传输(丢失的数据会重传)。
      • 典型流程:服务器 socket() -> bind() -> listen() -> accept();客户端 socket() -> connect();然后双方 send() / recv();最后 close()
    • 无连接 (UDP-like):
      • 不需要预先建立连接(类似寄明信片)。
      • 发送独立的数据包(数据报),不保证顺序、不保证可靠到达(可能丢失)。
      • 速度快,开销小。
      • 典型流程:双方都 socket() (指定为 UDP);服务器 bind();然后双方直接 sendto() (需要指定目标地址) / recvfrom() (能获取来源地址)。

简单总结: Socket 编程就是使用编程语言提供的工具(基于 Socket 概念),按照特定的流程(TCP/UDP),编写代码让程序通过网络相互通信。

3. Python 的 Socket 编程该如何用?

Python 通过内置的 socket 模块提供了强大的 Socket 编程能力。下面分别给出 TCP 和 UDP 的简单示例:

环境准备

确保你安装了 Python(通常自带 socket 模块)。

TCP Socket 示例(面向连接)

服务器端 (server.py)
import socket# 1. 创建 TCP Socket (AF_INET 表示 IPv4, SOCK_STREAM 表示 TCP)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2. 绑定地址和端口 ('' 表示绑定到本机所有可用网络接口)
server_address = ('', 8888)  # 端口号 8888
server_socket.bind(server_address)# 3. 开始监听连接 (参数 5 表示最大等待连接队列长度)
server_socket.listen(5)
print("服务器已启动,等待客户端连接...")# 4. 等待并接受客户端连接
# accept() 会阻塞,直到有客户端连接
# client_socket 是用于和这个特定客户端通信的新 Socket
# client_address 是客户端的 (IP地址, 端口号)
client_socket, client_address = server_socket.accept()
print(f"客户端 {client_address} 已连接")try:# 5. 接收客户端数据data = client_socket.recv(1024)  # 一次最多接收 1024 字节print(f"收到来自客户端的消息: {data.decode('utf-8')}")  # 假设是 UTF-8 文本# 6. 发送响应给客户端response = "你好,客户端!我已收到你的消息。".encode('utf-8')client_socket.sendall(response)  # sendall 确保发送所有数据finally:# 7. 关闭连接 (先关客户端Socket,再关服务器Socket)client_socket.close()server_socket.close()print("连接已关闭")
客户端 (client.py)
import socket# 1. 创建 TCP Socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2. 连接服务器 (替换 'localhost' 为服务器实际 IP)
server_address = ('localhost', 8888)  # 端口号必须与服务器一致
print("正在连接服务器...")
client_socket.connect(server_address)try:# 3. 发送数据给服务器message = "你好,服务器!这是来自客户端的消息。".encode('utf-8')client_socket.sendall(message)# 4. 接收服务器的响应data = client_socket.recv(1024)print(f"收到服务器的响应: {data.decode('utf-8')}")finally:# 5. 关闭连接client_socket.close()print("连接已关闭")

运行步骤:

  1. 先运行 server.py (它会等待连接)。
  2. 再运行 client.py
  3. 观察两个终端窗口的输出。

UDP Socket 示例(无连接)

接收方 (udp_receiver.py)
import socket# 1. 创建 UDP Socket (SOCK_DGRAM 表示 UDP)
receiver_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 2. 绑定地址和端口
receiver_address = ('', 9999)  # 端口号 9999
receiver_socket.bind(receiver_address)print("UDP 接收方已启动,等待数据...")# 3. 接收数据 (不需要先连接)
# recvfrom() 返回 (数据, 发送方地址)
data, sender_address = receiver_socket.recvfrom(1024)
print(f"收到来自 {sender_address} 的消息: {data.decode('utf-8')}")# 4. (可选) 发送回复
response = "UDP 消息已收到!".encode('utf-8')
receiver_socket.sendto(response, sender_address)# 5. 关闭 Socket
receiver_socket.close()
发送方 (udp_sender.py)
import socket# 1. 创建 UDP Socket
sender_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 2. 目标地址 (替换 'localhost' 为接收方实际 IP)
receiver_address = ('localhost', 9999)  # 端口号必须与接收方一致# 3. 发送数据 (不需要先连接)
message = "这是一条 UDP 测试消息!".encode('utf-8')
sender_socket.sendto(message, receiver_address)
print("UDP 消息已发送")# 4. (可选) 接收回复
data, addr = sender_socket.recvfrom(1024)
print(f"收到来自 {addr} 的回复: {data.decode('utf-8')}")# 5. 关闭 Socket
sender_socket.close()

运行步骤:

  1. 先运行 udp_receiver.py (它会等待数据)。
  2. 再运行 udp_sender.py
  3. 观察两个终端窗口的输出。

Python Socket 编程关键点

  1. 导入模块: import socket
  2. 创建 Socket:
    • socket.socket(family, type)
    • family: socket.AF_INET (IPv4), socket.AF_INET6 (IPv6)
    • type: socket.SOCK_STREAM (TCP), socket.SOCK_DGRAM (UDP)
  3. 绑定地址 (服务器端必需):
    • socket.bind((host, port)) - host 可以是 '' (所有接口), 'localhost' (仅本机), 或具体 IP;port 是整数端口号。
  4. 监听连接 (TCP 服务器): socket.listen(backlog)
  5. 接受连接 (TCP 服务器): client_socket, client_address = socket.accept()
  6. 发起连接 (TCP 客户端): socket.connect((host, port))
  7. 发送数据:
    • TCP: socket.send(data) (可能不发送完所有数据) 或 socket.sendall(data) (确保发送所有数据)。
    • UDP: socket.sendto(data, (host, port))
  8. 接收数据:
    • TCP: data = socket.recv(bufsize) - bufsize 是最大接收字节数。
    • UDP: data, address = socket.recvfrom(bufsize)
  9. 关闭 Socket: socket.close() - 非常重要! 务必在通信结束后关闭 Socket 释放资源。
  10. 地址格式: 总是使用元组 (host, port) 表示网络地址。
  11. 数据处理: 网络传输的是字节 (bytes)。发送前用 .encode('utf-8') 将字符串编码为字节;接收后用 .decode('utf-8') 将字节解码为字符串(假设是文本)。对于二进制数据(如图片),直接操作字节。
  12. 错误处理: 网络操作容易出错(连接失败、连接中断等),务必使用 try...except 块捕获可能的异常(如 socket.error, ConnectionResetError 等)。

进阶方向

  • 多客户端处理: 上面的 TCP 服务器一次只能处理一个客户端。要处理多个并发客户端,需要使用:
    • 多线程: 为每个接受的客户端连接创建一个新线程。
    • 多进程: 类似多线程,但开销更大。
    • 异步 I/O: 使用 select, poll, epoll (Linux) 或更高级的框架如 asyncioTwistedTornado 实现高性能非阻塞服务器。
  • Socket 选项: 使用 setsockopt() 设置各种选项(如重用地址 SO_REUSEADDR)。
  • 超时: 使用 settimeout() 设置阻塞操作的超时时间。
  • DNS 解析: socket.gethostbyname(), socket.gethostbyaddr()

通过理解 Socket 的基本概念和 Python socket 模块的使用,你就掌握了编写各种网络应用程序(如聊天程序、文件传输、远程控制等)的基础能力。实践是掌握的关键,多写代码多调试!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/91566.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/91566.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/91566.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【科普】进程与线程的区别

一、定义与概念:进程:进程是执行中的一段程序。一旦程序被载入到内存中并准备执行,就变成了一个进程。进程是表示资源分配的基本概念,又是调度运行的基本单位,是系统中的并发执行的单位。线程:线程是进程中…

Conda创建虚拟环境,解决不同项目的冲突!

随着需求的增多,又要增加多几个不同的项目来在本地测试,这个时候往往就会遇到 不同项目的Python版本不同等等一系列问题,只好请出Conda来帮忙。 一、先去下载安装一下Conda Conda | Anaconda.org 安装完后,需要给CONDA做个环境变…

RK3568下的进程间广播通信:用C语言构建简单的中心服务器

最近的项目中需要实现这样一个功能,就是一个进程A发消息,进程B和进程C都能收到相同的消息,同样,进程B发消息,进程A和进程C也都能收到消息,就像下图中的描述。 使用一个中心服务器作为消息转发枢纽,所有客户端连接到服务器,发送消息到服务器后,服务器再将消息转发给所有…

激光雷达/相机一体机 时间同步和空间标定(1)

一、参考链接 海康威视、LIVOX与PTP时间同步_海康相机ptp同步-CSDN博客 基于PTP实现主机与相机系统时钟同步功能_ptp同步-CSDN博客

嵌入式系统的中断控制器(NVIC)

1. NVIC的核心功能 核心价值:NVIC通过硬件级中断管理、自动状态处理及低延迟优化,为实时系统提供确定性响应,是Cortex-M芯片实时性的基石。 中断优先级管理 支持多级可编程优先级(通常4-8位,如STM32用4位实现16级优先级…

【源力觉醒 创作者计划】2025年国产AI模型深度测评:文心大模型4.5、DeepSeek、Qwen3能力大比拼

文章目录引言:AI大模型的新时代一、模型架构与技术生态对比1. 文心大模型4.5系列2. DeepSeek3. 通义千问(Qwen 3.0)二、语言理解能力实测2.1 情感分析测试2.1.1 文心一言的表现2.1.2 DeepSeek的表现2.1.3 Qwen 3.0的表现2.1.4 测试结果分析2.…

从C++0基础到C++入门(第十五节:switch语句)

一. switch语句1.1 语法结构如下:switch (表达式) {case 常量1:// 代码块1break;case 常量2:// 代码块2break;default:// 默认代码块 }1.2 注意 :表达式必须是整型或枚举类型(如int、char)。case后的常量必须与表达式类型兼容。学…

编程与数学 03-002 计算机网络 16_网络编程基础

编程与数学 03-002 计算机网络 16_网络编程基础一、网络编程的基本概念(一)客户端与服务器模型(二)套接字(Socket)编程的基本原理二、基于TCP的网络编程(一)TCP套接字的创建与使用&a…

在纯servlet项目中,使用@WebFilter定义了多个filter,如何设置filter的优先级

在纯 Servlet 项目中,WebFilter 注解本身并不提供直接的属性来设置过滤器的优先级(如过滤器执行的顺序)。但是,你可以通过以下几种方式来控制过滤器的执行顺序:1. 通过 web.xml 配置过滤器的顺序在 web.xml 中&#xf…

关于鸦片战争的历史

19世纪,英国东印度公司获得了鸦片贸易的垄断权,而犹太人是东印度公司的主要投资人之一,英国东印度公司又将鸦片经营权外包给了犹太人。其中,塞法迪犹太人控制了主要的鸦片交易,著名的沙逊家族就是当时臭名昭著的犹太鸦…

Maven - 并行安全无重复打包构建原理揭秘

作者:唐叔在学习 专栏:唐叔的Java实践 标签: #Maven并行构建 #Maven多线程打包 #Java构建优化 #Maven性能调优 #CI/CD加速 #Maven反应堆原理 #避免重复编译 #高并发构建 文章目录一、遇到问题:并行打包会不会翻车?二、…

phpyun人才系统v7.1使用升级补丁怎么从授权版升级至vip版?我说下我的技巧有资源的可以看过来,这样就不用花钱麻烦官方了,新版本照样支持小程序源码

前:这个方法我只在Phpyun 的7.x系列使用过,低于这个版本的我暂时没有研究过,我感觉大同小异! 一. 升级前提条件 无论现在你使用的是商业版还是学习版 想垮系列升级你必须有对应的升级补丁,比如说你是授权版或旗舰版 想升级到最新的…

P13014 [GESP202506 五级] 最大公因数

题目描述对于两个正整数 a,b,他们的最大公因数记为 gcd(a,b)。对于 k>3 个正整数 c1​,c2​,…,ck​,他们的最大公因数为:gcd(c1​,c2​,…,ck​)gcd(gcd(c1​,c2​,…,ck−1​),ck​)给定 n 个正整数 a1​,a2​,…,an​ 以及 q 组询问。对…

【机器学习-4】 | 集成学习 / 随机森林篇

集成学习与随机森林学习笔记 0 序言 本文将系统介绍Bagging、Boosting两种集成学习方法及随机森林算法,涵盖其原理、过程、参数等内容。通过学习,你能理解两种方法的区别,掌握随机森林的随机含义、算法步骤、优点及关键参数使用,明…

深入 Go 底层原理(十二):map 的实现与哈希冲突

1. 引言map 是 Go 语言中使用频率极高的数据结构,它提供了快速的键值对存取能力。虽然 map 的使用非常简单,但其底层的实现却是一个精心设计的哈希表,它需要高效地处理哈希计算、数据存储、扩容以及最关键的——哈希冲突。本文将解剖 map 的底…

Reinforcing General Reasoning without Verifiers

1.概述 DeepSeek-R1-Zero [10] 最近展示了使用可验证奖励的强化学习(RL)训练大型语言模型(LLMs)可以极大地提高推理能力。在这个可验证奖励的强化学习(RLVR)框架 [17] 中,LLM 生成一个推理过程(即,思维链,CoT),然后给出最终答案。一个基于规则的程序随后提取并评估…

Hyperbrowser MCP:重新定义网页抓取与浏览器自动化的AI驱动工具

在数据驱动的时代,网页内容的高效处理和自动化操作成为开发者和企业关注的焦点。Hyperbrowser MCP(Model Context Protocol Server)作为一款革命性的工具,通过AI与浏览器技术的深度融合,为网页抓取、结构化数据提取和浏览器自动化提供了全新的解决方案。无论你是需要从复杂…

关于Web前端安全防御XSS攻防的几点考虑

作为一位前端老鸟,总结一下web前端安全领域基础概念、防御策略、框架实践及新兴技术等几个维度的考虑。一、基础概念与核心漏洞1.XSS 攻击XSS(跨站脚本攻击)是 Web 前端安全中最常见的威胁之一,其核心是攻击者将恶意脚本注入到网页…

eSIM技术深度解析:从物理芯片到数字革命

当苹果公司在2018年首次在iPhone XS系列中引入eSIM技术时,许多用户可能并未意识到这个看似微小的改变将带来怎样的技术革命。从1991年第一张信用卡大小的SIM卡,到今天仅有5mm x 5mm的eSIM芯片,这不仅仅是尺寸的缩小,更是移动通信技…

通俗易懂解释Java8 HashMap

我们来用通俗易懂的方式解释一下 Java 8 中 HashMap 的原理,让你对它的结构、运行机制有清晰的理解。🌳 什么是 HashMap? HashMap 是 Java 中非常常用的数据结构,用于存储键值对(key-value)。你可以把它理解…