Socket多文件传输

Socket多文件传输代码

本文是一个多线程多文件传输实例,客户端里修改ipport即可实现,代码是完整的。

如果有不清楚的,可以给我留言。

服务端代码:

package com;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.net.ServerSocket;

import java.net.Socket;

public class FileServer implements Runnable {

private static final int DEFAULT_PORT = 7778;

private ServerSocket serverSocket;

public final static int PER_RECEIVE_SIZE = 1024 * 100;

/**

 * 启动程序

 * 

 * @param args

 */

public static void main(String[] args) {

FileServer server = new FileServer();

server.init();

Thread thread = new Thread(server);

thread.start();

}

public void init() {

try {

serverSocket = new ServerSocket(DEFAULT_PORT);

} catch (Exception e) {

e.printStackTrace();

}

}

public void run() {

if (serverSocket == null) {

System.out.println("ERROR");

return;

}

while (true) {

DataInputStream serverIn = null;

DataOutputStream serverOut = null;

Socket socket = null;

try {

socket = serverSocket.accept();

serverIn = new DataInputStream(socket.getInputStream());

serverOut = new DataOutputStream(socket.getOutputStream());

while (true) {

try {

String command = readUTF(serverIn);

if (command == null || !command.contains("ClientInfo")) {

continue;

}

String fileName = new String(command.replaceAll("(.+<FileName>|<\\/FileName>\\S+)", "")

.toString().getBytes("UTF-8"), "UTF-8");

String fileSize = new String(command.replaceAll("(.+<FileLength>|<\\/FileLength>\\S+)", "")

.toString().getBytes("UTF-8"), "UTF-8");

String offset = new String(command.replaceAll(

"(.+<FilePointerStart>|<\\/FilePointerStart>\\S+)", "").toString().getBytes("UTF-8"),

"UTF-8");

String endset = new String(command.replaceAll("(.+<FilePointerEnd>|<\\/FilePointerEnd>\\S+)",

"").toString().getBytes("UTF-8"), "UTF-8");

File tempFile = new File("E:\\socket", fileName + ".temp");

File parentFile = tempFile.getParentFile();

boolean isCreate = initFile(tempFile, parentFile, Long.valueOf(fileSize));

if (!isCreate) {

closeSocket(serverIn, serverOut, socket);

}

String readyCommand = "ready=1";

writeUTF(serverOut, readyCommand);

String startCommand = readUTF(serverIn);

if ("sendStart".contains(startCommand)) {

RandomAccessFile randomAccessFile = new RandomAccessFile(tempFile, "rw");

long curPoint = Long.valueOf(offset);

long endPoint = Long.valueOf(endset);

byte[] buffer = null;

while (curPoint < endPoint && isContinue(serverIn)) {

if ((endPoint - curPoint + 1 < PER_RECEIVE_SIZE)) {

buffer = new byte[(int) (endPoint - curPoint + 1)];

} else {

buffer = new byte[(int) (PER_RECEIVE_SIZE)];

}

int amount;

long perLength = 0;

while ((amount = serverIn.read(buffer)) != -1) {

randomAccessFile.seek(curPoint);

randomAccessFile.write(buffer, 0, amount);

curPoint += amount;

perLength += amount;

if (perLength == buffer.length) {

break;

} else if (perLength > buffer.length) {

System.out.println("perLength" + perLength + "\tbuffer" + buffer.length);

System.out.println("传输出错");

}

}

System.out.println(" 指针位置 " + curPoint + " , 大小" + fileSize + "\t"

+ (curPoint == endPoint) + "\tendPoint:" + endPoint);

writeUTF(serverOut, "SerGotIt");

if (curPoint == endPoint + 1) {

writeUTF(serverOut, "receiveEnd");

closeRandomAccessFile(randomAccessFile);

break;

} else if (curPoint > endPoint) {

System.out.println("curPoint" + curPoint + "\tendPoint" + endPoint);

System.out.println("文件传输出错");

break;

}

}

}

String sendCommand = readUTF(serverIn);

if ("sendEnd".equals(sendCommand)) {

boolean isRename = renameFile(tempFile);

if (!isRename) {

System.out.println("文件重命名失败");

}

break;

}

} catch (Exception e) {

e.printStackTrace();

break;

}

}

} catch (Exception e) {

e.printStackTrace();

break;

} finally {

try {

closeSocket(serverIn, serverOut, socket);

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

public void closeRandomAccessFile(RandomAccessFile randomAccessFile) throws IOException {

randomAccessFile.close();

}

public void closeSocket(DataInputStream serverIn, DataOutputStream serverOut, Socket socket) throws IOException {

if (serverIn != null) {

serverIn.close();

}

if (serverOut != null) {

serverOut.close();

}

if (socket != null) {

socket.close();

}

}

public boolean renameFile(File tempFile) {

String filePath = tempFile.getPath();

filePath = filePath.substring(0, filePath.lastIndexOf(".temp"));

boolean isRename = tempFile.renameTo(new File(filePath));

System.out.println("重命名是否成功:" + isRename);

return isRename;

}

public String readUTF(DataInputStream dis) throws IOException {

return dis.readUTF();

}

public boolean isContinue(DataInputStream dis) {

boolean flag = false;

String command;

try {

command = dis.readUTF();

System.out.println(command);

if ("Continue".equals(command)) {

flag = true;

}

} catch (IOException e) {

e.printStackTrace();

flag = false;

}

return flag;

}

public boolean initFile(File tempFile, File parentFile, long fileSize) {

if (tempFile.exists()) {

return true;

}

if (parentFile.isDirectory()) {

creat(tempFile, fileSize);

return true;

} else {

boolean isCreate = parentFile.mkdirs();

if (isCreate) {

creat(tempFile, fileSize);

return true;

} else {

return false;

}

}

}

/**

 * 创建文件

 * @param targetFile 文件对象

 * @param fileLength 文件字节长度

 */

public static void creat(File targetFile, long fileLength) {

long length = fileLength;//指定写入文件文件大小

byte[] buffer = new byte[PER_RECEIVE_SIZE];// 缓冲区1024 bytes

FileOutputStream fos;

try {

fos = new FileOutputStream(targetFile);

while (true) { // 建立缓冲区

if (length > PER_RECEIVE_SIZE) {

// 将缓冲区字节写入文件

try {

fos.write(buffer);// 写入缓冲

length = length - PER_RECEIVE_SIZE;

} catch (IOException e) {

e.printStackTrace();

}

} else {

byte[] buf = new byte[(int) length];

System.arraycopy(buffer, 0, buf, 0, (int) length);

try {

fos.write(buf);

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

break;

}

}

} catch (FileNotFoundException e1) {

e1.printStackTrace();

}

}

public void writeUTF(DataOutputStream dos, String command) throws IOException {

dos.writeUTF(command);

dos.flush();

}

}

客户端代码

package com;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.RandomAccessFile;

import java.net.Socket;

public class FileClient {

//服务端ip地址

private static final String DEFAULT_HOST = "192.10.33.95";

//服务端ip端口

private static final int DEFAULT_PORT = 7778;

public final static int PER_SEND_SIZE = 1024 * 100;

private Socket clientSocket;

/** 文件区域块 */

private int blockNum = 1;

/**

 * 启动客户端程序

 * 

 * @param args

 */

public static void main(String[] args) {

FileClient client = new FileClient();

client.init();

client.process();

}

public void init() {

try {

clientSocket = new Socket(DEFAULT_HOST, DEFAULT_PORT);

} catch (Exception e) {

e.printStackTrace();

}

}

public String[] getFileInfos(String fileName, long offset, long endset, long fileSize, long lastModifyTime) {

String[] fileInfos = new String[blockNum];

fileInfos[0] = "ClientInfo";

fileInfos[0] += "<FileName>" + fileName + "</FileName>";

fileInfos[0] += "<FilePointerStart>" + offset + "</FilePointerStart>";

fileInfos[0] += "<FilePointerEnd>" + endset + "</FilePointerEnd>";

fileInfos[0] += "<FileLength>" + fileSize + "</FileLength>";

fileInfos[0] += "<LastModifyTime>" + lastModifyTime + "</LastModifyTime>";

return fileInfos;

}

public void writeUTF(DataOutputStream dos, String command) throws IOException {

dos.writeUTF(command);

dos.flush();

}

public void writeBuffer(DataOutputStream dos, byte[] buffer) throws IOException {

dos.write(buffer);

dos.flush();

}

public String readUTF(DataInputStream dis) throws IOException {

return dis.readUTF();

}

public void process() {

if (clientSocket == null) {

System.out.println("ERROR");

return;

}

DataInputStream clientIn = null;

DataOutputStream clientOut = null;

try {

InputStream input = clientSocket.getInputStream();

OutputStream output = clientSocket.getOutputStream();

//发送文件

clientIn = new DataInputStream(new BufferedInputStream(input));

clientOut = new DataOutputStream(new BufferedOutputStream(output));

File tempFile = new File("D:\\tools\\QQMusicV7.72.1659.0907.exe");

String fileName = tempFile.getName();

long fileSize = tempFile.length();

long lastModifyTime = tempFile.lastModified();

long offset = 0; //区块起始位置

long endset = fileSize - 1; //区块结束位置

String[] fileInfos = getFileInfos(fileName, offset, endset, fileSize, lastModifyTime);

writeUTF(clientOut, fileInfos[0]);

while (true) {

String command = readUTF(clientIn);

if (!command.contains("ready=1")) {

continue;

}

writeUTF(clientOut, "sendStart");

RandomAccessFile randomAccessFile = new RandomAccessFile(tempFile, "r");

long curPoint = offset;

byte[] buffer = null;

while (curPoint < endset) {

writeUTF(clientOut, "Continue");

int length = 0;

try {

randomAccessFile.seek(curPoint);

if (endset - curPoint + 1 < PER_SEND_SIZE) {

buffer = new byte[(int) (endset - curPoint + 1)];

} else {

buffer = new byte[PER_SEND_SIZE];

}

length = randomAccessFile.read(buffer);

if (length == buffer.length) {

writeBuffer(clientOut, buffer);

for (;;) {

String serGotItCommand = readUTF(clientIn);

if ("SerGotIt".equals(serGotItCommand)) {

break;

}

}

curPoint += length;

System.out.println("curPoint:" + curPoint + "\tfileSize:" + fileSize);

if (curPoint == fileSize) {

System.out.println("发送完成");

break;

}

}

} catch (Exception e) {

e.printStackTrace();

break;

}

}

String endCommand = readUTF(clientIn);

System.out.println(endCommand);

if ("receiveEnd".equals(endCommand)) {

System.out.println("发送指令完成");

writeUTF(clientOut, "sendEnd");

break;

}

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (clientIn != null) {

clientIn.close();

}

if (clientOut != null) {

clientOut.close();

}

if (clientSocket != null) {

clientSocket.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值