Java简单网络编程之如何使用Socket进行文件上传到指定文件夹

服务器端(ServerSocket)

先贴源码

package javaSE_exise.网络编程;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class 文件接收服务器 {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8888)) {
            while (true) {
                Socket cilentSocket = serverSocket.accept();
                InetAddress address = serverSocket.getInetAddress();
                System.out.println(address + "正在上传文件");
                // 图片名称
                String imgName = address.getHostAddress().replace(".", "-").concat(".jpg");
                try (BufferedInputStream bis = new BufferedInputStream(cilentSocket.getInputStream());
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\Codes\\Java_works\\excise-basic\\src\\javaSE_exise\\网络编程\\图片上传文件夹"+"\\"+imgName));
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(cilentSocket.getOutputStream()))) {
                    byte[] bytes = new byte[2048];
                    int len = -1;
                    while((len = bis.read(bytes))!=-1){
                        bos.write(bytes, 0, len);
                    }
                    bos.flush();
                    bufferedWriter.write("上传成功");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

要点如下:

1.new ServerSocket(你的端口号),调用accept()方法时候也就是启动服务器时候,如果没有被请求,则是阻塞状态,被请求以后会返回请求主机的socket

2.图像名称就是把主机号的 . 改为 - 并且命名为 .jpg

3.输入流是从网络输入过来的,所以cilentSocket调用.getInputStream()方法并且封装为效率更高的BufferedInputStream对象。

4.输出流输出的字节,是由文件字节流实例的,所以先实例出FileOutputStream(需要输出的文件路径),再用FileOutputStream去实例效率更高的BufferedOutputStream对象。

5.上传成功后需要发消息给客户端,自然需要字符输出流BufferedWriter对象,但流中的数据都是字节,需要使用OutputStreamWriter来转化成字符流OutputStreamWriter中的字节数据来自于cilentSocket对象的输出流,所以使用cilentSocket中的getOutputStream()方法获得cilentSocket的输出流来实例OutputStreamWriter

客户端cilentSocket

代码如下:

package javaSE_exise.网络编程;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
public class 文件发送 {
    public static void main(String[] args) throws UnknownHostException, IOException {
        try (Socket socket = new Socket("192.168.199.156", 8888);
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\ZH\\Pictures\\头像壁纸\\头像.jpg"));
                BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());) {
            byte[] bytes = new byte[2048];
            int len = -1;
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes,0,len);
            }
            bos.flush();
            socket.shutdownOutput();
            String line = bufferedReader.readLine();
            System.out.println(line);
        }
    }
}

要点如下:

1.实例套接字Socket时候需要两个参数,第一个是目标主机ip,第二个是目标主机监听的端口号

2.首先发送文件首先要考虑的是输入流,毕竟想上传文件,先得把文件流进来,才能经过java的逻辑流出去。想要读(流入)文件就需要FileInputStream(你的文件地址),又因为效率低,再通过BufferedInputStream包装FileInputStream

3.其次,就要考虑流出,也就是发送文件的问题,通过网络发送那就直接使用套接字,socket中的getOutputSteam()方法获得输出流,同样的效率低下,使用BufferedOutputStream包装提升新能

4.还要考虑服务器给客户端发消息的问题,消息使用字符输入流最方便性能也很棒,并且消息通过网络传递,所以使用套接字socket中的getInputStream()方法获得输入流,这种输入流是字节输入流,我们要转化成字符输入流,就要使用当前输入流去实例InputStreamReader对象,这样就转成了字符流,但是性能较差可用方法较少读起来比较麻烦,再用字符流实例化缓冲区字符流BufferedReader对象即可

5.最需要注意的是当所有的文件以字节形式存在内存中,也就是缓冲区时,我们清空缓冲区,发送了但是服务器端并不会读取消息因为服务器不确定客户端还有没有要发送的流所以并不会读,我们需要在发送结束后,要用socket对象来暂时结束输出流,也就是告诉服务器端,我的流发送结束了,你可以读了。这样服务器端才会读取客户端发送的流。

好的,这是一个比较常见的网络编程问题。你可以使用 JavaSocket 类来实现这个功能。具体步骤如下: 1. 创建一个 ServerSocket 对象,指定端口号,等待客户端连接。 2. 创建一个 Socket 对象,连接到服务器端口。 3. 获取本地文件夹中的文件列表,遍历文件列表,依次发送文件到服务器。 4. 在服务器端创建相应的文件夹,并将接收到的文件保存到该文件夹中。 以下是一个简单Java 代码示例: ```java import java.io.*; import java.net.*; public class FileTransfer { public static void main(String[] args) throws Exception { // 创建服务器端的 ServerSocket 对象 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器已启动,等待客户端连接..."); // 等待客户端连接 Socket socket = serverSocket.accept(); System.out.println("客户端已连接,开始传输文件..."); // 获取本地文件夹中的文件列表 File folder = new File("C:\\Users\\xxx\\Documents\\test"); File[] files = folder.listFiles(); // 创建输出流,发送文件 OutputStream os = socket.getOutputStream(); for (File file : files) { FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { os.write(buffer, 0, len); } fis.close(); } os.close(); // 在服务器端创建相应的文件夹,并将接收到的文件保存到该文件夹中 InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String folderName = br.readLine(); File newFolder = new File("C:\\Users\\xxx\\Documents\\" + folderName); newFolder.mkdir(); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) != -1) { FileOutputStream fos = new FileOutputStream(newFolder + "\\" + len + ".txt"); fos.write(buffer, 0, len); fos.close(); } is.close(); socket.close(); serverSocket.close(); System.out.println("文件传输完成!"); } } ``` 客户端的代码类似,只需要将输出流和输入流的方向反过来即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值