Java Socket实现文件上传(发送)

Java基础 专栏收录该内容
75 篇文章 0 订阅

Socket套接字是网络通信中的基本操作单元,我们不仅可以Socket发送和接收字符串,还可以通过输入输出流进行文件的上传或发送。

TCP协议实现文件上传(发送)

TCP协议实现文件上传,即使用ServerSocket和Socket进行文件的上传和接收。

在发送端(客户端)我们需要通过输入流读取需要上传的文件的字节流,再通过socket的输出流将字节数据源源不断地发送出去。

例如:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientSocketTest {
	public static void main(String args[]) throws Exception {
		// 要连接的服务端IP地址和端口
		String host = "127.0.0.1";
		int port = 55533;
		// 与服务端建立连接
		Socket socket = new Socket(host, port);
		// 建立连接后获得输出流
		OutputStream outputStream = socket.getOutputStream();
		
		InputStream ins = new BufferedInputStream(new FileInputStream("Java 网络编程基础.png"));
		byte[] message = new byte[1024];
		System.out.println("客户端正在上传文件...");
		while (ins.read(message) != -1) {
			outputStream.write(message);
		}
		outputStream.flush();
		outputStream.close();
		ins.close();
		System.out.println("服务器上传完毕");
		socket.close();
	}
}

在接收端(服务端)我们需要通过ServerSocket的输入流读取需要接收的文件的字节流,再通过输出流将字节数据写成文件。

例如:

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketTest {
	public static void main(String[] args) throws Exception {
		// 监听指定的端口
		int port = 55533;
		ServerSocket server = new ServerSocket(port);
		// server将一直等待连接的到来
		System.out.println("server将一直等待连接的到来");
		Socket socket = server.accept();
		
		// 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
		InputStream inputStream = socket.getInputStream();
		byte[] bytes = new byte[1024];
		OutputStream outs = new BufferedOutputStream(new FileOutputStream("Java 网络编程基础2.png"));
		System.out.println("服务器正在接收文件...");
		while (inputStream.read(bytes) != -1) {
			outs.write(bytes);
		}
		outs.flush();
		inputStream.close();
		outs.close();
		System.out.println("服务器接收完毕");
		socket.close();
		server.close();
	}
}

UDP协议实现文件上传(发送)

UDP协议实现文件上传,即使用DatagramSocket进行文件的上传和接收。同样是在发送端通过输入流读取文件的字节数据,再在接收端通过输出流写出文件。

由于DatagramSocket对发送的DatagramPacket有大小的限制,我们不能一次性发送太大的数据包,所以需要将发送的文件分段发送,并且约定如果数据包的大小为0,则表示数据已经全部发送完毕,可以关闭socket。

例如:

发送端:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class DatagramSocketClientTest {
	public static void main(String[] args) {
		try {
			// 获取服务器的地址
			InetAddress addr = InetAddress.getByName("localhost");
			// 要发送的文件
			InputStream ins = new BufferedInputStream(new FileInputStream("Java 网络编程基础.png"));
			byte[] sendMsg = new byte[1024];
			System.out.println("客户端正在上传文件...");
			// 创建Socket对象
			DatagramSocket socket = new DatagramSocket();
			while (ins.read(sendMsg) != -1) {
				// 创建packet包对象,封装要发送的包数据和服务器地址和端口号
				DatagramPacket packet = new DatagramPacket(sendMsg, sendMsg.length, addr, 8088);
				//降低发送速率,防止丢包
Thread.sleep(10);
				// 发送消息到服务器
				socket.send(packet);
			}
			
			// 创建结束packet包对象
			byte[] endMsg = new byte[0];
			DatagramPacket packet = new DatagramPacket(endMsg, endMsg.length, addr, 8088);
			// 发送结束packet消息到服务器
			socket.send(packet);
			
			ins.close();
			// 关闭socket
			socket.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

接收端:

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class DatagramSocketServerTest {
	public static void main(String[] args) {
		try {
			// 要接收的报文
			byte[] bytes = new byte[1024];
			DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
			// 创建socket并指定端口
			DatagramSocket socket = new DatagramSocket(8088);
			System.out.println("服务器端正在等待客户端连接...");
			OutputStream outs = new BufferedOutputStream(new FileOutputStream("Java 网络编程基础2.png"));
			while(packet.getLength() != 0) {
				// 接收socket客户端发送的数据。如果未收到会一直阻塞
				socket.receive(packet);
				System.out.println("服务器正在接收文件...");
				outs.write(packet.getData());
			}
			outs.flush();
			outs.close();
			socket.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

}
  • 1
    点赞
  • 2
    评论
  • 9
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值