关于自定义协议利用SOCKET传输文件

goujunfu0822 2014-05-06 03:01:25
首先要说明,因为我不会去关闭服务器上的流和客户端的流,因为我想让客户端利用一个socket随意传递数据,不限次数
不能关闭流,那么不能通过while判断read是否返回-1来判断文件是否传递完毕。所以我采用提前告诉客户端文件大小,来决定服务器和客户端的write和read次数,但是却造成服务器发送的文件还没发送完,客户端就已经使用完所有read次数了
为了方便大家看,我截取重要代码,下面这里是服务器发送文件的代码
private void sendFile(String filePath, BufferedWriter bw)
throws IOException {
File file = new File(filePath);
if (!file.exists()) {
return;
}
// 文件读取流
BufferedInputStream bin = new BufferedInputStream(
new FileInputStream(file));

// 发送Head
bw.write("file,"+file.length()+"\n");
bw.flush();
byte[] b = new byte[8192];
int i=0;
int sum;
while ((sum = bin.read(b)) != -1) {
out.write(b,0,sum);
System.out.println("server"+i+"====>>>"+sum+"====>"+(file.length()));
i++;
out.flush();
}
out.flush();
System.out.println("传输完毕");
bin.close();
}
}

这里是客户端接受文件代码
long count = Long.parseLong(data.split(",")[1]);
long time;
if (count % 8192 == 0)
time = count / 8192;
else
time = count / 8192 + 1;

BufferedOutputStream bout = new BufferedOutputStream(
new FileOutputStream("G:\\text.chm"));

int sz;
byte[] b = new byte[8192];
for (int i = 0; i < time; i++) {
sz = in.read(b);
bout.write(b, 0, sz);
System.out.println("client:"+i + "/" + time+"======>>"+sz);
}

System.out.println("下载完成");
bout.flush();
bout.close();
...全文
638 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
vnvlyp 2014-05-16
  • 打赏
  • 举报
回复
一个好的文件传输协议是需要完善的实现的,你这个协议太粗糙了吧。。
请参考FTP,TFTP协议。
附一个TFTP协议的报文格式可以参考
chichenzhe 2014-05-16
  • 打赏
  • 举报
回复
引用 2 楼 goujunfu0822 的回复:
[quote=引用 1 楼 rumlee 的回复:] 你把数组定义成8192,不代表你每次读取的字节就是8192,这是两回事,每次读取你都要根据read方法返回值才能够确定实际读取了多少个字节。
那我应该如何确定客户端需要read多少次,从这边的控制台输出结果来看,客户端好像每次还是读取了8192但是还是没有读取完,服务器最后一次发送的字节数是6000+,但是客户端最后的读取字节数还是8192,是否在我不知道的时候,服务器的write在我没调用flush的时候又悄悄发送了数据[/quote] socket 要写得比较好 是个庞大的话题. 虽然有mina等开源jar可用 但依然是个庞大的话题. 所以.. 目前你最需要的还是补足这方面知识. 1.你不能确定客户端read多少次. 根据不同的 mtu 以及包的转发规则, 最后一个 8192的数据会分成多少个碎片到达终端很难确定. 2.服务器不会神出鬼没般的给客户端随意发数据过去. (这又不是神话传说) 3.如果你仅仅是要定关于 8192字节这么个简单的协议的话. 我建议你这么干: *) 服务器不管什么情况下(无论需要不需要发这么多数据) 都固定的一次发8192字节. 然后客户端while循环去读这8192 4.如果想写得比较好我建议你这么干: *) 定义一个包长在前2个字节里(short) *) 客户端先接这个short, 再while循环去读取这 short个字节.
woshilisao 2014-05-16
  • 打赏
  • 举报
回复
长连接要注意粘包、分包的问题
goujunfu0822 2014-05-06
  • 打赏
  • 举报
回复
引用 1 楼 rumlee 的回复:
你把数组定义成8192,不代表你每次读取的字节就是8192,这是两回事,每次读取你都要根据read方法返回值才能够确定实际读取了多少个字节。
那我应该如何确定客户端需要read多少次,从这边的控制台输出结果来看,客户端好像每次还是读取了8192但是还是没有读取完,服务器最后一次发送的字节数是6000+,但是客户端最后的读取字节数还是8192,是否在我不知道的时候,服务器的write在我没调用flush的时候又悄悄发送了数据
rumlee 2014-05-06
  • 打赏
  • 举报
回复
你把数组定义成8192,不代表你每次读取的字节就是8192,这是两回事,每次读取你都要根据read方法返回值才能够确定实际读取了多少个字节。
lliiqiang 2014-05-06
  • 打赏
  • 举报
回复
提前获知文件大小告诉客户端.
内容概要:本文围绕“阶梯碳下考虑P2G-CCS与供需灵活响应的IES优化调度”展开,基于Matlab平台构建综合能源系统(IES)在阶梯式碳交易机制下的优化调度模型。研究深度融合电制气(P2G)与碳捕集、利用与封存(CCS)技术,结合需求侧灵活响应机制,旨在提升系统的低碳运行能力与经济性。通过建立多能流耦合的优化模型,协调电力、天然气、热力等多种能源形式的协同调度,有效降低系统碳排放强度,并借助YALIMIP工具包调用求解器进行高效求解。文档提供了完整的代码实现、模型构建流程与结果分析方法,涵盖从问题建模到仿真实现的全过程,具备较强的可复现性与科研参考价值。; 适合人群:具备电力系统、能源系统或优化建模相关背景的研究生、高校教师及工程技术人员,尤其适合从事综合能源系统、碳减排策略、P2G与CCS技术集成研究的专业人员,需熟练掌握Matlab编程与基本的数学规划知识。; 使用场景及目标:①用于研究阶梯式碳交易政策下综合能源系统的低碳经济调度策略;②支撑P2G-CCS技术与需求响应机制在IES中的仿真集成与性能评估;③作为撰写高水平学术论文(如EI/SCI收录)的技术基础与复现资源,推动碳中和背景下能源系统优化方向的创新研究。; 阅读建议:建议结合百度网盘提供的完整代码与资料包,按照模块逐步调试程序,重点理解目标函数的设计逻辑、碳交易成本的建模方式、约束条件的数学表达及求解器的配置方法,同时关注多能耦合设备的建模细节,配合公众号“荔枝科研社”获取持续的技术支持与案例拓展。
内容概要:本文系统研究了基于卷积神经网络(CNN)与支持向量机(SVM)融合的CNN-SVM混合模型在数据分类预测中的应用,尤其聚焦于工业故障识别领域。通过Matlab平台实现,该方法首先利用CNN强大的多层次特征提取能力对原始输入数据进行深度特征学习,自动捕获关键局部模式与空间结构信息,随后将提取的高层特征作为输入传递至SVM分类器,借助SVM在高维空间中小样本条件下卓越的分类性能与泛化能力完成最终判别任务。文中详尽阐述了模型的整体架构设计、网络参数配置、训练优化流程及特征迁移机制,充分结合了深度学习在特征表达上的优势与传统机器学习在分类决策上的稳健性。实验部分通过实际故障数据集验证了该混合模型相较于单一CNN或SVM模型在分类准确率、鲁棒性和抗过拟合能力方面的显著提升,证明了其在复杂故障诊断任务中的有效性与先进性; 适合人群:具备一定机器学习与深度学习理论基础,熟悉Matlab编程环境,从事故障诊断、模式识别、智能制造、电力系统监控或工业数据分析等相关领域的研究生、科研人员及工程技术开发者; 使用场景及目标:① 应用于旋转机械、电力设备、航空航天等领域的多类别故障识别与状态监测;② 掌握深度特征提取与传统分类器融合的技术路径,提升小样本、高噪声环境下数据分类的精度与可靠性;③ 为撰写高水平学术论文、开展科研项目或工程实践提供可复现的算法框架与完整代码支持; 阅读建议:读者应深入理解CNN与SVM的协同工作机制,重点分析特征提取层与分类层之间的接口设计,建议动手运行并调试所提供的Matlab代码,尝试在不同数据集上进行迁移实验与参数调优,以全面掌握该混合模型的应用技巧与优化策略。

62,622

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧