您的位置:首页 > 编程语言 > Java开发

JAVA SOCKET 实现多线程文件传输(Server端的多线程,Client一次只有一个)

2014-07-07 17:32 519 查看
1.最近一个项目需要实现客户端文件上传到server,但是不希望把文件上传在与服务器同一台机器上,所以只能通过socket编程实现。

package socket;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

/**

* <p>

* Company:

* </p>

*

* @author

* @date 2014年7月7日

* @version 1.0

*/

public class ServerTransfer {

private int defaultBindPort = Constants.DEFAULT_BIND_PORT; // 默认监听端口号为10000

private int tryBindTimes = 0; // 初始的绑定端口的次数设定为0

private ServerSocket serverSocket; // 服务套接字等待对方的连接和文件发送

private ExecutorService executorService; // 线程池

private final int POOL_SIZE = 4; // 单个CPU的线程池大小

/**

* 不带参数的构造器,选用默认的端口号

*

* @throws Exception

*/

public ServerTransfer() throws Exception {

try {

this.bingToServerPort(defaultBindPort);

executorService = Executors.newFixedThreadPool(Runtime.getRuntime()

.availableProcessors() * POOL_SIZE);

System.out.println("开辟线程数 : "

+ Runtime.getRuntime().availableProcessors() * POOL_SIZE);

} catch (Exception e) {

throw new Exception("绑定端口不成功!");

}

}

private void bingToServerPort(int port) throws Exception {

try {

serverSocket = new ServerSocket(port);

System.out.println(port);

System.out.println("服务启动!");

} catch (Exception e) {

this.tryBindTimes = this.tryBindTimes + 1;

port = port + this.tryBindTimes;

if (this.tryBindTimes >= 20) {

throw new Exception("您已经尝试很多次了,但是仍无法绑定到指定的端口!请重新选择绑定的默认端口号");

}

// 递归绑定端口

this.bingToServerPort(port);

}

}

public void service() {

Socket socket = null;

while (true) {

try {

socket = serverSocket.accept();

executorService.execute(new Handler(socket));

} catch (Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) throws Exception {

new ServerTransfer().service();

}

}

Headler

package socket;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.FileOutputStream;

import java.net.Socket;

import java.util.zip.GZIPOutputStream;

/**

* <p>

* Company:

* </p>

*

* @author

* @date 2014年7月7日

* @version 1.0

*/

class Handler implements Runnable {

private Socket socket;

public Handler(Socket socket) {

this.socket = socket;

}

public void run() {

System.out.println("New connection accepted " + socket.getInetAddress()

+ ":" + socket.getPort());

DataInputStream dis = null;

DataOutputStream dos = null;

int bufferSize = 8192;

byte[] buf = new byte[bufferSize];

try {

dis = new DataInputStream(new BufferedInputStream(

socket.getInputStream()));

String savePath = Constants.RECEIVE_FILE_PATH + dis.readUTF();

long length = dis.readLong();

dos = new DataOutputStream(new BufferedOutputStream(

new GZIPOutputStream(new FileOutputStream(savePath))));

int read = 0;

long passedlen = 0;

while ((read = dis.read(buf)) != -1) {

passedlen += read;

dos.write(buf, 0, read);

System.out.println("文件[" + savePath + "]已经接收: " + passedlen

* 100L / length + "%");

}

System.out.println("文件: " + savePath + "接收完成!");

} catch (Exception e) {

e.printStackTrace();

System.out.println("接收文件失败!");

} finally {

try {

if (dos != null) {

dos.close();

}

if (dis != null) {

dis.close();

}

if (socket != null) {

socket.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

ClientServer

package socket;

import java.io.BufferedInputStream;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.zip.GZIPInputStream;

/**

* <p>

* Company:

* </p>

*

* @author

* @date 2014年7月7日

* @version 1.0

*/

public class ClientTransfer {

// private String sendFilePath = Constants.SEND_FILE_PATH;

//

private String sendFilePath = "D:/test";

public void service() {

ExecutorService executorService = Executors.newCachedThreadPool();

executorService.execute(sendFile("D:/test1/test.zip"));

}

private static Runnable sendFile(final String filePath) {

return new Runnable() {

private Socket socket = null;

private String ip = "localhost";

private int port = 10000;

public void run() {

System.out.println("开始发送文件:" + filePath);

File file = new File("D:/test1/test.zip");

if (createConnection()) {

int bufferSize = 8192;

byte[] buf = new byte[bufferSize];

try {

GZIPInputStream gzin = new GZIPInputStream(new FileInputStream(

"D:\\test1\\test.zip"));

java.io.InputStream is = new BufferedInputStream(gzin);

DataInputStream fis = new DataInputStream(

is);

DataOutputStream dos = new DataOutputStream(

socket.getOutputStream());

dos.writeUTF(file.getName());

dos.flush();

dos.writeLong(file.length());

dos.flush();

int read = 0;

int passedlen = 0;

long length = file.length(); // 获得要发送文件的长度

while ((read = fis.read(buf)) != -1) {

passedlen += read;

System.out.println("已经完成文件 [" + file.getName()

+ "]百分比: " + passedlen * 100L / length

+ "%");

dos.write(buf, 0, read);

}

dos.flush();

fis.close();

dos.close();

socket.close();

System.out.println("文件 " + filePath + "传输完成!");

} catch (Exception e) {

e.printStackTrace();

}

}

}

private boolean createConnection() {

try {

socket = new Socket(ip, port);

System.out.println("连接服务器成功!");

return true;

} catch (Exception e) {

System.out.println("连接服务器失败!");

return false;

}

}

};

}

public static void main(String[] args) {

new ClientTransfer().service();

}

}

package socket;

/**

* <p>Company: </p>

* @author

* @date 2014年7月7日

* @version 1.0

*/

public interface Constants {

public final static String RECEIVE_FILE_PATH = "D:\\target\\";

public final static String SEND_FILE_PATH = "D:\\send";

public final static int DEFAULT_BIND_PORT = 8888;

}

本文实现了GZIP文件的上传和下载,如果需要上传任何文件的内容,只需要更去除Handler 和ClientServer两个类中的 GZIPOutputStream 一层封装既可。

其实ClientServer也可以实现多线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐