图片上传

首先,在这里我描述以下,我在实现图片上传时遇到的问题。

1、首先运行服务端,然后运行客户端,服务器端输出提示:图片已接收完毕,但是客户端并没有接收到服务器端的响应结果,我仔仔细细的走了一遍流程,最后发现是在客户端上传完图片的时候,刷新输出管道,关闭本地输入管道之后,需要主动将socket管道shutdowmOutput

// 通知服务器端,客户端已经上传完毕。
        socket.shutdownOutput();

这样子服务器端才能知道你的文件上传完毕,才能往下执行发送给客户端响应消息的代码,否则若客户端为shutdonw掉socket的管道,服务器端会一直以为你还在给它传数据,但其实管道里面没有字节在传输,但是output管道还是通的,服务器代码就不会往下执行。

2、第二个问题就是,既然是使用ip访问本机服务器,那么非本机是否也是可以通过本机外网的ip访问到自己本机的服务器,那么我就用室友的电脑试了一试(由于服务器不是在公网ip上,所以两台电脑要在同一个wifi下才可以),但是怎样也连接不上,于是我就使用cmd去在室友的电脑上ping自己电脑的ip是可以ping通的,那么就不是室友的电脑问题,那自然也不是代码的问题,因为自己电脑上开了好几个客户端都可以成功。最后经过工作室的老师的提示下,发现自己电脑的防火墙是全开着的(windows10)

java文件上传js java文件上传接口没有响应_客户端


可以看到,三个防火墙都是开着的,注意的是有一个防火墙显示(使用中),一定要关闭这个防火墙,室友的电脑才可以成功将图片上传至你的服务器。(很有气人的一件事就是,一开始我将域网络的防火墙关了,发现还是不行,然后辗转反侧才发现有个使用中的防火墙开着,我灵机一动,将他一贯,非本机客户端一运行,ok了,真的是茅塞顿开的感觉,就喜欢这种成就感)

若有不懂,联系qq:1620460256,无偿帮助,共同进步!!!

具体实现代码如下:

客户端代码实现:

/**
 * 文件上传
 *      客户端
 *      服务端 IP:127.0.0.1 端口:7777
 *      SRC_FILE: D:\相册\头像\2.jpg
 *      DEST_FILE: D:\相册\服务器图片仓库
 */
public class FileUploadClient {
    public static String SRC_FILE = "D:\\相册\\头像\\2.jpg";
    public static void main(String[] args) throws Exception {
        System.out.println("=======客户端启动======");
        System.out.println(InetAddress.getLocalHost());
//        1、请求服务器socket管道
        Socket socket = new Socket("192.168.137.1", 6655);
//        2、冲socket管道中获取一个字节输出流
        OutputStream os = socket.getOutputStream();
//        3、将低级的输出流包装成高级的字节缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(os);
//        4、读取本地的文件到bos中,复制
        System.out.println("文件名称为:"+new File(SRC_FILE).getName());
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(SRC_FILE));
//        5、读多少倒多少
        byte[] buffer = new byte[1024];
        int len;
        while((len = bis.read(buffer)) != -1){
            bos.write(buffer,0,len);
        }
        bos.flush();
        bis.close();
        System.out.println("客户端已将文件数据上传完毕!");
        // 通知服务器端,客户端已经上传完毕。
        socket.shutdownOutput();

        // 接收服务器响应消息
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//        System.out.println(br);
        System.out.print("服务器响应消息:");
        System.out.println(br.readLine());
    }
}

8.2 服务器端代码实现

服务端采用了多线程为每个客户端管道分配一个线程,上传文件,当然这样子的方式在项目中是不可取的,因为一旦客户端太多,服务器会因为创建线程维护线程的运行太多,而宕机,这里仅仅是为了实现图片上传的代码

public class FileUploadServer {
    public static String DEST_FILE = "D:\\相册\\服务器图片仓库\\";
    public static void main(String[] args) throws Exception{
        System.out.println("=====服务端启动======");
        // 1、先创建服务器管道 socket
        ServerSocket serverSocket = new ServerSocket(6655);

        while(true){
            //        2、等待接收客户端 socket
            Socket socket = serverSocket.accept();
            System.out.println("用户信息"+socket);
//            2.1 为当前客户端管道分配一个独立的线程来处理通信
            new ServerReadThread(socket).start();
        }

    }
}

// 线程代码
public class ServerReadThread extends Thread {
    private Socket socket;

    public ServerReadThread(Socket socket){
        this.socket = socket;
//        System.out.println(socket);
    }

    @Override
    public void run() {
       try{
//        3、从socket获取字节输入流
           InputStream is = socket.getInputStream();
           System.out.println(socket.getRemoteSocketAddress()+"上线了");
//        4、将低级的字节输入流包装成高级的字节输入流
           BufferedInputStream bis = new BufferedInputStream(is);
//        5、获取本地的文件输出流,将接收到的文件写入本地文件夹中
           FileOutputStream os = new FileOutputStream(DEST_FILE + UUID.randomUUID().toString()+".jpg");
           System.out.println("新文件名为:"+DEST_FILE + UUID.randomUUID()+".jpg");
//           6、创建一个本地文件输出流
           BufferedOutputStream bos = new BufferedOutputStream(os);

           byte[] buffer = new byte[1024];
           int len;
           while((len = bis.read(buffer)) != -1){
               bos.write(buffer,0,len);
           }
//          刷新、关闭本地IO管道
           bos.flush();
           bos.close();

//         服务器响应接收成功结果
           PrintStream ps = new PrintStream(socket.getOutputStream());
           ps.println("亲爱的客户端,你上传的图片,我已接收完毕!");
           ps.flush();

           Thread.sleep(1000);
       }catch (Exception e){
           System.out.println(socket.getRemoteSocketAddress()+"下线了");
       }
    }
}