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

简单的学习一下SOCKET的文件传输

2015-04-18 17:11 309 查看
用sokcet和hashmap的序列化反序列化实现文件传输。

首先是接收端的服务器:

package 网络连接;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

public class Sockethanshu {

private static ServerSocket serversocket;

@SuppressWarnings("unchecked")
public static void main(String[] args)  {

ObjectInputStream mObjectInputStream = null;//把输入流反序列化;只有继承了implements Serializable 才能序列化
HashMap<String, Object> getData = null;
FileOutputStream fileOutputStream = null;//从文件输出流。
String destenyfile="f:/dest.avi";
int i = 0;
int bandport=8000;
// TODO 自动生成的方法存根
try {
serversocket = new ServerSocket(bandport);
}
catch (Exception e) {
// TODO: handle exception
System.out.println("绑定端口出错");
}

System.out.println("绑定端口成功正在监听");
Socket socket = null;
try {
socket = serversocket.accept();
}
catch (Exception e) {
// TODO 自动生成的 catch 块
System.out.println("监听出错");
System.exit(0);
}

try {
fileOutputStream = new FileOutputStream(destenyfile);
}
catch (FileNotFoundException e1) {

System.out.println("文件创建出错");
System.exit(0);
}

try {
mObjectInputStream = new ObjectInputStream(socket.getInputStream());// 设置类的输入流的入口是socekt的输入流
}
catch (IOException e1) {

System.out.println("设置输入端口出错");
System.exit(0);
}
System.out.println("准备接收文件");

while (true) {
try {

getData = ((HashMap<String, Object>) mObjectInputStream.readUnshared());// 读取类的输入流并反序列化为hashmap;
if ((int) getData.get("int") == -1) break;//表示文件已经结束,本次的流不再写入
fileOutputStream.write((byte[]) getData.get("data"));// 写入
fileOutputStream.flush();// 把缓存中的流,强制输出;

i++;
}
catch (Exception e) {
System.out.println("接收文件出错");
break;
}

}

try {
fileO
910b
utputStream.close();
}
catch (IOException e) {

}

System.out.println("接受完毕,共" + i+"个文件块");

}

}
然后是发送端的的
package 网络连接客户机;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;

public class KeHuJi {

public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根

byte[] sendBytes = new byte[4096];
Socket socket = null;
String sourcefile = "f:/xianjian.avi";
String ip="123.246.59.79";
int port =8000;
FileInputStream output = null;

try {
socket = new Socket(ip, port);
}
catch (Exception e) {
System.out.println("连接超时");
System.exit(0);

}
HashMap<String, Object> buffer = new HashMap<String, Object>();
try {
output = new FileInputStream(sourcefile);
}
catch (Exception e) {
System.out.println("文件打开出错");
}

ObjectOutputStream objoutstream = new ObjectOutputStream(socket.getOutputStream());
output.skip(sendBytes.length * 0);// 表示读取位置从第0 个BUFFER文件块读取;由这个可以实现断点续传;
int k = 0, i = 0;
while (true) {

i = output.read(sendBytes);// 从文件输入流读取4k到buffer中,当读到文件末尾时返回-1;
buffer.put("data", sendBytes);
buffer.put("int", k);
if (i < 4096) {// 当读到的内容少于4096时候。说明已经读完了文件
if (i > 0) {
byte[] finalbuffer = new byte[i];// 最后一次写入的文件不足4096字节
for (int j = 0; j < i; j++)
finalbuffer[j] = sendBytes[j];// 为了保证文件后面不会出现空白的0
buffer.put("int", k);
buffer.put("data", finalbuffer);
objoutstream.writeUnshared(buffer);
buffer.put("int", -1);// 告诉对面文件已经全部发送完成
objoutstream.writeUnshared(buffer);
break;
}
else {// 这个情况表示正好文件大小是4096的整数倍,上一次是4096但是这一次已经是-1了不能带入上面的;
buffer.put("int", -1);

objoutstream.writeUnshared(buffer);
break;
}

}

objoutstream.writeObject(buffer);// 写入类输出流,由于类的输出流出口是SOCKET,于是在这里发送出去;
objoutstream.reset();// 重置类输出流的所以状态,以免由于发送同一个地址的东西出现重复内容;

k++;

}

System.out.println("发送完毕,共文件块" + k + "个");

}
}

这里只要保存好int里面的值就可以实现传输中断后再次不覆盖传输,相当于断点续接,当然,要改写入方式为追加~;

这里特别要注意是writeObject 不重置的话会出现每次发送的都是第一个hashmap;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息