Socket 多文件传输代码
本文是一个多线程多文件传输实例,客户端里修改 ip 和 port 即可实现,代码是完整的。
如果有不清楚的,可以给我留言。
服务端代码:
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
=
String(command.replaceAll("(.+|<\\/FileName>\\S+)", "")
.toString().getBytes("UTF-8"), "UTF-8");
String(command.replaceAll("(.+|<\\/FileLength>\\S+)", "")
String
fileSize
=
.toString().getBytes("UTF-8"), "UTF-8");
String offset = new String(command.replaceAll(
"(.+|<\\/FilePointerStart>\\S+)",
"").toString().getBytes("UTF-8"),
"UTF-8");
=
String(command.replaceAll("(.+|<\\/FilePointerEnd>\\S+)",
endset
String
"").toString().getBytes("UTF-8"), "UTF-8");
new
new
new
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 +
System.out.println("传输出错");
}
}
System.out.println(" 指针位置 " + curPoint + " , 大小" +
"\tbuffer" + buffer.length);
fileSize + "\t"
endPoint);
"\tendPoint" + endPoint);
+ (curPoint == endPoint) + "\tendPoint:" +
writeUTF(serverOut, "SerGotIt");
if (curPoint == endPoint + 1) {
writeUTF(serverOut, "receiveEnd");
closeRandomAccessFile(randomAccessFile);
break;
} else if (curPoint > endPoint) {
System.out.println("curPoint"
+
curPoint
+
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 + "";
fileInfos[0] += "" + offset + "";
fileInfos[0] += "" + endset + "";
fileInfos[0] += "" + fileSize + "";
fileInfos[0] += "" + 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();
}