关键是发送端每write一次就要flush一次,否则容易出错。
发送时要先发送文件的长度,然后才是文件的内容。
先来发送端,主要的代码:
int tempCount = 0;
System.out.print("Server Start");
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(Const.NET_PORT);
File fileRoot = new File(Const.IMAGE_FILE_SOURCE_ROOT);
File[] subFiles = fileRoot.listFiles();
Socket socket = serverSocket.accept();
DataOutputStream doStream = new DataOutputStream(socket.getOutputStream());
for(int j=0;j<subFiles.length;j++)
{
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(subFiles[j])));
doStream.writeLong((long) subFiles[j].length());
doStream.flush();
System.out.println(subFiles[j].getName());//temp
System.out.println("length " + subFiles[j].length());//temp
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
while (true) {
int read = 0;
if (fis != null) {
read = fis.read(buf);
}
if (read == -1) {
break;
}
doStream.write(buf, 0, read);
doStream.flush();//这步是必须的,不然发送多了容易接收出错
}
fis.close();
System.out.println("ok " + tempCount++);//temp
}
socket.close();
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
接收端,要知道读取到何时知道是一个文件的结尾
for(int j=0;j<1000;j++)//测试用,接收1000个文件数量,理论上发送端应发送共有多少个文件数量过来
{
receiveFile(dis);
}
public static void receiveFile(DataInputStream inpStr) throws IOException
{
long length = inpStr.readLong();
System.out.println("length " + length);//temp
File fileOut = new File("/home/Videos/temp" + fileNameIndex++);
if(!fileOut.exists())
{
fileOut.createNewFile();
}
FileOutputStream fos = new FileOutputStream(fileOut);
int bufferSize = 8192;//使用8192,是因为socket自带的缓冲区大小是这个,似乎大小匹配了,传输效率更高
byte[] buf = new byte[bufferSize];
while (true) {
if (length >= bufferSize) {
inpStr.readFully(buf);
fos.write(buf, 0, bufferSize);
}
else {
byte[] smallBuf = new byte[(int)length];
inpStr.readFully(smallBuf);
fos.write(smallBuf);
break;
}
length -= bufferSize;
}
fos.close();
}