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和多路复用是非常重要的。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【AIGC】AI时代的数据安全:使用ChatGPT时的自查要点

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;法律法规背景中华人民共和国保守秘密法中华人民共和国网络安全法中华人民共和国个人信息保护法遵守法律法规的重要性 &#x1f4af;ChatGPT的数据使用特点ChatGPT数据安全…

学校在线学习作业批改教学管理平台的设计与实现SpringBoot+VUE

目录 一、项目背景及目标 二、技术选型 三、系统功能模块设计 四、关键技术实现 五、总结 在当今社会上&#xff0c;随着社会的发展和进步&#xff0c;对于现代的学生来说网络课程已经广泛应用于学校的每个角落&#xff0c;而一个课程教学管理平台对于现如今的课堂是不可缺…

资源《Arduino 扩展板4-单游戏摇杆》说明。

资源链接&#xff1a; Arduino 扩展板4-单游戏摇杆 1.文件明细&#xff1a; 2.文件内容说明 包含&#xff1a;AD工程、原理图、PCB。 3.内容展示 4.简述 该文件为PCB工程&#xff0c;采用AD做的。 该文件打板后配合Arduino使用&#xff0c;属于Arduino的扩展板。 该文件…

华为资源分享

紫光云文档中心提供弹性计算服务文档https://www.unicloud.com/document/product/ElasticComputeService/index.html报文格式华为报文格式资料Info-Finder&#xff08;在线工具&#xff09; 报文格式华为IP网络电子书华为IP网络相关电子书IP网络系列丛书 - 华为企业业务华为产品…

(C语言贪吃蛇)11.贪吃蛇方向移动和刷新界面一起实现面临的问题

目录 前言 实现效果 支持方向变换 修改默认效果 如何修改 总结 前言 我们上节实现了不需要按下右键就可以是贪吃蛇自发的向右移动&#xff0c;本节我们主要来解决贪吃蛇方向移动和刷新界面所遇到的问题。 实现效果 上图是我们希望实现的效果&#xff0c;我们可以自发地控…

【递归】13. leetcode 1457. 二叉树中的伪回文路径

1 题目描述 题目链接&#xff1a;二叉树中的伪回文路径 2 解答思路 第一步&#xff1a;挖掘出相同的子问题 &#xff08;关系到具体函数头的设计&#xff09; 第二步&#xff1a;只关心具体子问题做了什么 &#xff08;关系到具体函数体怎么写&#xff0c;是一个宏观的过…

已解决:Could not find artifact xxx

已解决&#xff1a;Could not find artifact xxx 文章目录 写在前面问题描述报错原因分析 解决思路解决办法1. 检查依赖声明的正确性2. 检查远程仓库配置3. 检查网络连接4. 清理本地缓存并强制更新5. 手动上传依赖到私有仓库6. 检查本地仓库是否已被损坏 总结 写在前面 在使用…

生信初学者教程(二十三):REF+SVM筛选候选标记物

文章目录 介绍加载R包导入数据准备数据机器学习特征筛选数据分割基础模型Recursive Feature Elimination特征筛选调参最终分类模型测试集验证标记基因输出结果总结介绍 采用了REF(Recursive Feature Elimination) 结合 SVM(Support Vector Machine) 的方法,对差异基因(参…

遥感影像-语义分割数据集:Landsat8云数据集详细介绍及训练样本处理流程

原始数据集详情 简介&#xff1a;该云数据集包括RGB三通道的高分辨率图像&#xff0c;在全球不同区域的分辨率15米。这些图像采集自Lansat8的五种主要土地覆盖类型&#xff0c;即水、植被、湿地、城市、冰雪和贫瘠土地。 KeyValue卫星类型landsat8覆盖区域未知场景水、植被、…

Llama3.2开源:Meta发布1B和3B端侧模型、11B和90B多模态模型

最近这一两周不少互联网公司都已经开始秋招提前批面试了。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友…

司法质量改善:巡回法庭的准自然实验(2000-2022年)(原始数据、计算代码、最终计算结果(Excel和Dta)和参考文献)

巡回法庭的设立背景 最高人民法院自2015年起分批次设立地方巡回法庭&#xff0c;以期改善司法质量&#xff0c;促进司法公正。这种改革措施为研究提供了一个独特的机会&#xff0c;可以通过准自然实验的方法来评估其效果。 2000-2022年司法质量改善&#xff1a;巡回法庭的准自…

ML 系列: (10)— ML 中的不同类型的学习

一、说明 我们之前将机器学习方法分为三类&#xff1a;监督学习、无监督学习和强化学习。机器学习方法可以分为不同的类型&#xff0c;我们将在下面讨论最重要的类型。 二、懒惰学习与急切学习 预先学习的工作原理是使用训练数据构建模型&#xff0c;然后使用此模型评估测试数据…

强大的JVM监控工具

介绍 在生产环境中&#xff0c;经常会遇到各种各样奇葩的性能问题&#xff0c;所以掌握最基本的JVM命令行监控工具还是很有必要的 名称主要作用jps查看正在运行的Java进程jstack打印线程快照jmap导出堆内存映像文件jstat查看jvm统计信息jinfo实时查看和修改jvm配置参数jhat用…

水域救援方案

水域救援是一项在复杂水域环境中进行的紧急救援行动&#xff0c;旨在保障人民生命财产安全、维护社会稳定&#xff0c;并促进相关产业的发展。以下是对水域救援的全面介绍&#xff1a; 一、定义与重要性 水域救援是指在人员在水域中生命受到严重威胁或重要场所、建筑物受到水…

前缀和(8)_矩阵区域和

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 前缀和(8)_矩阵区域和 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 温馨提示:…

MybatisPlus代码生成器的使用

在使用MybatisPlus以后&#xff0c;基础的Mapper、Service、PO代码相对固定&#xff0c;重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成PO、Mapper、Service等相关代码。只不过代码生成器同样要编码使用&#xff0c;也很麻烦。 这里推荐大家使…

华为Nova9开启开发人员选项

默认状态下&#xff0c;华为Nova9的开发人员选项是隐藏的&#xff0c;如下图&#xff1a; 要开启开发人员选项&#xff0c;在“设置→关于手机”中找到“HarmonyOS版本”或者“软件版本”&#xff0c;在版本号上连续点击&#xff0c;每次点击“HarmonyOS版本”和“软件版本”会…

Yocto - 使用Yocto开发嵌入式Linux系统_05 认识Bitbake工具

Meeting the BitBake Tool 通过本章&#xff0c;我们将开始学习 Yocto 项目引擎如何在幕后工作的旅程。正如每一段旅程一样&#xff0c;沟通是至关重要的&#xff0c;因此我们需要理解 Yocto 项目工具所使用的语言&#xff0c;并学习如何充分利用这些工具来实现我们的目标。 Wi…

启用vnc访问Dell 服务器IDRAC 7虚拟控制台

Dell IDRAC 7 版本太老&#xff0c;SSL证书过期&#xff0c;IDRAC的Java和本地远程虚拟机控制台访问不了&#xff0c;怎么办&#xff1f; 可以启用vnc访问IDRAC 虚拟控制台

使用pytdx获取股票行情数据

使用pytdx获取股票行情数据 先展示效果股票清单股票行情 下载通达信金融终端安装插件pytdxpython代码实现同步股票列表同步股票行情 先展示效果 股票清单 总共统计深市与沪市总计5397只股票信息。 股票行情 以下是详细的实现步骤 下载通达信金融终端 此步骤的目的是要获取…