socket通信,完成文件传输
本文是一个基于TCP,一对多的文件传输小案例代码如下:
服务端:
/**
* 服务端
* */
public class server extends ServerSocket {
/**
* 构造函数
* */
public server()throws IOException{
super(8999);
}
/**
* 连接
* */
public void load()throws Exception{
System.out.println("等待连接------------");
while(true){
Socket socket = this.accept();
System.out.println("IP:"+socket.getInetAddress()+"已连接");
new Thread(new mutiClient(socket),"客户端1").start();
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args){
try{
server s = new server();
s.load();
}catch (Exception e){
e.printStackTrace();
}
}
}
/**
* 线程类
* */
class mutiClient implements Runnable{
private Socket socket;
private ObjectInputStream ois;
private FileOutputStream oos;
public mutiClient(Socket socket){
this.socket = socket;
}
@Override
public void run(){
try {
ois = new ObjectInputStream(socket.getInputStream());
String fileName = ois.readUTF();
long fileLength = ois.readLong();
File directory = new File("E:\\socket");
if (!directory.exists()) {
directory.mkdir();
}
File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);
oos = new FileOutputStream(file);
System.out.println("-------开始接收文件-------");
byte[] bytes = new byte[1024];
int length = 0;
while((length = ois.read(bytes, 0, bytes.length)) != -1) {
oos.write(bytes, 0, length);
oos.flush();
}
System.out.println("-------文件接收成功 -------");
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
ois.close();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
/**
* 客户端
* */
public class client extends Socket{
private Socket client;
/**
* 构造方法
* @throws IOException
* */
public client() throws IOException {
super("127.0.0.1",8999);
this.client = this;
System.out.println("**->"+client.getInetAddress()+"已成功连接服务器");
}
/**
* 发送文件
* @param file
* @throws Exception
* */
public void sendFile(File file)throws Exception{
FileInputStream ois = new FileInputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeUTF(file.getName());
oos.flush();
oos.writeLong(file.length());
oos.flush();
// 开始传输文件
System.out.println("开始传送-----------------");
byte[] bytes = new byte[1024];
int length = 0;
long pro = 0;
while ((length = ois.read(bytes, 0, bytes.length)) != -1) {
oos.write(bytes, 0, length);
oos.flush();
pro += length;
}
System.out.println();
System.out.println("传送结束----------------");
ois.close();
oos.close();
}
public static void main(String[] args){
try{
client c = new client();
c.sendFile(new File("E:\\User.bat"));
}catch (Exception e){
e.printStackTrace();
}
}
}
可以同时开启多个客户端进行文件发送,一个服务端进行接收。
知识点:
TCP的socket通信有三次握手的一个过程:
Socket socket = server.accept();
服务端的accept()方法一直在端口侦听连接到的套接字,并接受它。该方法将阻塞直
到建立连接。
在进行初步连接的时候,客户端要知道服务端的Ip地址和端口号即套接字。而服务端要指定端口号
二.序列化和反序列化
将对象序列化存储在磁盘上,再反序列化读取的一个过程。 1.首先定义一个类User,该类的对象要实现序列化,就要实现Serializable接口。 2.下来就可以进行序列化操作:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("E:\\User.bat")));
User user1 = new User("1410064201","杜涛",22,"陕西榆林");
oos.writeObject(user1);
ObjectOutputStream中的writeObject()方法可以写入对象,原始数据类型可以使用DataOutputStream写入,也可以使用该方法写入
3. 反序列化操作:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:\\User.bat")));
User user1 = (User)ois.readObject();
readObject()方法在反序列化的时候,必须保持和序列化每一步相同的类型,即读取的顺序不能变,在反序列化的过程中,我们需要强转类型,因为在之前,我们把数据都封装在某个文件中,往出拿的时候才知道是什么类型。 |