Java关于个人对于Socket的理解,Socket多线程批量上传文件,适合新手
2015-01-03 00:39
691 查看
搞软件将近三年了,回想三年来匆匆忙忙,所涉猎的东西比较驳杂,Java、android、c#、ios,当回首望去才发现,原来,想要真正精通一门语言其实还是比较困难的,因此,在今天终于是开了博客,希望能够记住自己偶尔的感悟和一些编程思想,同时,也希望能够帮助更多的人进入软件行业,同为程序员,大家互相交流新得,这样才能不断的进步,程序员的大家庭才能更轻松,若本人所写东西有不得当之处,希望五湖四海的朋友能够不吝指导,谢谢。
话不多说,直接贴代码:
客户端:
<span style="color:#000000;">package com.qzf.socket; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class SocketClient { private static List<String> fQuene = new ArrayList<String>();// 文件路径的消息队列 public static void main(String[] args) { fQuene.add("E:\\2013-12-08-2.bmp"); fQuene.add("E:\\U盘备份\\111726邱振飞_数据结构.rar"); fQuene.add("F:\\music\\BEYOND - 光辉岁月.mp3"); fQuene.add("F:\\迅雷下载\\MB855tools.zip"); fQuene.add("d:\\Mavericks.cdr"); new Thread(new Runnable() { @Override public void run() {// 开启遍历消息队列的线程检查消息队列中是否有文件需要上传 try { while (true) { Thread.sleep(200); if (!fQuene.isEmpty()) { String fName = fQuene.remove(0); if (new File(fName).exists()) { sendFile(fName); } } } } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } static int i = 0; static void sendFile(String fName) { Socket sendSocket = null; try { sendSocket = new Socket(Configs.SERVER_IP, Configs.SERVER_PORT); new SendThread(sendSocket, "thread-" + ++i, fName).start(); } catch (IOException e) { e.printStackTrace(); } } } class SendThread extends Thread { private Socket socket; private String fName; private String fNameTemp; public SendThread(Socket socket, String name, String fName) { this.socket = socket; this.setName(name); this.fName = fName; this.fNameTemp= fName.substring(fName.lastIndexOf('\\'));//这里是取得文件的名称,不带路径,一般用文件分隔符,这里我偷懒了 } @Override public void run() { try { Thread.sleep(1000); OutputStream os = socket.getOutputStream(); os.write(fNameTemp.getBytes("utf-8"));//将文件名称发送过去 InputStream is = socket.getInputStream(); byte[] revBuff = new byte[1]; is.read(revBuff);//接收服务端传回的握手结果 int result = revBuff[0];//自行处理,可以不处理,但是要read握手结果,表示对方已经接收到文件名称 System.out.println(result); if(result == 1){//表示成功接收文件名,我自定义的返回结果为1 System.out.println("start send file:" + fName); File sendFile = new File(fName); FileInputStream fis = new FileInputStream(sendFile); byte[] buffer = new byte[Configs._BUFFER_SIZE]; int fLen = (int)sendFile.length();//文件大小 //接下来打包发送文件,将字节数组的前四个字节放置文件的大小,当然,也可以像前面一样握手,这里不再进行握手 byte[] fLenBuff = Utils.int2bytes(fLen); for(int i=0; i<fLenBuff.length; i++){ //将文件大小放到传送的缓存数组中,待发送,这里就是简单的自定义传输协议了,包头4个字节放文件大小,后面是文件内容 //实际操作中,我们都是这么组包的,文件名等内容也是一起组包的,不过为了方便理解,这里介绍了握手操作,以及read这个 //阻塞方法的应用,其实都是自定义传输协议,不过,如果商用,就是组协议包,这样比较通用,理解之后,随便自定义 buffer[i] = fLenBuff[i]; } //sendLen 记录已经发送的字节数,可用于断点续传,也可用来标识上传进度 int read, sendLen = fis.read(buffer, fLenBuff.length, buffer.length - fLenBuff.length); os.write(buffer); sendLen += fLenBuff.length; while((read = fis.read(buffer, 0, buffer.length)) > 0){//循环发送输入流读取到的数据 sendLen += read; os.write(buffer, 0, read); if(sendLen == fLen)//发送完成 break; } byte[] overOuffer = new byte[1024]; int overLen = is.read(overOuffer); System.out.println("send over:" + new String(overOuffer, 0, overLen, "utf-8")); os.close(); fis.close(); is.close(); socket.close(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }</span>
服务端:
<span style="color:#000000;">package com.qzf.socket; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class SocketReceiveServer { private static ServerSocket linstener = null; private static boolean isRunning = false; public static void main(String[] args) { isRunning = true; new Thread(new Runnable() {// 启动线程监听是否有连接上来 @Override public void run() { try { linstener = new ServerSocket(Configs.SERVER_PORT); System.out.println("准备就绪.."); } catch (IOException e) { System.out.println("linstenner exception:" + e.toString()); } while (isRunning) { try { Thread.sleep(90); Socket socket = linstener.accept();// 阻塞监听,获取socket实例 System.out.println("有新连接上来.."); new ReceiveThread(socket).start();// 开启新线程处理socket的数据 } catch (InterruptedException e) { } catch (IOException e) { } } } }).start(); } } class ReceiveThread extends Thread { private Socket revSocket = null; public ReceiveThread(Socket revSocket) {// 构造器实例化socket this.revSocket = revSocket; } @Override public void run() { System.out.println("接收线程开始启动"); byte[] buffer = new byte[Configs._BUFFER_SIZE]; // 接收到的字节数 InputStream is; OutputStream os ; try { is = revSocket.getInputStream(); os = revSocket.getOutputStream(); int received = is.read(buffer); if (received > 0) { String fName = new String(buffer, 0 , received, "utf-8"); System.out.println("开始接受:" + fName); os.write(new byte[]{1});//返回握手结果1 // length文件的长度,receive已接收的文件长度 is.read(buffer); int receive, length = Utils.bytes2int(buffer);//将收到的数组前四字节转化得到文件大小 System.out.println(fName + " size:" + length + " B"); FileOutputStream fos = new FileOutputStream(new File(Configs.TEST_ROOT_DIR + fName)); fos.write(buffer, 4, buffer.length - 4);//这边的-4指的 是客户端发过来的文件大小的4个字节 received = buffer.length - 4; while((receive = is.read(buffer, 0, buffer.length)) > 0){ fos.write(buffer, 0, receive); received += receive; if(received == length){//接收完毕 os.write((fName + " Recevice OK.").getBytes("utf-8"));//发送接收成功给客户端 break; } } System.out.println("rev over"); fos.close(); is.close(); os.close(); revSocket.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } </span>
相关文章推荐
- 关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手
- 关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手
- 关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手
- [置顶] 关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手
- 关于JAVA面向对象基础整理以及个人的理解(适合初学者阅读)
- java文件原生方式的上传和下载,适合新手学习
- 关于stuts2文件上传出错java.lang.NoSuchMethodException: com.cn.file.upload.UploadFile.uploadfile()
- 个人对于JAVA异常的理解
- JAVA NIO SOCKET大文件上传服务器
- 关于Java的socket服务端项目如何打包成exe文件运行在服务器上。
- 【JAVA】Socket文件上传遇到的问题!~
- 个人关于java与指针的理解
- Java-Socket TCP-文件上传
- Java网络编程实践和总结 --- 基于TCP的Socket编程之实现文件上传和下载服务
- Flex与java进行socket通信完成以断点续传方式的文件上传
- 对于android文件上传中 java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream 的错误解决方法
- 关于socket的一些个人理解
- java-★-Socket文件上传/进度条
- Java关于文件上传的一个例子
- Java 不用三方包, 并且使用socket, 访问ftp, 并且将文件上传