服务端与多客户端照片的传输,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、增加判断润年的功能...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...