java tcp 传送任意文件
来源:互联网 发布:uniprot数据库教程 编辑:程序博客网 时间:2024/04/28 23:15
- /*
- TCP通讯
- 需求:传送任意文件
- tcp传输要定义2个端点,客户端和服务端
- 步骤
- 1.定义服务, 服务器ip和接收端口
- 2.读取客户端已有的图片文件
- 3.使用socket输出流将数据发给服务端
- 4.读取服务端的反馈信息
- 5.关闭资源
- 注意:
- 1.在while循环中的read方法最后读到文件结束标记-1后循环退出了
- 而没有将该标记写入socket流中,那么服务端接收到的数据是不完整的,而且停不下来
- 用shutdownOutput方法告诉服务端文件到了末尾结束发送了
- [示例]:传送任意文件 (客户端)
- */
- import java.net.*;
- import java.io.*;
- class Demo
- {
- public static void main(String[] args) throws Exception
- {
- new FileClient("c:\\FoxitReader_CHS.rar"); //启动客户端,准备发送指定文件
- }
- }
- class FileClient //客户端
- {
- FileClient(String fileStr) throws Exception
- {
- s.op("客户端启动....");
- File file = new File(fileStr); //关联一个文件c:\\FoxitReader_CHS.rar
- if(file.isFile()) //是一个标准文件吗?
- {
- client(file); //启动连接
- }
- else
- {
- s.op("要发送的文件 "+fileStr+" 不是一个标准文件,请正确指定");
- }
- }
- public void client(File file)throws Exception
- {
- Socket sock= new Socket("192.168.1.3",10007); //指定服务端地址和端口
- FileInputStream fis = new FileInputStream(file); //读取本地文件
- OutputStream sockOut = sock.getOutputStream(); //定义socket输出流
- //先发送文件名.让服务端知道
- String fileName = file.getName();
- s.op("待发送文件:"+fileName);
- sockOut.write(fileName.getBytes());
- String serverInfo= servInfoBack(sock); //反馈的信息:服务端是否获取文件名并创建文件成功
- if(serverInfo.equals("FileSendNow")) //服务端说已经准备接收文件,发吧
- {
- byte[] bufFile= new byte[1024];
- int len=0;
- while(true)
- {
- len=fis.read(bufFile);
- if(len!=-1)
- {
- sockOut.write(bufFile,0,len); //将从硬盘上读取的字节数据写入socket输出流
- }
- else
- {
- break;
- }
- }
- }
- else
- {
- s.op("服务端返回信息:"+serverInfo);
- }
- sock.shutdownOutput(); //必须的,要告诉服务端该文件的数据已写完
- s.op("服务端最后一个返回信息:"+servInfoBack(sock));//显示服务端最后返回的信息
- fis.close();
- sock.close();
- }
- public String servInfoBack(Socket sock) throws Exception //读取服务端的反馈信息
- {
- InputStream sockIn = sock.getInputStream(); //定义socket输入流
- byte[] bufIn =new byte[1024];
- int lenIn=sockIn.read(bufIn); //将服务端返回的信息写入bufIn字节缓冲区
- String info=new String(bufIn,0,lenIn);
- return info;
- }
- }
- class s
- {
- public static void op(Object obj) //打印
- {
- System.out.println(obj);
- }
- }
- /*
- 服务端原先有很大的局限性
- 原先我们没有考虑客户端的文件名,和客户端判断是否有重名文件,我们是另外指定了文件名和路径
- 当客户端A连接服务端,被服务端获取到后,服务端执行具体流程,
- 这时如果B客户端尝试连接服务端,但只能等待
- 因为服务端还没有处理完A客户端的请求,不能回while起始位置执行accept方法,所以
- 暂时获取不到B客户端对象,那么为了可以让多个客户端同时被服务端并发接收,
- 那么服务端最好就是将每个客户端封装到一个个单独的线程中,这样,就可以同时处理多个客户端请求
- 如何定义线程呢?
- 只要明确每一个客户端要再服务端执行的代码即可,将该代码放到run方法中
- 如果服务端存在同名文件就返回信息并断开该次连接
- 如果要让客户端选择是否要覆盖文件,可以再加个反馈操作应该就可以了
- [示例]:传送任意文件 (服务端并发执行)
- */
- import java.net.*;
- import java.io.*;
- class Demo
- {
- public static void main(String[] args) throws Exception
- {
- new FileServer(); //启动文件存储服务端
- }
- }
- class FileServer //服务端
- {
- FileServer() throws Exception
- {
- s.op("服务端启动......");
- server();
- }
- public void server() throws Exception
- {
- ServerSocket serversock = new ServerSocket(10007); //监听端口
- while(true)
- {
- Socket sock = serversock.accept(); //循环等待客户端连接
- new Thread(new FileServThread(sock)).start(); //当成功连接客户端后开启新线程接收文件
- }
- }
- }
- class FileServThread implements Runnable //服务端线程
- {
- private Socket sock;
- FileServThread(Socket sock)
- {
- this.sock = sock;
- }
- public void run()
- {
- String ip = sock.getInetAddress().getHostAddress(); //获取客户端ip
- try
- {
- s.op("开启新线程接收来自客户端IP: "+ip+" 的文件");
- InputStream sockIn= sock.getInputStream();//定义socket输入流,接收客户端的信息
- File file =getClientFileName(sockIn); //创建同名文件
- if(file==null)
- {
- writeOutInfo(sock,"存在同名文件或获取文件失败,服务端断开连接!");
- sock.close(); return;
- }
- FileOutputStream fos= new FileOutputStream(file); //用来写入硬盘
- byte[] bufFile = new byte[1024*1024]; //接收数据的缓存
- int len=0;
- while(true)
- {
- len=sockIn.read(bufFile); //接收数据
- if(len!=-1)
- {
- fos.write(bufFile,0,len); //写入硬盘文件
- }
- else
- {
- break;
- }
- }
- writeOutInfo(sock,"上传成功!"); //文件接收成功后给客户端反馈一个信息
- s.op("文件接收成功!"+System.getProperty("line.separator")); //服务端打印一下
- fos.close();
- sock.close();
- }
- catch(Exception ex)
- {
- throw new RuntimeException(ip+"异常!!!");
- }
- }
- public void writeOutInfo(Socket sock,String infoStr)throws Exception//将信息反馈给服务端
- {
- OutputStream sockOut = sock.getOutputStream();
- sockOut.write(infoStr.getBytes());
- }
- public File getClientFileName(InputStream sockIn) throws Exception //获取文件名并创建
- {
- //获取客户端请求发送的文件名,并判断在D盘创建同名文件的情况
- byte[] bufName=new byte[1024];
- int lenInfo =0;
- lenInfo = sockIn.read(bufName); //获取文件名
- String fileName = new String(bufName,0,lenInfo);
- File dir = new File("d:\\"); //存到D盘根目录
- File[] files=dir.listFiles(); //遍历d盘目录
- for(File f:files)
- {
- if(!f.isDirectory()) //如果遍历到的该文件不是一个目录的话
- {
- if(f.getName().equals(fileName)) //判断是否是同名文件
- {
- s.op(f.getName()+"文件已存在,断开该ip连接."+System.getProperty("line.separator"));
- writeOutInfo(sock,"服务端已存在同名文件!"); //反馈给客户端的信息
- return null;
- }
- }
- }
- s.op("将客户端发来的文件( "+fileName+" )存到"+dir.getAbsolutePath());
- File file= new File(dir+fileName);
- if(file.createNewFile())
- {
- s.op("成功创建文件("+fileName+" )准备写入数据");
- writeOutInfo(sock,"FileSendNow"); //告诉客户端,开始传送数据吧
- return file;
- }
- else
- {
- return null; //如果由于硬盘满了等原因创建文件失败的话
- }
- }
- }
- class s
- {
- public static void op(Object obj) //打印
- {
- System.out.println(obj);
- }
- }
转载自:http://xouou.iteye.com/blog/1387875
0 0
- java tcp 传送任意文件
- java 通过tcp传送xml文件
- tcp文件的传送
- TCP文件传送
- Java TCP使用Socket进行网络文件传送(5)
- java服务端客户端交互系列(四)传送任意文件(服务端并发)
- java 传送文件
- java NIO 传送文件
- Linux下通过TCP传送文件(客户端)
- Linux下通过TCP传送文件(服务器端)
- 使用Ip/tcp协议进行文件传送
- java socket 传送图片文件。
- 远程传送大文件的例子,使用TCP协议
- 基于TCP的局域网多用户通信、文件传送程序详解
- TCP/IP 详解 卷1 ch27 FTP: 文件传送协议
- TCP协议从客户端传送文件给服务端
- 【TCP/IP详解】第27章 FTP:文件传送协议
- [c#源码分享]TCP通信中的大文件传送
- linux 下Opencv安装
- reverse interger --- leetcode
- POJ 3320
- 查看oracle当前session
- QTCreator添加链接库
- java tcp 传送任意文件
- 黑马程序员——Java基础中的输入输出流(I/O)
- Java设计模式之状态模式
- Linux中profile、bashrc、~/.bash_profile、~/.bashrc、~/.bash_profile之间的区别和联系以及执行顺序
- Android学习笔记之适配器
- 计算几何小结
- 2015年实习心情周记III
- properties
- 【软件打包】Advanced Installer -- Windows的安装包制作工具【1】