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 ...
随机推荐
- ChatGPT - 圈里的百科
ChatGPT(全名:Chat Generative Pre-trained Transformer),美国OpenAI [1] 研发的聊天机器人程序 [12] ,于2022年11月30日发布 [ ...
- 你天天用4G 这些基本常识都知道吗?
不少朋友在选购4G智能手机的时候,经常可能会遇到这样的名词,五模十三频.五模十七频.双4G.移动4G.联通4G.那这些名词到底是什么意思呢?它们之间又有什么区别呢? 其实上面的这些说法其实都是比较具有 ...
- Azure Data Factory(十二)传参调用 Azure Function
一,引言 在实际的项目中,Azure Data Factroy 中的 Data Flow 并不能彻底帮我们完成一系列复制逻辑计算, 比如我们需要针对数据集的每一行数据进行判断计算,Data Flow ...
- 解决每次 git pull/push 时都需要输入账号和密码的问题
问题 在提交代码或者拉取代码的时候,如果每次git都要输入用户名密码 解决方法 1. 终端输入 git config --global credential.helper store 2. 在git ...
- Python实现二叉查找
搜索 搜索是在一个项目集合中找到一个特定项目的算法过程.搜索通常的答案是真的或假的,因为该项目是否存在. 搜索的几种常见方法:顺序查找.二分法查找.二叉树查找.哈希查找 二分法查找 二分查找又称折半查 ...
- NC15033 小G有一个大树
题目链接 题目 题目描述 小G想要把自己家院子里的橘子树搬到家门口(QAQ..就当小G是大力水手吧) 可是小G是个平衡性灰常灰常差的人,他想找到一个这个橘子树的平衡点. 怎么描述这棵树呢...就把它看 ...
- STC89C52驱动MAX7219LED点阵级联, 文字滚动效果
级联下的传值方式 级联下, N个MAX7219相当于组成了一个8*N bit宽度的锁存器, 如果需要对第M个7219进行写入, 需要做M次寻址+写入后拉高CS, 才能到达这个7219. 如果仅仅对这个 ...
- CentOS8-pacemaker+corosync高可用部署
部署pacemaker yum install pacemaker pcs corosync fence-agents resource-agents 启动pcs服务 systemctl enable ...
- java.lang.System快速指南
1.介绍 在本教程中,我们将快速了解java.lang.System类及其特性和核心功能. 2.IO 系统类是java.lang的一部分,它的一个主要特性是让我们能够访问标准的I/O流. 简单地说,它 ...
- 如何设置 vcpkg 依赖特定编译器
最近项目要部署到 gitlab-ci 上,所以远程机器上也要安装好编译环境 在相关的环境安装完后,发现编译项目时提示找不到三方库的符号文件 看到这个错误的第一反应就是依赖库的版本不对,因为远程机器上不 ...