服务端与多客户端照片的传输,recv,send
一、照片传输
server.c
/*===============================================
* 文件名称:server.c
* 创 建 者:
* 创建日期:2025年02月07日
* 描 述:
================================================*/
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
int main(int argc, char *argv[])
{ signal(SIGPIPE,SIG_IGN);//创建套接字int sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd < 0){perror("socket");exit(-1);}printf("socket success!\n");//绑定本机ip地址和端口号struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(6666);saddr.sin_addr.s_addr = inet_addr("192.168.6.44");int s_len = sizeof(saddr);int ret = bind(sockfd,(struct sockaddr *)&saddr,s_len);if(ret < 0){perror("bind");exit(-1);}printf("bind success\n");//设置监听套接字ret = listen(sockfd,10);if(ret < 0){perror("listen");exit(-1);}printf("listen success\n");//等待客户端连接printf("wait for a new client\n");struct sockaddr_in caddr;memset(&caddr,0,sizeof(caddr));int c_len = sizeof(caddr);while(1){int connfd = accept(sockfd,(struct sockaddr *)&caddr,&c_len);if(connfd < 0){perror("accept");exit(-1);}printf("link success\n");printf("client_ip = %s client_port = %d\n",inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));int fd = open("1.jpg",O_RDONLY);if(-1 == fd){perror("open");close(connfd);continue;}char data[1024],len[5];int ret;//每次读取文件的实际长度while(1){//读取文件内容ret = read(fd,data,1024);//将长度变成字符串sprintf(len,"%d",ret);//向客户端发送这一次的长度if(-1 == write(connfd,len,5))break;if(0 == ret)break;//向客户端发送这一次的正文if(-1 == write(connfd,data,ret))break;}close(fd);close(connfd);}return 0;
}
client.c
/*===============================================
* 文件名称:client.c
* 创 建 者:
* 创建日期:2025年02月07日
* 描 述:
================================================*/
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc, char *argv[])
{if(argc < 3){printf("Usage:%s <IP><port>\n",argv[0]);exit(-1);}//创建套接字int sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd < 0){perror("socket");exit(-1);}printf("socket success!\n");//发起连接struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[2]));saddr.sin_addr.s_addr = inet_addr(argv[1]);int s_len = sizeof(saddr);int ret = connect(sockfd,(struct sockaddr *)&saddr,s_len);if(ret < 0){perror("connect");exit(-1);}int fd = open("1.jpg",O_WRONLY|O_CREAT,0777);if(-1 == fd){perror("open");exit(-1);}char data[1024],len[5];int size;while(1){//固定读取5字节代表这次传输文件正文长度ret = read(sockfd,len,5);if(0 >= ret)break;size = atoi(len);if(0 == size){puts("over");break;}//读取正文ret = read(sockfd,data,size);if(0 >= ret)break;write(fd,data,size);}//关闭套接字close(fd);close(sockfd);return 0;
}
二、循环服务器模型
服务器一次只能处理一个连接请求,只有将对应客户端的请求处理完成然后与之断开连接再与下一个客户端建立连接。
listenfd = socket(...);bind(...);listen(...);while(1){int confd = accept(...);while(1){//处理对应的客户端请求.}}
三、TCP粘包
TCP粘包:tcp的数据包边界不明显。
解决方案:
-
遍历每个字节寻找消息的格式头解析;
-
保证完整接收期望的数据
1: char buf[1024]; int count, size, ret; //count:实际读取字节数 size:期望读取字节数 ...count = 0;while(count < size){ret = read(confd, buf+count, size-count);count += ret;}2:在服务器每次发送完整数据后睡眠一段时间3:while(size > recv(confd, buf, size, MSG_PEEK));recv(confd, buf, size, 0);4:recv(confd, buf, size, MSG_WAITALL); //不稳定,会被信号影响
四、recv/send函数详解
recv/send函数专门用来进行网络通信的函数
recv:接收
#include <sys/types.h>
#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);
返回值:出错-1 对端关闭连接0 >0表示实际读取的字节数
int sockfd: 通信套接字
void *buf: 接收数据存放的缓冲区
size_t len: 期望接收的字节数
int flags: 0与read一样MSG_OOB:带外数据(紧急数据:只有1个字节有效并且一个套接字至多只有一个紧急数据)MSG_PEEK: 查询缓冲区数据但是不会取走对应数据MSG_DONTWAIT:非阻塞模式MSG_WAITALL:保证读到期望字节数的数据
send:发送
#include <sys/types.h>
#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);
返回值:出错-1 >0表示实际发送的字节数
int sockfd: 通信套接字
void *buf: 发送数据存放的缓冲区首地址
size_t len: 发送字节数
int flags: 0与write一样MSG_OOB:带外数据(紧急数据:只有1个字节有效并且一个套接字至多只有一个紧急数据)MSG_NOSIGNAL:当对端连接断开时发送数据不产生SIGPIPE信号
五、并发服务器模型
服务器可以同时处理多个客户端的请求,就是并发服务器。
1、多线程实现并发服务器模型
将每个客户端的请求都创建对应线程去处理
void *client_handler(void *arg);int main()
{listenfd = socket(...);bind(...);listen(...);while(1){int confd = accept(...);pthread_create(.., .., client_handler, (void *)confd);...;}
}
相关文章:
服务端与多客户端照片的传输,recv,send
一、照片传输 server.c /* * 文件名称:server.c * 创 建 者: * 创建日期:2025年02月07日 * 描 述: */ #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h…...
JS实现灯光闪烁效果
在 JS中,我们可以实现灯光闪烁效果,这里主要用 setInterval 和 clearInterval 两个重要方法。 效果图 源代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>灯闪烁效果<…...
SpringCloud面试题----Nacos和Eureka的区别
功能特性 服务发现 Nacos:支持基于 DNS 和 RPC 的服务发现,提供了更为灵活的服务发现机制,能满足不同场景下的服务发现需求。Eureka:主要基于 HTTP 的 RESTful 接口进行服务发现,客户端通过向 Eureka Server 发送 HT…...
verilog练习:i2c slave 模块设计
文章目录 前言1. 结构2.代码2.1 iic_slave.v2.2 sync.v2.3 wr_fsm.v2.3.1 状态机状态解释 2.4 ram.v 3. 波形展示4. 建议5. 资料总结 前言 首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。 下面将是我本次设计的一些局部设计汇总,如果对读者有…...
3.5 Go(特殊函数)
目录 一、匿名函数 1、匿名函数的特点: 2、匿名函数代码示例 2、匿名函数的类型 二、递归函数 1. 递推公式版本 2. 循环改递归 三、嵌套函数 1、嵌套函数用途 2、代码示例 3、作用域 & 变量生存周期 四、闭包 1、闭包使用场景 2、代码示例 五、De…...
Android的MQTT客户端实现
在 Android 平台上实现 MQTT 客户端的完整技术方案,涵盖基础实现、安全连接、性能优化和最佳实践: 一、技术选型与依赖配置 推荐库 Eclipse Paho Android Service(官方维护,支持后台运行) gradle 复制 // build.gradl…...
国产编辑器EverEdit - 编辑辅助功能介绍
1 编辑辅助功能 1.1 各编辑辅助选项说明 1.1.1 行号 打开该选项时,在编辑器主窗口左侧显示行号,如下图所示: 1.1.2 文档地图 打开该选项时,在编辑器主窗口右侧靠近垂直滚动条的地方显示代码的缩略图,如下图所示&…...
WPF 在后台使TextBox失去焦点的方法
在软件设计开发的时候,偶尔会遇到在后台xaml.cs后台中,要将TextBox控件的焦点取消或者使TextBox控件获取焦点,下面介绍讲述一种简单的“只让特定的 TextBox 失去焦点”方法: 前端xaml代码示例: <StackPanel Orientation"…...
工作案例 - python绘制excell表中RSRP列的CDF图
什么是CDF图 CDF(Cumulative Distribution Function)就是累积分布函数,是概率密度函数的积分。CDF函数是一个在0到1之间的函数,描述了随机变量小于或等于一个特定值的概率。在可视化方面,CDF图表明了一个随机变量X小于…...
CTF SQL注入学习笔记
部分内容来自于SQL注入由简入精_哔哩哔哩_bilibili SQL语句 1.mysqli_error():返回最近调用函数的最后一个错误描述 语法:mysqli_error(connection) 规定要使用的Mysql连接; 返回一个带有错误描述的字符串。如果没有错误发生则返回 "" 2…...
element-plus el-tree-select 修改 value 字段
element-plus el-tree-select 修改 value 字段 ,不显示label 需要注意两个地方: <el-tree-select v-model"value" :data"data" multiple :render-after-expand"false" show-checkbox style"width: 240px" …...
基于javaweb的SpringBoot小区智慧园区管理系统(源码+文档+部署讲解)
🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 运行环境开发工具适用功能说明 运行环境 Java≥8、MySQL≥5.7、Node.js≥14 开发工具 后端:eclipse/idea/myeclipse…...
SpringBoot学习之shardingsphere实现分库分表(基于Mybatis-Plus)(四十九)
一、shardingsphere介绍 ShardingSphere是一款起源于当当网内部的应用框架。2015年在当当网内部诞生,最初就叫ShardingJDBC。2016年的时候,由其中一个主要的开发人员张亮,带入到京东数科,组件团队继续开发。在国内历经了当当网、电信翼支付、京东数科等多家大型互联网企业的…...
23.PPT:校摄影社团-摄影比赛作品【5】
目录 NO12345 NO6 NO7/8/9/10 单元格背景填充表格背景填充文本框背景填充幻灯片背景格式设置添加考生文件夹下的版式 NO12345 插入幻灯片和放入图片☞快速:插入→相册→新建相册→文件→图片版式→相框形状→调整边框宽度左下角背景图片:视图→…...
Baumer工业相机堡盟相机的相机传感器芯片清洁指南
Baumer工业相机堡盟相机的相机传感器芯片清洁指南 Baumer工业相机1.Baumer工业相机传感器芯片清洁工具和清洁剂2.Baumer工业相机传感器芯片清洁步骤2.1、准备步骤2.2、清洁过程1.定位清洁工具2.清洁传感器3.使用吹风装置 Baumer工业相机传感器芯片清洁的优势设计与结…...
Spring Boot 整合 JPA 实现数据持久化
目录 前言 一、JPA 核心概念与实体映射 1. 什么是 JPA? 2. JPA 的主要组件 3. 实体映射 4. 常见的字段映射策略 二、Repository 接口与自定义查询 1. 什么是 Repository 接口? 2. 动态查询方法 3. 自定义查询 4. 分页与排序 三、实战案例&…...
快速在wsl上部署学习使用c++轻量化服务器-学习笔记
知乎上推荐的Tinywebserver这个服务器,快速部署搭建,学习c服务器开发 仓库地址 githubhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServerhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServer 在…...
【R语言】数据操作
一、查看和编辑数据 1、查看数据 直接打印到控制台 x <- data.frame(a1:20, b21:30) x View()函数 此函数可以将数据以电子表格的形式进行展示。 用reshape2包中的tips进行举例: library("reshape2") View(tips) head()函数 查看前几行数据&…...
MariaDB MaxScale实现mysql8主从同步读写分离
一、MaxScale基本介绍 MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 二、MaxScale实验环境 中间件192.168.121.51MaxScale…...
【python】简单的flask做页面。一组字母组成的所有单词。这里的输入是一组字母,而输出是所有可能得字母组成的单词列表
目录结构如下: https://github.com/kaede316/Pythons_pj.git 效果: 后续可扩展为工具网站: 更新 2025.02.09 1、增加等间距制作人 时间信息 2、增加判断润年的功能...
数字永生:将意识上传云端的技术与伦理极限
——一个软件测试从业者的技术解构与风险分析各位同行,当你看到“数字永生”这四个字时,脑海里浮现的是什么?是马斯克口中2045年即将实现的意识上传,还是《黑镜》里那些被困在虚拟牢笼中的数字灵魂?作为一个每天与需求…...
深入浅出MCP:从零开始的完整学习指南(保姆级教程)
手把手带你理解MCP是什么、怎么用、如何开发,每个步骤都有详细说明 写在前面 很多朋友看完MCP的介绍还是一头雾水:“这到底是什么?跟我有什么关系?我该怎么用?” 别急,这篇文章我会用最通俗的方式&#x…...
模拟工程师必备:口袋参考指南的实战价值与核心应用
1. 为什么每个硬件工程师都需要一本“口袋参考书”?前几天整理书桌,翻出来一本2016年从TI官网下载打印的《模拟工程师口袋参考指南》,纸张已经有点发黄,边角也卷了。但就是这么一本薄薄的小册子,从毕业到现在ÿ…...
家庭影院系统构建指南:从流媒体技术到硬件选型
1. 疫情下的娱乐变局:从影院到客厅的深度迁移作为一名长期关注消费电子与家庭娱乐领域的从业者,我亲历了过去几年行业最剧烈的震荡。疫情像一只无形的手,强行按下了社会运行的暂停键,却又为另一个赛道按下了加速键。当电影院的大门…...
Steam Cron Studio:可视化配置生成器,为AI代理打造Steam自动化任务
1. Steam Cron Studio:一个为AI代理量身定制的Steam自动化配置生成器如果你是一个Steam重度用户,同时又对AI代理(AI Agent)和自动化工具感兴趣,那么你很可能和我一样,曾经被一个看似简单实则繁琐的问题困扰…...
为Claude Code配置Taotoken解决封号与Token不足困扰
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为Claude Code配置Taotoken解决封号与Token不足困扰 应用场景类,针对频繁使用Claude Code作为编程助手但受限于官方限制…...
如何解决QQ音乐下载的歌曲在其他设备上无法播放的问题
如何解决QQ音乐下载的歌曲在其他设备上无法播放的问题 【免费下载链接】qmcflac2mp3 直接将qmcflac文件转换成mp3文件,突破QQ音乐的格式限制 项目地址: https://gitcode.com/gh_mirrors/qm/qmcflac2mp3 你是否曾经在QQ音乐下载了喜欢的歌曲,却发现…...
手把手教你配置Synopsys DesignWare PCIe控制器:从寄存器读写到ATU映射实战
Synopsys DesignWare PCIe控制器深度配置指南:从寄存器操作到DMA通信实战 1. PCIe控制器基础架构解析 Synopsys DesignWare PCIe控制器作为业界广泛采用的IP核,其架构设计充分考虑了灵活性和可扩展性。控制器核心由以下几个关键模块组成: Tra…...
构建个人技能库:从代码片段到可复用技能单元的设计与实践
1. 项目概述:当代码遇上魔法,技能库的构建哲学在软件开发的日常里,我们常常会羡慕那些“魔法师”般的同事:他们似乎总能信手拈来一段代码,优雅地解决一个棘手问题;或者拥有一个私人的“百宝箱”,…...
基于图特征选择与XGBoost的电动公交预测性维护模型构建
1. 项目概述:从数据洪流到精准预警的挑战在电动公交的日常运营中,车辆控制器局域网(CAN)总线每秒都在产生海量的传感器数据,从电池电压、电机温度到刹车片厚度,这些数据流如同车辆的“生命体征”。预测性维…...
