当前位置: 首页 > 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…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...