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

Linux下Socket编程

1. Socket简介

  • Socket是什么?
    • Socket是一种进程间通信的机制,通过它应用程序可以通过网络进行数据传输。Socket提供了一种跨平台的接口,使得同样的代码可以在不同的操作系统上运行。
  • Socket类型
    • 流式套接字(SOCK_STREAM): 基于TCP协议,提供可靠的双向字节流通信。
    • 数据报套接字(SOCK_DGRAM): 基于UDP协议,提供不可靠的、无连接的通信。
    • 原始套接字(SOCK_RAW): 允许直接访问底层协议,主要用于协议开发或网络分析工具。

2. Socket编程流程

  1. 创建Socket

    int socket(int domain, int type, int protocol);

    • domain: 协议族,常用的有 AF_INET(IPv4) 和 AF_INET6(IPv6)。
    • type: 套接字类型,如 SOCK_STREAMSOCK_DGRAM
    • protocol: 通常设为 0,表示由系统自动选择合适的协议。
  2. 绑定Socket

    int bind(int sockfd, const struct sockaddr *addr,

    socklen_t addrlen);

    • 将Socket与指定的IP地址和端口绑定。
  3. 监听连接

    int listen(int sockfd, int backlog);

    • 服务器端Socket进入监听模式,backlog指定队列中允许的最大未处理连接数。
  4. 接受连接

    int accept(int sockfd, struct sockaddr *addr,

    socklen_t *addrlen);

    • 接受客户端的连接请求,创建一个新的Socket用于与客户端通信。
  5. 连接到服务器

    int connect(int sockfd, const struct sockaddr *addr,

    socklen_t addrlen);

    • 客户端Socket使用此函数连接到服务器。
  6. 发送和接收数据

    • 发送数据:

      ssize_t send(int sockfd, const void *buf, size_t len,

      int flags);

    • 接收数据:

      ssize_t recv(int sockfd, void *buf, size_t len, int flags);

  7. 关闭Socket

    int close(int sockfd);

3. 常用API详解

  • socket()

    • 功能: 创建一个新的Socket。
    • 参数:
      • domain: 地址族,常用的如 AF_INET 表示IPv4地址。
      • type: Socket类型,SOCK_STREAMSOCK_DGRAM
      • protocol: 协议编号,通常为0,由系统选择默认协议。
    • 返回值: 返回新的文件描述符,失败返回 -1
  • bind()

    • 功能: 将Socket绑定到特定的IP地址和端口。
    • 参数:
      • sockfd: 由 socket() 创建的文件描述符。
      • addr: 结构体指针,包含要绑定的地址信息。
      • addrlen: addr 的长度。
  • listen()

    • 功能: 在Socket上监听连接请求。
    • 参数:
      • sockfd: 由 socket() 创建的文件描述符。
      • backlog: 未处理连接的最大数量。
  • accept()

    • 功能: 接受连接请求,创建用于通信的新Socket。
    • 参数:
      • sockfd: 监听套接字。
      • addr: 客户端的地址信息结构体。
      • addrlen: addr 的长度。
  • connect()

    • 功能: 客户端使用此函数连接到服务器。
    • 参数:
      • sockfd: 由 socket() 创建的文件描述符。
      • addr: 服务器的地址信息。
      • addrlen: addr 的长度。
    • 返回值: 成功返回 0,失败返回 -1
  • send() 和 recv()

    • send() 用于向对方发送数据,recv() 用于接收数据。
    • 参数:
      • sockfd: 通信的套接字。
      • buf: 数据缓冲区。
      • len: 缓冲区的大小。
      • flags: 标志位,一般为0。

4. 错误处理

在Socket编程中,经常会遇到错误。通常的做法是检查函数的返回值,若为 -1 则出错,并通过 errno 查看具体的错误原因。以下是一些常见的错误:

  • EADDRINUSE: 地址已被使用。
  • EADDRNOTAVAIL: 无效的地址。
  • ECONNREFUSED: 连接被拒绝。
  • ETIMEDOUT: 连接超时。

5. 高级特性

  • 非阻塞I/O: 使用 fcntl() 设置Socket为非阻塞模式。
  • 多路复用: 使用 select()poll() 等函数同时监听多个Socket。

6. 示例代码

服务器端

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int clientFd;
int serverFd;
void hand(int s){if(2 == s){//7 断开连接close(clientFd);close(serverFd);printf("bye bye 了勾八!\n");exit(1);}
}int main(){signal(2,hand);//1 创建socketserverFd = socket(AF_INET,SOCK_STREAM,0);if(-1 == serverFd) printf("创建socket失败:%m!\n"),exit(-1);printf("创建socket成功!\n");//2 协议地址簇struct sockaddr_in addr={0};addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");//ip地址 注意字符串转网络字节序addr.sin_port = htons(8888);//端口号 用1W左右的  //3 绑定int r = bind(serverFd,(struct sockaddr*)&addr,sizeof addr); if(-1 == r) printf("绑定失败:%m!\n"),close(serverFd),exit(-1);printf("绑定成功!\n");//4 监听r = listen(serverFd,100);//最大容量为100if(-1 == r) printf("监听失败:%m!\n"),close(serverFd),exit(-1);printf("监听成功!\n");//5 接受客户端连接struct sockaddr_in cAddr = {0};//用来接收客户端的协议地址簇int len = sizeof cAddr;clientFd = accept(serverFd,(struct sockaddr*)&cAddr,&len);if(-1 == clientFd) printf("服务器崩溃:%m\n"),close(serverFd),exit(-1);printf("接受客户端连接成功:%d %s %u\n",clientFd,inet_ntoa(cAddr.sin_addr),cAddr.sin_port);//6 通信char buff[1024];int n=0;char temp[1024];while(1){r = recv(clientFd,buff,1023,0);if(r > 0) {buff[r] = '\0';//添加字符串结束符号 '\0'printf("%d:%s\n",r,buff);sprintf(temp,"%d-%s",n++,buff);send(clientFd,temp,strlen(temp),0);}}
}
客户端
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int fd;
void hand(int s){if(2 == s){//5 断开连接close(fd);printf("bye bye !\n");exit(1);}
}int main(){signal(2,hand);//1 创建socketfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == fd) printf("创建socket失败:%m!\n"),exit(-1);printf("创建socket成功!\n");//2 协议地址簇struct sockaddr_in addr={0};addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");//ip地址 注意字符串转网络字节序addr.sin_port = htons(8888);//端口号 用1W左右的  大小端转换//3 连接服务器int r = connect(fd,(struct sockaddr*)&addr,sizeof addr);if(-1 == r) printf("连接服务器失败:%m!\n"),exit(-1);printf("连接服务器成功!\n");//4 通信char buff[1024];char temp[1024];while(1){printf("请输入要发送给服务器的数据:");scanf("%s",buff);r = send(fd,buff,strlen(buff),0);printf("发送%d字节数据到服务器!\n",r);r = recv(fd,temp,1023,0);if(r>0){temp[r] = '\0';printf("服务器回复:%s\n",temp);}}
}

7. 结论

Socket编程是网络通信的基础,通过了解各种Socket API的使用,可以实现复杂的网络应用程序。在实际编程中,掌握错误处理和高级特性如非阻塞I/O和多路复用是非常重要的。

相关文章:

Linux下Socket编程

1. Socket简介 Socket是什么&#xff1f; Socket是一种进程间通信的机制&#xff0c;通过它应用程序可以通过网络进行数据传输。Socket提供了一种跨平台的接口&#xff0c;使得同样的代码可以在不同的操作系统上运行。Socket类型 流式套接字&#xff08;SOCK_STREAM&#xff0…...

Scrapy 爬虫的大模型支持

使用 Scrapy 时&#xff0c;你可以轻松使用大型语言模型 (LLM) 来自动化或增强你的 Web 解析。 有多种使用 LLM 来帮助进行 Web 抓取的方法。在本指南中&#xff0c;我们将在每个页面上调用一个 LLM&#xff0c;从中抽取我们定义的一组属性&#xff0c;而无需编写任何选择器或…...

数据仓库简介(一)

数据仓库概述 1. 什么是数据仓库&#xff1f; 数据仓库&#xff08;Data Warehouse&#xff0c;简称 DW&#xff09;是由 Bill Inmon 于 1990 年提出的一种用于数据分析和挖掘的系统。它的主要目标是通过分析和挖掘数据&#xff0c;为不同层级的决策提供支持&#xff0c;构成…...

Kafka和RabbitMQ区别

RabbitMQ的消息延迟是微秒级&#xff0c;Kafka是毫秒级&#xff08;1毫秒1000微秒&#xff09; 延迟消息是指生产者发送消息发送消息后&#xff0c;不能立刻被消费者消费&#xff0c;需要等待指定的时间后才可以被消费。 Kafka的单机呑吐量是十万级&#xff0c;RabbitMQ是万级…...

go-zero学习

go-zero官网&#xff1a; https://go-zero.dev/docs/tasks 好文&#xff1a; https://blog.csdn.net/m0_63629756/article/details/136599547 视频&#xff1a; https://www.bilibili.com/video/BV18JxUeyECg 微服务基础 根目录下&#xff0c;一个文件夹就是一个微服务。如果微…...

python如何查询函数

1、通用的帮助函数help() 使用help()函数来查看函数的帮助信息。 如&#xff1a; import requests help(requests) 会有类似如下输出&#xff1a; 2、查询函数信息 ★查看模块下的所有函数&#xff1a; dir(module_name) #module_name是要查询的函数名 如&#xff1a; i…...

计算机视觉与深度学习 | 从激光雷达数据中提取地面点和非地面点(附matlab代码)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 激光雷达数据 使用velodyneFileReader函数从P...

vulnhub-wakanda 1靶机

vulnhub&#xff1a;wakanda: 1 ~ VulnHub 导入靶机&#xff0c;放在kali同网段&#xff0c;扫描 靶机在192.168.81.5&#xff0c;扫描端口 四个端口&#xff0c;详细扫描一下 似乎没什么值得注意的&#xff0c;先看网站 就这一个页面&#xff0c;点按钮也没反应&#xff0c;扫…...

Bilibili视频如何保存到本地

Bilibili(哔哩哔哩)作为中国领先的视频分享平台之一&#xff0c;汇聚了大量的优质内容&#xff0c;从搞笑动画、综艺节目到专业教程&#xff0c;应有尽有。许多用户时常会遇到这样的需求&#xff1a;希望将视频保存到本地&#xff0c;方便离线观看或者保存珍藏。由于版权保护等…...

C++之多线程

前言 多线程和多进程是并发编程的两个核心概念,它们在现代计算中都非常重要,尤其是在需要处理大量数据、提高程序性能和响应能力的场景中。 多线程的重要性: 资源利用率:多线程可以在单个进程中同时执行多个任务,这可以更有效地利用CPU资源,特别是在多核处理器上。 性…...

《C++音频降噪秘籍:让声音纯净如初》

在音频处理领域&#xff0c;降噪是一项至关重要的任务。无论是录制音乐、语音通话还是音频后期制作&#xff0c;都需要有效地去除背景噪声&#xff0c;以获得清晰、纯净的音频效果。在 C中实现高效的音频降噪处理&#xff0c;可以为音频应用带来更高的质量和更好的用户体验。本…...

C(十)for循环 --- 黑神话情景

前言&#xff1a; "踏过三界宝刹&#xff0c;阅过四洲繁华。笑过五蕴痴缠&#xff0c;舍过六根牵挂。怕什么欲念不休&#xff0c;怕什么浪迹天涯。步履不停&#xff0c;便是得救之法。" 国际惯例&#xff0c;开篇先喝碗鸡汤。 今天&#xff0c;杰哥写的 for 循环相…...

记录一次docker报错无法访问文件夹,权限错误问题

记录一次docker报错无法访问文件夹&#xff0c;权限错误问题 1. 背景 使用docker安装photoview&#xff0c;为其分配了一个cache目录&#xff0c;用户其缓存数据。在运行过程中&#xff0c;扫描文件后显示如下错误 could not make album image cache directory: mkdir /app/c…...

react crash course 2024(8) useEffect

引入 import { useEffect } from react; useEffect – React 中文文档useEffect 是一个 React Hook&#xff0c;它允许你 将组件与外部系统同步。 有些组件需要与网络、某些浏览器 API 或第三方库保持连接&#xff0c;当它们显示在页面上时。这些系统不受 React 控制&#xff0…...

GEE开发之Modis_NDWI数据分析和获取

GEE开发之Modis_NDWI数据分析和获取 0 数据介绍NDWI介绍MOD09GA介绍 1 NDWI天数据下载2 NDWI月数据下载3 NDWI年数据下载 前言&#xff1a;本文主要介绍Modis下的NDWI数据集的获取。归一化差异水指数 (NDWI) 对植被冠层液态水含量的变化很敏感。它来自近红外波段和第二个红外波…...

netty之NettyClient半包粘包处理、编码解码处理、收发数据方式

前言 Netty开发中&#xff0c;客户端与服务端需要保持同样的&#xff1b;半包粘包处理&#xff0c;编码解码处理、收发数据方式&#xff0c;这样才能保证数据通信正常。在前面NettyServer的章节中我们也同样处理了&#xff1b;半包粘包、编码解码等&#xff0c;为此在本章节我们…...

Linux:文件描述符介绍

文章目录速览 1、虚拟地址空间(1)What&#xff08;什么是虚拟地址空间&#xff09;(2)Why&#xff08;为什么需要虚拟地址空间&#xff09; 2、文件描述符(1)What&#xff08;什么是文件描述符&#xff09;(2)文件描述符表 1、虚拟地址空间 (1)What&#xff08;什么是虚拟地址…...

stm32f103调试,程序与定时器同步设置

在调试定时器相关代码时&#xff0c;注意到定时器的中断位总是置1&#xff0c;怀疑代码有问题&#xff0c;经过增大定时器的中断时间&#xff0c;发现定时器与代码调试并不同步&#xff0c;这一点对于调试涉及定时器的代码是非常不利的&#xff0c;这里给出keil调试stm32使定时…...

《Python编程:从入门到实践》数据可视化

一、项目 数据可视化学习 二、库依赖 matplotlib&#xff0c;pygal&#xff0c; 三、生成数据 1.绘制简单的折线图 import matplotlib.pyplot as pltsquares [1, 4, 9, 16, 25] plt.plot(squares) plt.show() 模块pyplot包含很多用于生成图表的函数。 &#xff08;1&am…...

github/git密钥配置与使用

零、前言 因为要在ubuntu上做点东西&#xff0c;发现git clone 的时候必须输账户密码&#xff0c;后来发现密码是token&#xff0c;但是token一大串太烦了&#xff0c;忙了一天发现可以通过配置 公钥 来 替代 http 的 部署方式。 一、生成 ssh 密钥对 我们先测试下能不能 连接…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...