当前位置: 首页 > article >正文

C/C++ Socket网络编程 介绍

前言对于C/C初学者来说网络编程似乎是一道门槛而Socket就是打开这扇门的钥匙。今天我们一起来看看如何入门Socket网络编程。目录一、什么是Socket二、Socket编程流程三、TCP Socket编程示例四、一些注意事项一、什么是SocketSocket套接字是操作系统提供的网络通信编程接口是应用层与传输层之间的桥梁。┌─────────────────────────────────────┐ │ 应用层 (HTTP/FTP/DNS) ├─────────────────────────────────────┤ │ Socket 接口 ← 我们编程的位置 ├─────────────────────────────────────┤ │ 传输层 (TCP/UDP) ├─────────────────────────────────────┤ │ 网络层 (IP/ICMP) ├─────────────────────────────────────┤ │ 网络接口层 (以太网/WiFi) └─────────────────────────────────────┘1) Socket的作用通信信道Socket 为网络中的数据传输提供了一个虚拟信道数据可以通过这个信道从发送方传输到接收方地址识别通过 IP 地址和端口号Socket 能够标识网络中的特定设备和应用程序协议兼容性Socket 允许应用使用不同的传输层协议来进行通信如 TCP 和 UDP。2) Socket的类型类型协议特点应用场景流式套接字TCP面向连接、可靠、有序、无边界文件传输、网页浏览、数据库数据报套接字UDP无连接、不可靠、有边界、高效视频直播、DNS、在线游戏原始套接字IP/ICMP直接访问底层协议网络诊断、安全工具二、Socket编程流程1) 服务端编程步骤创建套接字socket使用socket()函数创建一个新的套接字。绑定套接字bind通过bind()函数将套接字与特定的IP地址和端口号关联起来。监听连接listen使用listen()函数使服务器套接字监听来自客户端的连接请求。接受连接accept当客户端请求连接时accept()函数会接受这个连接。读取数据read/recv从客户端接收数据。发送数据write/send向客户端发送数据。关闭套接字close完成数据传输后关闭连接。2) 客户端编程步骤创建套接字socket同服务端。发起连接connect使用connect()函数向服务器发起连接请求。发送数据write/send向服务器发送数据。读取数据read/recv从服务器接收数据。关闭套接字close完成数据传输后关闭连接。例如TCP Socket通信流程服务端Server 客户端Client │ │ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ socket() │ 创建套接字 │ socket() │ │ 创建监听fd │ │ 创建通信fd | └──────┬──────┘ └──────┬──────┘ │ │ ▼ │ ┌─────────────┐ │ │ bind() │ 绑定IP:端口 │ │ 0.0.0.0:8080│ │ └──────┬──────┘ │ │ │ ▼ │ ┌─────────────┐ │ │ listen() │ 开始监听backlog队列 │ │ 被动等待连接│ │ └──────┬──────┘ │ │◄────────────────────────────────────────┤ │ connect() 发起连接 │ │ 三次握手开始... │ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ accept() │◄───────────────────────► │ 连接建立 │ │ 阻塞等待连接 │ 返回新的通信fd(connfd) │ │ └──────┬──────┘ └──────┬──────┘ │ │ │◄────────── 双向数据传输 ───────────────► │ │ read()/write() 或 recv()/send() │ │ │ │ 四次挥手断开连接... │ │◄───────────────────────────────────────►│ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ close() │ │ close() │ │ 关闭connfd │ │ 关闭fd │ │ 关闭listenfd│ │ │ └─────────────┘ └─────────────┘三、TCP Socket编程示例本文仅演示基础版本(阻塞式TCP通信单线程)服务器编程// server_basic.cpp #include iostream #include cstring #include string #include unistd.h // close, read, write #include arpa/inet.h // inet_addr, htons #include sys/socket.h // socket, bind, listen, accept int main() { // 1. 创建套接字 (IPv4, TCP, 默认协议) int server_fd socket(AF_INET, SOCK_STREAM, 0); if (server_fd -1) { std::cerr 创建socket失败 std::endl; return -1; } std::cout [1] Socket创建成功, fd server_fd std::endl; // 2. 绑定地址和端口 struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); // 清零 server_addr.sin_family AF_INET; // IPv4 server_addr.sin_port htons(8080); // 端口8080 (转网络字节序) server_addr.sin_addr.s_addr INADDR_ANY; // 监听所有网卡 0.0.0.0 if (bind(server_fd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { std::cerr 绑定失败 std::endl; close(server_fd); return -1; } std::cout [2] 绑定成功 0.0.0.0:8080 std::endl; // 3. 开始监听 (最大等待队列长度5) if (listen(server_fd, 5) -1) { std::cerr 监听失败 std::endl; close(server_fd); return -1; } std::cout [3] 开始监听... std::endl; // 4. 接受客户端连接 (阻塞等待) struct sockaddr_in client_addr; socklen_t addr_len sizeof(client_addr); std::cout [4] 等待客户端连接... std::endl; int client_fd accept(server_fd, (struct sockaddr*)client_addr, addr_len); if (client_fd -1) { std::cerr 接受连接失败 std::endl; close(server_fd); return -1; } char client_ip[16]; inet_ntop(AF_INET, client_addr.sin_addr, client_ip, sizeof(client_ip)); std::cout [5] 客户端连接! IP client_ip 端口 ntohs(client_addr.sin_port) std::endl; // 5. 数据收发循环 char buffer[1024]; while (true) { // 接收数据 memset(buffer, 0, sizeof(buffer)); int recv_len recv(client_fd, buffer, sizeof(buffer) - 1, 0); if (recv_len 0) { std::cout [6] 客户端断开连接 std::endl; break; } std::cout [收到] buffer std::endl; // 发送响应 std::string response 服务器收到: ; response buffer; send(client_fd, response.c_str(), response.length(), 0); } // 6. 关闭连接 close(client_fd); close(server_fd); std::cout [7] 服务器关闭 std::endl; return 0; }客户端编程// client_basic.cpp #include iostream #include cstring #include string #include unistd.h #include arpa/inet.h #include sys/socket.h int main() { // 1. 创建套接字 int sock_fd socket(AF_INET, SOCK_STREAM, 0); if (sock_fd -1) { std::cerr 创建socket失败 std::endl; return -1; } std::cout [1] Socket创建成功 std::endl; // 2. 设置服务器地址 struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_port htons(8080); // 服务器端口 // 将IP字符串转为网络字节序 if (inet_pton(AF_INET, 127.0.0.1, server_addr.sin_addr) 0) { std::cerr 无效的IP地址 std::endl; close(sock_fd); return -1; } // 3. 连接服务器 std::cout [2] 正在连接服务器... std::endl; if (connect(sock_fd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { std::cerr 连接失败 std::endl; close(sock_fd); return -1; } std::cout [3] 连接成功! std::endl; // 4. 发送和接收数据 char buffer[1024]; while (true) { // 输入消息 std::cout 请输入消息 (输入quit退出): ; std::string msg; std::getline(std::cin, msg); if (msg quit) { break; } // 发送 if (send(sock_fd, msg.c_str(), msg.length(), 0) -1) { std::cerr 发送失败 std::endl; break; } // 接收响应 memset(buffer, 0, sizeof(buffer)); int recv_len recv(sock_fd, buffer, sizeof(buffer) - 1, 0); if (recv_len 0) { std::cout 服务器断开连接 std::endl; break; } std::cout [服务器回复] buffer std::endl; } // 5. 关闭 close(sock_fd); std::cout [4] 客户端关闭 std::endl; return 0; }四、一些注意事项1)网络字节序问题端口、IP 地址在协议头中都是网络字节序大端如果直接填主机字节序在大小端不同的机器上会错乱。2)返回值与错误码每个系统调用都需要检查返回值并打印错误信息。3)必须关闭Socketsocket 是文件描述符或句柄不关闭会慢慢耗尽资源。

相关文章:

C/C++ Socket网络编程 介绍

前言:对于C/C初学者来说,网络编程似乎是一道"门槛",而Socket就是打开这扇门的钥匙。今天我们一起来看看如何入门Socket网络编程。 目录 一、什么是Socket 二、Socket编程流程 三、TCP Socket编程示例 四、一些注意事项 一、什么…...

FramePack深度解析:如何利用下一代帧预测技术创作高质量AI舞蹈视频

FramePack深度解析:如何利用下一代帧预测技术创作高质量AI舞蹈视频 【免费下载链接】FramePack Lets make video diffusion practical! 项目地址: https://gitcode.com/gh_mirrors/fr/FramePack FramePack是一款革命性的视频扩散神经网络框架,它通…...

leetcode 1636. 按照频率将数组升序排序-耗时100-Sort Array by Increasing Frequency

Problem: 1636. 按照频率将数组升序排序- Sort Array by Increasing Frequency 耗时100%&#xff0c;哈希表统计频次&#xff0c;然后频次和数字放入数组&#xff0c;按照题意的规则排序&#xff0c;最后得到最终的数组 Code class Solution { public:int ump[201];vector<…...

AutoGLM-Phone-9B功能体验:实测语音指令控制与图像识别

AutoGLM-Phone-9B功能体验&#xff1a;实测语音指令控制与图像识别 1. 多模态能力初体验 AutoGLM-Phone-9B作为一款专为移动端优化的多模态大模型&#xff0c;其最吸引人的特点莫过于融合了视觉、语音与文本处理能力。在实际测试中&#xff0c;我发现这款模型在资源受限设备上…...

基于CURSOR的APP自动化测试框架实战指南(一)

1. 为什么选择CURSOR搭建APP自动化测试框架 第一次接触APP自动化测试时&#xff0c;我被各种工具和框架搞得晕头转向。直到遇到CURSOR&#xff0c;才发现原来搭建测试框架可以这么简单。CURSOR最大的优势在于它把复杂的配置过程封装成了可视化操作&#xff0c;就像用积木搭房子…...

小白友好指南:在星图GPU平台无代码体验OpenClaw+Qwen3-32B

小白友好指南&#xff1a;在星图GPU平台无代码体验OpenClawQwen3-32B 1. 为什么选择云端无代码方案&#xff1f; 去年第一次接触OpenClaw时&#xff0c;我花了整整三天时间在本地环境折腾依赖项。从CUDA版本冲突到Python虚拟环境报错&#xff0c;最后连基础命令都无法执行。直…...

别再只会用OpenAI库了!用Requests库手把手教你调用硅基流动大模型API(附完整错误处理)

深入解析Requests库调用大模型API的工程化实践 在当今AI技术快速发展的背景下&#xff0c;大语言模型(LLM)已成为开发者工具箱中不可或缺的一部分。虽然OpenAI库提供了便捷的封装&#xff0c;但直接使用Requests库进行API调用能带来更大的灵活性和控制力。本文将深入探讨如何通…...

非线性悬架与UKF状态估计的Matlab/Simulink建模源码及文档资料

非线性悬架&#xff0c;UKF状态估计 软件使用&#xff1a;Matlab/Simulink 适用场景&#xff1a;采用模块化建模方法&#xff0c;搭建空气悬架模型&#xff0c;UKF状态估计模型&#xff0c;可实现悬架动挠度等状态估计。 包含&#xff1a;simulink源码文件&#xff0c;详细建模…...

一款基于 .NET 开源、跨平台应用程序自动升级组件恳

基础示例&#xff1a;单工作表 Excel 转 TXT 以下是将一个 Excel 文件中的第一个工作表转换为 TXT 的完整步骤&#xff1a; 1. 加载并读取Excel文件 from spire.xls import * from spire.xls.common import * workbook Workbook() workbook.LoadFromFile("示例.xlsx"…...

HTTP 与 HTTPS 详解:区别、工作原理、应用场景(超清晰易懂版)

HTTP 与 HTTPS 详解&#xff1a;区别、工作原理、应用场景&#xff08;超清晰易懂版&#xff09;一、HTTP 是什么&#xff1f;二、HTTPS 是什么&#xff1f;三、HTTP 与 HTTPS 最核心区别&#xff08;一张表看懂&#xff09;四、HTTP 工作原理&#xff08;极简&#xff09;五、…...

保姆级教程:彻底解决VMware vCenter证书过期问题(含certificate-manager全流程)

深度解析&#xff1a;VMware vCenter证书体系与certificate-manager全流程操作指南 当你突然无法登录vCenter管理界面&#xff0c;看到浏览器弹出"此网站的安全证书已过期"的红色警告时&#xff0c;作为运维人员的肾上腺素立刻飙升。这不是普通的登录问题&#xff0c…...

【RocketMQ】消息重试机制深度解析:从异常处理到死信队列的最佳实践

1. RocketMQ消息重试机制全景解读 第一次接触RocketMQ的重试功能时&#xff0c;我踩过一个坑&#xff1a;线上系统突然出现大量消息堆积&#xff0c;排查后发现是消费者处理异常导致消息不断重试。这个经历让我深刻认识到&#xff0c;理解消息重试机制是保障分布式系统可靠性的…...

AI图像增强实用指南:用Real-ESRGAN-GUI提升图片清晰度

AI图像增强实用指南&#xff1a;用Real-ESRGAN-GUI提升图片清晰度 【免费下载链接】Real-ESRGAN-GUI Lovely Real-ESRGAN / Real-CUGAN GUI Wrapper 项目地址: https://gitcode.com/gh_mirrors/re/Real-ESRGAN-GUI 在数字时代&#xff0c;我们经常遇到低分辨率、模糊的图…...

Docker数据迁移到新磁盘的5个常见坑及解决方案(附详细步骤)

Docker数据迁移到新磁盘的5个常见坑及解决方案&#xff08;附详细步骤&#xff09; 当你发现服务器上的Docker容器运行越来越慢&#xff0c;或者频繁出现"no space left on device"的错误时&#xff0c;数据迁移就成了迫在眉睫的任务。作为一名经历过数十次Docker迁移…...

如何高效管理电脑COM端口:编辑与重置技巧

1. 为什么需要管理COM端口号&#xff1f; 当你同时连接多个串口设备时&#xff0c;比如调试单片机、连接工业控制器或者使用老式打印机&#xff0c;Windows会自动为这些设备分配COM端口号。时间一长&#xff0c;你会发现设备管理器里的COM号像野草一样疯长&#xff0c;从COM1一…...

从硬件小白到项目上线:我的第一个STM32物联网项目(小熊派智慧路灯踩坑实录)

从硬件小白到项目上线&#xff1a;我的第一个STM32物联网项目&#xff08;小熊派智慧路灯踩坑实录&#xff09; 第一次拿到小熊派开发板时&#xff0c;那种既兴奋又忐忑的心情至今记忆犹新。作为一个刚转行物联网开发的菜鸟&#xff0c;我对着这块印着卡通熊标志的绿色电路板发…...

Klipper配置TMC2209避坑指南:UART模式下的74HC4066切换电路详解

Klipper配置TMC2209避坑指南&#xff1a;UART模式下的74HC4066切换电路详解 在3D打印机DIY领域&#xff0c;TMC2209驱动芯片凭借其静音性能和精细控制能力广受欢迎。但许多玩家在尝试UART模式配置时&#xff0c;常常遇到多个电机同时响应、信号干扰等棘手问题。本文将深入解析7…...

、SEATA分布式事务——XA模式讼

MySQL 中的 count 三兄弟&#xff1a;效率大比拼&#xff01; 一、快速结论&#xff08;先看结论再看分析&#xff09; 方式 作用 效率 一句话总结 count(*) 统计所有行数 最高 我是专业的&#xff01;我为统计而生 count(1) 统计所有行数 同样高效 我是 count(*) 的马甲兄弟…...

从零到百:用Python代码解放剪映生产力,告别重复剪辑劳动

从零到百&#xff1a;用Python代码解放剪映生产力&#xff0c;告别重复剪辑劳动 【免费下载链接】JianYingApi Third Party JianYing Api. 第三方剪映Api 项目地址: https://gitcode.com/gh_mirrors/ji/JianYingApi 想象一下这样的场景&#xff1a;你是一家电商公司的视…...

Java 25虚拟线程在微服务网关中的压测实录(QPS提升8.2倍但GC耗时翻倍的真相)

第一章&#xff1a;Java 25虚拟线程在高并发架构下的实践成本控制策略Java 25正式将虚拟线程&#xff08;Virtual Threads&#xff09;从预览特性转为标准特性&#xff0c;其核心价值在于以极低的内存与调度开销支撑百万级并发任务。然而&#xff0c;在生产环境中规模化落地时&…...

uniApp相机、存储、电话权限申请全攻略:告别频繁弹窗,提升用户体验

uniApp权限管理艺术&#xff1a;优雅实现相机、存储、电话权限的智能授权策略 在移动应用开发中&#xff0c;权限管理一直是开发者与用户之间的微妙博弈。过于频繁的权限请求会引发用户反感&#xff0c;而缺乏透明度的权限获取又可能导致应用商店审核失败。如何在uniApp框架下构…...

ORB SLAM3性能优化:如何用ORBvoc.bin替代txt文件实现秒级加载(附完整代码修改指南)

ORB SLAM3性能优化实战&#xff1a;二进制词袋加载速度提升10倍的工程实践 第一次运行ORB SLAM3时&#xff0c;盯着终端里缓慢滚动的词袋加载进度条&#xff0c;我下意识看了下手表——整整8秒。在机器人实时定位场景中&#xff0c;这种等待简直像永恒。直到发现二进制词袋的加…...

【PHP 8.9 纤维协程实战黄金手册】:20年架构师亲授高并发服务重构的5大避坑法则

第一章&#xff1a;PHP 8.9 纤维协程的底层机制与演进本质PHP 8.9 并非官方发布的正式版本&#xff08;截至 PHP 官方最新稳定版为 8.3&#xff09;&#xff0c;但本章所探讨的“纤维协程”概念&#xff0c;实为对 PHP 8.1 引入的 Fiber 类、经 8.2/8.3 持续优化后&#xff0c;…...

告别手动整理!用快马AI生成脚本,自动化处理论文参考文献格式

最近在赶毕业论文&#xff0c;最让我头疼的就是参考文献的格式整理。不同期刊要求不同&#xff0c;手动调整费时费力还容易出错。后来发现用Python写个自动化脚本能省不少时间&#xff0c;今天就把我的实现思路分享给大家。 首先明确需求&#xff0c;脚本需要处理的核心问题包括…...

Flutter 性能优化:构建流畅的应用体验

Flutter 性能优化&#xff1a;构建流畅的应用体验掌握 Flutter 性能优化的高级技巧&#xff0c;创建流畅、响应迅速的应用。一、性能优化概述 作为一名追求像素级还原的 UI 匠人&#xff0c;我对 Flutter 性能优化有着深入的研究。性能优化是现代应用开发的重要组成部分&#x…...

CSS 动画高级技巧:创建流畅的用户体验

CSS 动画高级技巧&#xff1a;创建流畅的用户体验掌握 CSS 动画的高级技巧&#xff0c;创建流畅、引人入胜的用户体验。一、动画基础回顾 作为一名追求像素级还原的 UI 匠人&#xff0c;我对 CSS 动画有着深入的研究。CSS 动画是现代前端开发的重要组成部分&#xff0c;它可以为…...

Flutter 响应式设计:构建适配多设备的应用

Flutter 响应式设计&#xff1a;构建适配多设备的应用掌握 Flutter 响应式设计的高级技巧&#xff0c;创建适配不同屏幕尺寸的应用。一、响应式设计概述 作为一名追求像素级还原的 UI 匠人&#xff0c;我对 Flutter 响应式设计有着深入的研究。响应式设计是现代应用开发的重要组…...

分支定界算法实战:从理论到编程实现的关键步骤解析

1. 分支定界算法入门&#xff1a;从买菜砍价到代码实现 想象一下你在菜市场砍价的场景&#xff1a;老板开价100元&#xff0c;你心里有个底线是80元。这时候你会怎么做&#xff1f;通常会先试探性报个低价&#xff08;比如60元&#xff09;&#xff0c;然后根据老板反应逐步调…...

概率论作业救星:用科学计算器5分钟搞定样本标准差与方差(含S和σ区分指南)

概率论作业救星&#xff1a;科学计算器5分钟速成样本标准差与方差实战指南 深夜赶概率论作业时&#xff0c;你是否也曾在样本标准差&#xff08;S&#xff09;和总体标准差&#xff08;σ&#xff09;的选项前犹豫不决&#xff1f;面对卡西欧fx-82ES计算器密密麻麻的按键&…...

STC单片机冷启动下载总失败?手把手教你STC8G1K08A的ISP下载正确姿势(附V6.90软件设置)

STC8G1K08A单片机ISP下载全流程避坑指南 最近在调试STC8G1K08A时&#xff0c;发现不少初学者卡在ISP下载这个入门第一步。明明接线正确&#xff0c;软件设置也没问题&#xff0c;但就是反复提示"检测不到单片机"。这其实与STC特有的冷启动机制密切相关。今天我们就来…...