清明节放完假刚回来,马上进入到写博文的节奏,今天继续来学习关于传统的Socket编程 - 客户端与服务器端如何进行文件传送的。
在这之前,先来回顾一下上一篇‘Java Socket 01- 常识篇之消息处理’所讲到的内容: 1) 发送消息前如何对消息进行处理 2) 对消息如何进行编码 3)接收消息时如何对消息进行处理 4)发送端与接收端如何进行“对话”式的交互。其中讲到两个重要的概念:① 显式长度(Explicit length) ②基于定界符(Delimiter-based)。
文件的传送包括了两部分:文件的发送与文件的接收。文件发送端、文件的接收端这里分别简称为发送端、接收端。文件的传送也需要发送端与接收端协议好如何传送,比如,文件名,文件内容如何发送,谁先谁后,怎么编码等等。
这里用简单的方法来完成文件的传送:首先发送文件名的长度,然后使用文件名,再发送文件内容的长度,最后发送文件的内容。这里先所以下规则,文件名的长度占4个字节,文件内容的长度占8个字节。如下图:
附件会带上一个完整的源码:(下图是效果图)
下面来一段主要的源码(发送端):
public void uploadFile(String sPath) throws IOException { long lStart = System.currentTimeMillis(); // check the precondition FileInputStream oFileInput = new FileInputStream(new File(sPath)); FileChannel oChannel = oFileInput.getChannel(); // the File length long lLen = oChannel.size(); // the file name String sFileName = sPath.substring(sPath.lastIndexOf(File.separator) + 1); byte[] bFileName = sFileName.getBytes("utf-8"); // 发送文件名的长度和文件名到接收端 m_handler.out().write(BasicTypeConverter.intToByte(bFileName.length)); m_handler.out().write(bFileName); m_handler.out().flush(); // 发送文件内容的长度和文件内容到接收端 m_handler.out().write(BasicTypeConverter.longToByte(lLen)); m_handler.out().flush(); ByteBuffer oBuffer = ByteBuffer.allocate(1024); while (oChannel.read(oBuffer) != -1) { oBuffer.flip(); if (oBuffer.hasRemaining()) { m_handler.out().write(oBuffer.array(), 0, oBuffer.limit()); m_handler.out().flush(); } oBuffer.clear(); } oFileInput.close(); oChannel.close(); long lEnd = System.currentTimeMillis(); long lUseTime = lEnd - lStart; ClientFrame.self.setMsg("文件已经发送完成 ;文件大小:" + lLen/1024 + "KB; 共耗时:"+ lUseTime + "ms ----> "+ sPath); }
如果对FileChannel 和ByteBuffer不了解,请看一下之前我写的博文,Java NIO里面有提到。这里给个链接http://jimmyhr.iteye.com/admin/categories/272010
下面是一段主要的源码(接收端):
@Override public void run() { try { // 文件名的长度 byte[] bHeadLength = new byte[4]; if (m_oIn.read(bHeadLength) == -1) { return; } // 获得文件名的长度 int iLen = BasicTypeConverter.bytesToInt(bHeadLength); // 获得文件名 ByteBuffer oBuffer = ByteBuffer.allocate(iLen); int iR = 0; while (oBuffer.hasRemaining()) { byte[] b = new byte[iLen - iR]; iR += m_oIn.read(b); oBuffer.put(b); } String sFileName = new String(oBuffer.array(), "UTF-8"); // 文件的长度 bHeadLength = new byte[8]; m_oIn.read(bHeadLength); long lFileLen = BasicTypeConverter.byteToLong(bHeadLength); // 接收文件并保存 long lHasRev = 0; File oFile = new File(SAVEPATH + sFileName); if (!oFile.exists()) { File oDir = oFile.getParentFile(); if (!oDir.exists()) { oDir.mkdirs(); } oFile.createNewFile(); } FileOutputStream oOut = new FileOutputStream(oFile); while (lHasRev < lFileLen) { int iAvail = m_oIn.available(); byte[] b = new byte[Math.min((int) (lFileLen - lHasRev), iAvail)]; int iRev = m_oIn.read(b); lHasRev += iRev; oOut.write(b, 0, iRev); oOut.flush(); } oOut.close(); ServerFrame.m_oFrame.setMsg("文件已经保存在:" + SAVEPATH + sFileName); } catch (Exception e) { e.printStackTrace(); } finally { try { m_oSocket.close(); if (m_oIn != null) { m_oIn.close(); } if (m_oOut != null) { m_oOut.close(); } } catch (IOException e) { e.printStackTrace(); } } }
这里可能大家注意到 接收完成后,关闭Socket连接。所以例子中现在只支持单文件传送。大家不妨试试搞一下如何多文件传送。
相关推荐
Java网络编程-Socket-文件传输小案例
在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。 socket 的典型应用就是 ...
java-socket传输文件-图片-源码 我试过本地和局域网传输文件。 按理说,网络传输也是可以的。 效率可以。还可以写成线程操作
Java网络编程-Socket-文件传输小案例学习资料分享c
java socket 大文件传输,快速传输, 数据包的分片,组装,涉及UDP,TCP传输技术,NIO非阻塞等等,适合对socket编程进一步学习的同学
用JAVA实现的文件上传,控制台输入,保存到数据库
Java Socket编程 PC端程序 用来传输文件 包括服务器、客户端
基于java nio socket 的文件传输例程
java socket 简单的文件传输程序,只是实现了基本功能而已。
采用java socket编程,利用Internet传输各种类型的文件,在传输过程中数据完整,传输速度快等优点。
Java基于Socket文件传输示例Java基于Socket文件传输示例Java基于Socket文件传输示例
自己写的东东,已经打成jar包,java socket的聊天和文件传输的工具,暂不提供源代码,有兴趣可以反编译。
java文件传输 之前上传的文件代码多了
socket 文件传输编程 java 多线程
用java socket编写的局域网聊天和文件传送,类似飞秋,但没那么多功能,目前实现的功能有:聊天,发送窗口抖动,传送文件,其中传送文件采用TCP实现,其他的用UDP实现。本文件包含源代码和用到的jar包,代码结构清晰...
对java socket 编程的练习,做了一个基于socket的文件传输程序,可以实现单方文件传输
3.实现了基本文件传送功能 4.实现了发送窗口抖动的功能 5.实现了语音聊天的功能(新增) 资源内容包括源程序和打包后的可执行jar文件,以及要用到的所有jar包; 代码保证可用,如有问题请留言,代码较规范,结构清晰...
Java Socket传输图片源代码;短小精悍,适合初学者学习参考使用