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

Socket 函数详细讲解(Socket编程步骤、socket函数、TCP和UDP的区别)

Socket 函数详细讲解和 C++ 示例

  • 一、 Socket 基本概念
    • 1. Socket 简介
    • 2. Socket 编程步骤
    • 3. TCP Socket 编程示例
      • 服务器端
      • 客户端
    • 4. 详细说明
  • 二、 socket 函数
    • 1. domain 通讯的协议家族
    • 2. type 数据传输的类型
    • 3. protocol 最终使用的协议
      • 返回值
      • 示例
  • 三、TCP 和 UDP的区别
    • 1. TCP(传输控制协议)
    • 2. UDP(用户数据报协议)
    • 3. 总结
    • 示例应用

一、 Socket 基本概念

1. Socket 简介

Socket 是一种通信机制,允许在不同主机之间或同一主机的不同进程之间进行数据交换。使用 socket 编程可以实现 TCP 和 UDP 协议的网络通信。

2. Socket 编程步骤

  1. 创建 Socket
  2. 绑定(仅服务器)
  3. 监听(仅服务器)
  4. 接受连接(仅服务器)
  5. 连接服务器(仅客户端)
  6. 发送和接收数据
  7. 关闭 Socket

3. TCP Socket 编程示例

服务器端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 8080
#define BUFFER_SIZE 1024int main() {int server_fd, new_socket;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[BUFFER_SIZE] = {0};// 创建 socket 文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 绑定address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");close(server_fd);exit(EXIT_FAILURE);}// 监听if (listen(server_fd, 3) < 0) {perror("listen failed");close(server_fd);exit(EXIT_FAILURE);}// 接受连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept failed");close(server_fd);exit(EXIT_FAILURE);}// 读取客户端发送的数据read(new_socket, buffer, BUFFER_SIZE);std::cout << "Message from client: " << buffer << std::endl;// 发送数据给客户端const char *message = "Hello from server";send(new_socket, message, strlen(message), 0);std::cout << "Hello message sent\n";// 关闭 socketclose(new_socket);close(server_fd);return 0;
}

客户端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080
#define BUFFER_SIZE 1024int main() {int sock = 0;struct sockaddr_in serv_addr;char buffer[BUFFER_SIZE] = {0};// 创建 socket 文件描述符if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {std::cerr << "Socket creation error" << std::endl;return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 将地址转换成二进制if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {std::cerr << "Invalid address/ Address not supported" << std::endl;return -1;}// 连接服务器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {std::cerr << "Connection Failed" << std::endl;return -1;}// 发送数据给服务器const char *message = "Hello from client";send(sock, message, strlen(message), 0);std::cout << "Hello message sent\n";// 读取服务器发送的数据read(sock, buffer, BUFFER_SIZE);std::cout << "Message from server: " << buffer << std::endl;// 关闭 socketclose(sock);return 0;
}

4. 详细说明

  1. 创建 Socket

    • socket(int domain, int type, int protocol)
      • domain: 使用的协议族,例如 AF_INET 表示 IPv4 网络协议。
      • type: Socket 类型,例如 SOCK_STREAM 表示面向连接的 TCP。
      • protocol: 一般设置为 0,让系统自动选择合适的协议。
  2. 绑定

    • bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
      • 将 socket 绑定到特定的 IP 地址和端口号。
  3. 监听

    • listen(int sockfd, int backlog)
      • 使 socket 处于监听状态,准备接受连接。
      • backlog 指定等待连接队列的最大长度。
  4. 接受连接

    • accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
      • 从监听队列中接受一个连接,返回一个新的 socket 文件描述符,用于与客户端通信。
  5. 连接服务器

    • connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
      • 客户端使用这个函数连接到服务器。
  6. 发送和接收数据

    • send(int sockfd, const void *buf, size_t len, int flags)
    • recv(int sockfd, void *buf, size_t len, int flags)
    • readwrite 也可以用于接收和发送数据。
  7. 关闭 Socket

    • close(int sockfd)
      • 关闭 socket 文件描述符。

二、 socket 函数

  • socket(int domain, int type, int protocol)
    • domain: 使用的协议族,例如 AF_INET 表示 IPv4 网络协议。
    • type: Socket 类型,例如 SOCK_STREAM 表示面向连接的 TCP。
    • protocol: 一般设置为 0,让系统自动选择合适的协议。

1. domain 通讯的协议家族

  • PF_INET IPv4互联网协议族。
  • PF_INET6 IPv6互联网协议族。
  • PF_LOCAL 本地通信的协议族。
  • PF_PACKET 内核底层的协议族。
  • PF_IPX IPX Novell协议族。

IPv6尚未普及,其它的不常用。

2. type 数据传输的类型

  • SOCK_STREAM 面向连接的socket:
    -----1)数据不会丢失;2)数据的顺序不会错乱;3)双向通道。
  • SOCK_DGRAM 无连接的socket:
    -----1)数据可能会丢失;2)数据的顺序可能会错乱;3)传输的效率更高。

3. protocol 最终使用的协议

protocol:协议类型

  • 通常为 0,表示自动选择与指定域和类型匹配的协议。
  • 对于 AF_INETSOCK_STREAM,默认为 IPPROTO_TCP
  • 对于 AF_INETSOCK_DGRAM,默认为 IPPROTO_UDP

返回值

  • 成功时返回一个新的套接字描述符。
  • 失败时返回 -1,并设置 errno 以指示错误类型。

示例

int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {perror("socket failed");exit(EXIT_FAILURE);
}

在IPv4网络协议家族中,数据传输方式为SOCK_STREAM的协议只有IPPROTO_TCP,数据传输方式为SOCK_DGRAM的协议只有IPPROTO_UDP

本参数也可以为0

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);    // 创建tcp的sock
socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);    // 创建udp的sock

三、TCP 和 UDP的区别

TCP(传输控制协议)和UDP(用户数据报协议)是两种主要的传输层协议,用于网络通信。它们有各自的优缺点和适用场景。

1. TCP(传输控制协议)

  1. 连接导向

    • TCP是面向连接的协议,在传输数据之前需要建立连接(三次握手)。
    • 连接建立后,双方可以进行可靠的数据传输。
  2. 可靠性

    • 提供可靠的数据传输,确保数据包按顺序到达并且没有丢失或重复。
    • 使用确认机制、重传机制和校验和来保证数据的完整性和正确性。
  3. 流量控制

    • 具有流量控制和拥塞控制机制,防止网络拥塞和发送方发送速度过快。
    • 使用滑动窗口协议来管理流量控制。
  4. 传输速度

    • 由于其可靠性和流量控制机制,TCP的传输速度相对较慢,但可靠性高。
  5. 头部开销

    • TCP头部较大,通常为20字节(不包括可选字段)。
  6. 适用场景

    • 适用于需要高可靠性的数据传输场景,如网页浏览(HTTP/HTTPS)、文件传输(FTP)、电子邮件(SMTP)、远程登录(SSH)等。

2. UDP(用户数据报协议)

  1. 无连接

    • UDP是无连接的协议,在传输数据之前不需要建立连接。
    • 数据包独立发送,无需维护连接状态。
  2. 不可靠性

    • 提供不可靠的数据传输,不保证数据包的顺序、无丢失和无重复。
    • 发送数据后不确认是否到达目的地,不重传丢失的数据包。
  3. 无流量控制

    • UDP没有流量控制和拥塞控制机制,发送速度完全取决于应用程序。
  4. 传输速度

    • 由于没有连接建立、流量控制和重传机制,UDP的传输速度较快,但可靠性低。
  5. 头部开销

    • UDP头部较小,固定为8字节。
  6. 适用场景

    • 适用于对传输速度要求高但对可靠性要求不高的场景,如视频直播、在线游戏、实时语音通话(VoIP)、广播通信等。

3. 总结

特性TCPUDP
连接性面向连接(需要三次握手)无连接
可靠性可靠传输,保证顺序和完整性不可靠传输,不保证顺序和完整性
流量控制有流量控制和拥塞控制无流量控制和拥塞控制
传输速度较慢较快
头部开销较大(20字节,不包括可选字段)较小(8字节)
适用场景需要高可靠性的应用需要高速度的应用

示例应用

  • TCP:HTTP/HTTPS、FTP、SMTP、SSH、Telnet
  • UDP:DNS查询、DHCP、TFTP、在线游戏、视频流、实时音频

了解TCP和UDP的区别及其适用场景,可以帮助开发人员在实际网络编程中选择合适的传输层协议,以满足不同应用的需求。

相关文章:

Socket 函数详细讲解(Socket编程步骤、socket函数、TCP和UDP的区别)

Socket 函数详细讲解和 C 示例 一、 Socket 基本概念1. Socket 简介2. Socket 编程步骤3. TCP Socket 编程示例服务器端客户端 4. 详细说明 二、 socket 函数1. domain 通讯的协议家族2. type 数据传输的类型3. protocol 最终使用的协议返回值示例 三、TCP 和 UDP的区别1. TCP&…...

【限免】杂波环境下线性调频脉冲、巴克码、频率步进脉冲雷达MTI、脉冲压缩【附MATLAB代码】

来源&#xff1a;微信公众号&#xff1a;EW Frontier 本代码主要模拟杂波环境&#xff08;飞机、地杂波、鸟类信号&#xff09;下&#xff0c;Chirp脉冲、巴克码脉冲、频率步进脉冲雷达信号的脉冲压缩及MTI、​匹配滤波。 MATLAB主代码 % 定义参数 fs 1000; % 采样率 T 1; …...

前端最新面试题(Javascript模块篇)

目录 1 数据类型基础 1.1 JS内置类型 1.2 null和undefined区别 1.3 null是对象吗?为什么? 1.4 1.toString()为什么可以调用? 1.5 0.1+0.2为什么不等于0.3?如何让其相等 1.6 如何理解BigInt 1.7 JS 整数是怎么表示的 1.8 Number() 的存储空间是多大?如果后台发送了…...

Android11热点启动和关闭

Android官方关于Wi-Fi Hotspot (Soft AP) 的文章&#xff1a;https://source.android.com/docs/core/connect/wifi-softap?hlzh-cn 在 Android 11 的WifiManager类中有一套系统 API 可以控制热点的开和关&#xff0c;代码如下&#xff1a; 开启热点&#xff1a; // SoftApC…...

DI-engine强化学习入门(三)DI-ZOO强化学习环境搭建与示例运行——Atari

Atari是一家知名的电子游戏公司&#xff0c;成立于1972年&#xff0c;是早期电子游戏产业的先驱之一。在强化学习领域&#xff0c;提到Atari通常指的是Atari 2600游戏的一系列环境&#xff0c;这些环境是用于开发和测试强化学习算法的标准平台。 Atari 2600 强化学习环境概述 …...

【一站式学会Kotlin】第十节:kotlin 语言的可控性特点和安全调用操作符

作者介绍: 百度资深Android工程师T6,在百度任职7年半。 目前:成立赵小灰代码工作室,欢迎大家找我交流Android、微信小程序、鸿蒙项目。= 一:通俗易懂的人工智能教程:https://www.captainbed.cn/nefu/ 点一下,打开新世界的大门。 二:【一站式学会Kotlin】免费领取:作者…...

PaddleClas 指定gpu

在使用PaddleClas进行模型训练或预测时&#xff0c;如果您想要指定使用特定的GPU设备&#xff0c;可以通过CUDA_VISIBLE_DEVICES环境变量来设置。 在命令行中设置GPU的方法如下&#xff1a; # 指定第0号GPU export CUDA_VISIBLE_DEVICES0 # 之后运行PaddleClas的命令&#xf…...

langchain进阶一:特殊的chain,轻松实现对话,与数据库操作,抽取数据,以及基于本地知识库的问答

特殊的chain langchain中的Chain有很多,能够轻松实现部分需求,极致简化代码,但是实现效果与模型智慧程度有关 会话链 效果与LLMChain大致相同 javascript 复制代码 from langchain.chains import ConversationChain from langchain_community.llms import OpenAI conversat…...

【Spring Boot】响应式编程

响应式编程 1.WebFlux2.比较 MVC 和 WebFlux2.1 工作方式2.2 Spring MVC 与 Spring WebFlux 的区别2.3 使用 WebFlux 的好处 3.Mono 和 Flux3.1 Mono 和 Flux 是什么3.2 Mono 和 Flux 的区别 4.开发 WebFlux 的流程4.1 注解式开发流程4.2 响应式开发流程 5.用注解式开发实现 He…...

【C++练级之路】【Lv.21】C++11——列表初始化和声明

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、列表初始化1.1 内置类型1.2 结构体或类1.3 容器 二、声明2.1 auto2.2 decltype2.3 nullptr 三、STL的…...

输入一串字符串,前中后都有*号,去掉字符串中间和后面的*号,保留前面的*号和字母

#include <stdio.h> void fun(char* a) {//***df**fr*fg***int i 0, j 0,n0,m0;char* p;p a;while (p[i] ! \0){i;//i是一共的字符的个数}printf("%d\n",i);while (a[n] *){n;//计算字母前的*的个数}printf("%d\n", n);m n;for (j n; j < …...

【机器学习与大模型】驱动下的应用图像识别与处理

摘要&#xff1a; 本文深入探讨了机器学习在图像识别与处理领域的应用&#xff0c;特别是在大模型的推动下所取得的巨大进展。详细阐述了图像识别与处理的基本原理、关键技术&#xff0c;以及机器学习算法和大模型如何提升其性能和准确性。通过实际案例分析了其在多个领域的广泛…...

24李林跌落神坛,880还刷吗?还是换1000、900、660?

“李林今年跌落神坛了&#xff01;” “全是固定题型没新题&#xff0c;结果今年考的全是新题。” 880是“老真题的神”&#xff0c; 遇到24年&#xff0c;冷门考点多&#xff0c;计算量又大&#xff0c;就不灵了。 但“老真题”&#xff0c;还是得刷。就像往年真题是要刷的…...

数据库漫谈-sybase

sybase就是“system”加“database”&#xff0c;代表着信息系统的底层。Sybase公司很早就推出了关系数据库产品&#xff08;1987年5月推出的Sybase SQLServer1.0&#xff09;。Sybase也是第一个提出Client/Server 体系结构的思想&#xff0c;并率先在Sybase SQLServer 中实现。…...

Springboot开发 -- Postman 调试类型详解

引言 在 Spring Boot 应用开发过程中&#xff0c;接口测试是必不可少的一环。Postman 作为一款强大的 API 开发和测试工具&#xff0c;可以帮助开发者轻松构建、测试和管理 HTTP 请求。本文将为大家介绍如何在 Spring Boot 开发中使用 Postman 进行接口测试。 一、准备工作 安…...

Windows 后台启动jar并且输出日志到特定日志

Windows 后台启动jar并且输出日志到特定日志 javaw -Dfile.encodingutf-8 -jar xxx.jar >log.log 2>&1 &日志输出以年月日格式显示 javaw -Dfile.encodingutf-8 -jar xxx.jar >log_%DATE:~0,4%-%DATE:~5,2%-%DATE:~8,2%_%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2…...

垃圾回收机制及算法

文章目录 概要对象存活判断引用计数算法可达性分析算法对象是否存活各种引用 垃圾收集算法分代收集理论复制算法标记清除算法标记-整理算法 概要 垃圾收集&#xff08;Garbage Collection&#xff0c; 下文简称GC&#xff09;&#xff0c;其优缺点如下&#xff1a; 优点&#…...

蓝桥杯-暴力搜索BFS+DFS

九九乘法表挂毯 问题描述&#xff1a; 在一个古老的城堡里&#xff0c;一位名为 Alex 的少年发现了一幅巨大的九九乘法表挂毯。挂毯被划分成了9x9的方格&#xff0c;每个方格上写着相应的乘积。Alex 想象自己站在数值为1的方格上&#xff0c;他的目标是到达数值为 81 的方格。…...

巧用count与count()

在C#中&#xff0c;talentInnoPfChains.Count() 和 talentInnoPfChains.Count 的性能差异主要取决于 talentInnoPfChains 的类型。这里有两种可能的情况&#xff1a; 如果 talentInnoPfChains 是一个实现了 ICollection<T> 接口的集合&#xff08;如 List<T>, Hash…...

MongoDB 覆盖索引查询:提升性能的完整指南

MongoDB 覆盖索引查询是一种优化数据库查询性能的技术&#xff0c;它通过创建适当的索引&#xff0c;使查询可以直接从索引中获取所需的数据&#xff0c;而无需访问实际的文档数据。这种方式可以减少磁盘 I/O 和内存消耗&#xff0c;提高查询性能。 基本语法 在 MongoDB 中&a…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...