day04-2发送文件
多用户即时通讯系统04
4.编码实现03
4.6功能实现-发送文件功能实现
4.6.1思路分析
客户端(发送者):
- 先把文件a.jpg读取到客户端的字节数组
- 把文件对应的字节数组封装到message对象[包含文件内容,发送者,接收者]
- 将message对象发送到服务端
服务端:
- 接收到message对象
- 拆解message对象的getteruid,获取接收者用户的通信线程,得到socket
- 把message转发给指定用户
客户端(接收者):
- 在接收到包含有文件的message消息后,读取对应的文件字节数组,将该数组刷出到磁盘
4.6.2代码实现
1. 客户端:
1.修改MessageType接口
在该接口中拓展消息类型
String MESSAGE_FILE_MES = "8";//表示发送文件消息
2.修改Message类
扩展 和文件相关的成员和方法
//进行扩展 和文件相关的成员
private byte[] fileBytes;
private int fileLen = 0;
private String dest ;//将文件传输到哪里
private String src;//源文件路径
public byte[] getFileBytes() {
return fileBytes;
}
public void setFileBytes(byte[] fileBytes) {
this.fileBytes = fileBytes;
}
public int getFileLen() {
return fileLen;
}
public void setFileLen(int fileLen) {
this.fileLen = fileLen;
}
public String getDest() {
return dest;
}
public void setDest(String dest) {
this.dest = dest;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
3.创建FileClientService
该类完成文件传输服务
package qqclient.service;
import qqcommon.Message;
import qqcommon.MessageType;
import java.io.*;
/**
* @author 李
* @version 1.0
* 该类完成 文件传输服务
*/
public class FileClientService {
/**
* @param src 源文件
* @param dest 把该文件传输到对方的哪个目录
* @param senderId 发送用户的id
* @param getterId 接收用户的id
*/
public void sendFileToOne(String src, String dest, String senderId, String getterId) {
//读取src文件--封装-->message对象
Message message = new Message();
message.setMesType(MessageType.MESSAGE_FILE_MES);//设置为文件类型
message.setSender(senderId);
message.setGetter(getterId);
message.setSrc(src);
message.setDest(dest);
//需要将文件读取到程序中
FileInputStream fileInputStream = null;
byte[] fileBytes = new byte[(int) new File(src).length()];//创建一个和文件大小对应的字节数组
try {
fileInputStream = new FileInputStream(src);
fileInputStream.read(fileBytes);//将src的文件读入到程序的字节数组
//将文件对应的字节数组设置成message对象
message.setFileBytes(fileBytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
//关闭流
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("\n" + senderId + " 给 " + getterId + " 发送文件:" + src +
" 到对方的电脑目录: " + dest);
//发送
try {
//从管理线程的集合中,拿到发送者id的线程,
// 在该线程对应的属性socket中得到输出流,将输出流转为对象输出流
ObjectOutputStream oos =
new ObjectOutputStream(ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.修改ClientConnectServerThread类
在在该类中增加接收message消息的类型,并进行相应的操作
else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {
//接收到的是文件类型的消息
//把服务器转发的message对象
System.out.println("\n" + message.getSender() + " 给 " + message.getGetter() +
" 发送文件: " + message.getSrc() + " 到我的电脑的目录:" + message.getDest());
//取出message文件的字节数组,通过文件输出流写出到磁盘
FileOutputStream fileOutputStream =
new FileOutputStream(message.getDest());
fileOutputStream.write(message.getFileBytes());
fileOutputStream.close();
System.out.println("\n保存文件成功~");
}

5.修改QQView
1.在该类中创建FileClientService对象
private FileClientService fileClientService = new FileClientService();//该对象用于文件传输
在该类中通过键盘,将用户输入传送到sendFileToOne方法中

case "4":
System.out.println("请输入你希望发送文件的用户(在线):");
getterId = Utility.readString(50);
System.out.println("请输入要发送文件的路径:(形式如:d:\\xx.jpg)");
String src = Utility.readString(100);
System.out.println("请输入把文件发送到对方电脑下的路径:(形式如:d:\\yy.jpg)");
String dest = Utility.readString(100);
fileClientService.sendFileToOne(src,dest,userId,getterId);
break;
2.服务端
1.修改MessageType接口
在该接口中拓展消息类型
String MESSAGE_FILE_MES = "8";//表示发送文件消息
2.修改Message类
扩展 和文件相关的成员和方法
//进行扩展 和文件相关的成员
private byte[] fileBytes;
private int fileLen = 0;
private String dest ;//将文件传输到哪里
private String src;//源文件路径
public byte[] getFileBytes() {
return fileBytes;
}
public void setFileBytes(byte[] fileBytes) {
this.fileBytes = fileBytes;
}
public int getFileLen() {
return fileLen;
}
public void setFileLen(int fileLen) {
this.fileLen = fileLen;
}
public String getDest() {
return dest;
}
public void setDest(String dest) {
this.dest = dest;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
3.修改ServerConnectClientThread类
在该类的run方法中增加服务端接收文件并转发的业务
else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {
//业务五:客户请求给某用户发送文件
//根据接收的message对象的getter id 获取到对应的线程,将message对象进行转发
//拿到线程
ServerConnectClientThread serverConnectClientThread =
ManageClientThreads.getServerConnectClientThread(message.getGetter());
//获取socket,将socket输出流转为对象流
ObjectOutputStream oos =
new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
//转发
oos.writeObject(message);
}

运行:
1.运行服务端

2.运行客户端,登录两个用户(100,200)

3.用户100 尝试给用户200 发送文件
用户100:

用户200:

用户200的磁盘下成功接收到文件:

4.服务端

功能实现完毕
day04-2发送文件的更多相关文章
- win7系统下的飞秋发送文件失败问题
飞秋发送文件失败这个问题大多数是由防火墙引起的1.检查windows自带的防火墙设置,在左侧的"允许程序通过windows防火墙"查看飞秋是否存在,不存在则增加之,公网.专网都勾选 ...
- 利用Socket远程发送文件
思想: 1.注意使用两个通道,一个普通对象通信通道,另一个纯净的文件字节流通道 2.利用通信通道发送文件请求,新建字节流通道,开始发送文件
- [转]C#网络编程(订立协议和发送文件) - Part.4
本文转自:http://www.tracefact.net/CSharp-Programming/Network-Programming-Part4.aspx 源码下载:http://www.trac ...
- android开发,socket发送文件,read阻塞,得不到文件尾-1
这是我的接收文件代码:开始可以读取到-1,但是现在又读取不到了,所以才加上红色字解决的(注释的代码) File file = new File(mfilePath,"chetou." ...
- tengine lua 开源一 调用内部接口高效发送文件
tengine lua 开源一 调用内部接口高效发送文件 开源自己封装的sendfile 模块,可以高效的通过lua发送文件 源码地址:https://github.com/weinyzhou/Lu ...
- ASP.NET MVC:通过 FileResult 向 浏览器 发送文件
在 Controller 中我们可以使用 FileResult 向客户端发送文件. FileResult FileResult 是一个抽象类,继承自 ActionResult.在 System.Web ...
- socket(TCP)发送文件
一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端: using System; using System.Collections.Generic; using System.Componen ...
- xmpp发送文件
xmpp 文件传输协议: XEP-0096: SI File Transfer:文件传输流初始化协议 XEP-0065: SOCKS5 Bytestreams:带外socks5代理字节流传输协议 XE ...
- C#_Socket网络编程实现的简单局域网内即时聊天,发送文件,抖动窗口。
最近接触了C#Socket网络编程,试着做了试试(*^__^*) 实现多个客户端和服务端互相发送消息 发送文件抖动窗口功能 服务端: using System; using System.Collec ...
- Smack+Openfire 接收和发送文件
转载请注明出处:http://blog.csdn.net/steelychen/article/details/37958839 发送文件须要提供准确的接收放username称(例:user2@192 ...
随机推荐
- 全世界 LoRA 训练脚本,联合起来!
来自社区的 SD-XL Dreambooth LoRA 微调最佳实践指南 太长不看版 我们把 Replicate 在 SDXL Cog 训练器中使用的枢轴微调 (Pivotal Tuning) 技术与 ...
- 聚石塔的K8s 容器服务使用注意事项,坑的总结
1. 首先聚石塔是不能使用 8080 端口的,会审核不通过. 2.然而,容器服务默认的却是8080,最彻底的解决方法就是修改成80,注意3个地方: 以上3个地方要严重留意,缺一不可,已经踩了2次坑了, ...
- windows 10 制作招聘系统镜像
我一直以来都有个想法,就是彻底攻破重装系统这块,但是一直没有时间 没有攻破,今天终于攻破.参考了文章:https://www.cnblogs.com/del88/p/12667087.html 需求: ...
- Python 爬虫方法总结
实现爬虫的套路 准备URL 准备start_url url地址规律不明显,总数不确定 通过代码提取下一页的url 通过xpath提取 寻找url地址,部分参数在当前的响应中(比如当前页码数和总页码数在 ...
- jq 实现select 下拉框的联动效果
实现联动的代码 $(document).ready(function() { $("#selectone").bind("change",function(){ ...
- Maven多模块项目版本统一管理
如图所示,项目中定义了这样几个模块: pdd-workflow-build :定义项目版本,及全局配置 pdd-workflow-dependencies :外部依赖管理,统一管理所有用到的外部依赖的 ...
- Windows xp 无法远程连接Windows Server 2008
-------------------------转载自: Windows XPSP3通过网络级身份验证方式连接Windows Server 2008远程桌面 远程桌面大大方便了大家的日常管理工作,W ...
- 导致Redis访问慢的常见操作
导致Redis访问慢的原因通常有2个方面: 第一,Redis本身性能出现了瓶颈,如:内存使用率过高,并发过大等 第二,存在大KEY,或者客户端访问命令使用不当引起的阻塞 在此,只列举因为的客户端命令使 ...
- __init_subclass__特殊方法
__init_subclass__ 是 Python 3.6 引入的一个特殊方法,用于在子类被定义时执行一些操作. 这个方法允许你在父类中定义一个类方法,当子类继承父类时会自动调用这个方法,你可以在其 ...
- 记一个 Andorid 生成文件失败的bug
Android生成文件失败:java.lang.IllegalStateException:Failed to build unique file: /storage/emulated/0/... 1 ...