使用套接字从服务器向客户端发送静态文件

时间:2015-12-31 18:12:18

标签: java

我在使用此代码时遇到了一些问题:

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

public class WorkerRunnable implements Runnable, HttpServer {

    protected Socket clientSocket = null;
    protected String serverText = null;
    protected Map<String, String> paramMap = null;



    private String OK = "HTTP/1.0 200 OK",
            NOT_FOUND = "HTTP/1.0 404 Not Found",
            BAD_REQUEST = "HTTP/1.0 400 Bad Request",
            FORBIDDEN = "HTTP/1.0 403 Forbidden",
            SERVER_ERROR = "HTTP/1.0 500 Internal Server Error";

    public WorkerRunnable(Socket clientSocket, String serverText) {
        this.clientSocket = clientSocket;
        this.serverText = serverText;
    }

    public void run() {
        try {



            paramMap = parse(clientSocket.getInputStream());
            // response(clientSocket.getOutputStream(), paramMap);
            response(clientSocket.getOutputStream(), paramMap);

        } catch (IOException e) {
            // report exception somewhere.
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, String> parse(InputStream is) throws IOException {
        Map<String, String> paramMap = new HashMap<String, String>();
        LineNumberReader lr = new LineNumberReader(new InputStreamReader(is));
        String inputLine = null;
        String method = null;
        String httpVersion = null;
        String uri = null;

        // read request line
        inputLine = lr.readLine();
        String[] requestCols = inputLine.split("\\s");
        method = requestCols[0];
        uri = requestCols[1];
        httpVersion = requestCols[2];
        System.out.println("http version:\t" + httpVersion);

        // read header
        while (StringUtils.isNotBlank(inputLine = lr.readLine())) {
            System.out.println("post header line:\t" + inputLine);
        }

        // parse GET param
        if (uri.contains("?")) {
            paramMap.putAll(parseParam(uri.split("\\?", 2)[1], false));
            System.out.println("get body:\t" + paramMap.toString());
        } else if (method.toUpperCase().equals("POST")) {
            // read body - POST method
            StringBuffer bodySb = new StringBuffer();
            char[] bodyChars = new char[1024];
            int len;

            // ready() make sure it will not block,
            while (lr.ready() && (len = lr.read(bodyChars)) > 0) {
                bodySb.append(bodyChars, 0, len);
            }
            paramMap.putAll(parseParam(bodySb.toString(), true));

            System.out.println("post body:\t" + bodySb.toString());
        } else {
            System.out.println("home");
        }

        return paramMap;
    }

    @Override
    public Map<String, String> parseParam(String paramStr, boolean isBody) {
        String[] paramPairs = paramStr.trim().split("&");
        Map<String, String> paramMap = new HashMap<String, String>();

        String[] paramKv;
        for (String paramPair : paramPairs) {
            if (paramPair.contains("=")) {
                paramKv = paramPair.split("=");
                if (isBody) {
                    // replace '+' to ' ', because in body ' ' is replaced by
                    // '+' automatically when post,
                    paramKv[1] = paramKv[1].replace("+", " ");
                }
                paramMap.put(paramKv[0], paramKv[1]);
            }
        }

        return paramMap;
    }

    @Override
    // public void response(OutputStream os, Map<String, String> paramMap) {
    // String name = StringUtils.isBlank(paramMap.get("name")) ? "xxx"
    // : paramMap.get("name");
    //
    // String comando = StringUtils.isBlank(paramMap.get("comando")) ? "xxx"
    // : paramMap.get("comando");
    //
    // PrintWriter pw = null;
    // pw = new PrintWriter(os);
    // pw.println("HTTP/1.1 200 OK");
    // pw.println("Content-type: text/html; Charset=UTF-8");
    // pw.println("");
    // pw.println("<h1>Hi <span style='color: #FFF; background: #000;'>"
    // + name + "</span> !</h1>");
    // pw.println("<h4>current date: " + new Date() + "</h4>");
    // pw.println("<p>you can provide your name via a param called <span style='color: #F00; background: yellow;'>\"name\"</span>, in both GET and POST method.</p>");
    // pw.flush();
    // pw.close();
    //
    // }
    public void response(OutputStream out, Map<String, String> paramMap) {
        File file = new File("pageClient.html");
        String mimeType = getMimeType(file);
        sendFile(file, mimeType, file.getName());
    }

    /* Sends the requested file to the client */
    public void sendFile(File file, String fileType, String fileName) {
        try {
            PrintStream send = new PrintStream(clientSocket.getOutputStream());
            // Buffer must not be to low, => fragments
            int length = 0; // (int) file.length();
            FileInputStream fileIn = new FileInputStream(fileName);
            byte[] bytes = new byte[1024];
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            /* Write until bytes is empty */
            while ((length = fileIn.read(bytes)) != -1 ){
                bos.write(bytes, 0, length);
                // send.write(bytes, 0, length);
                // send.flush();
            }
            bos.flush();
            bos.close();
            byte[] data1 = bos.toByteArray();

            System.out.print(new String(data1));
            send.print(OK);
            send.print("");
            send.print("Content-Type: " + fileType + "\r\n");
            send.println("");
            send.write(data1, 0, data1.length);
            send.println("");

            send.flush();
            send.close();

            fileIn.close();
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }

    /* Finds out the MIME type of the requested file */
    public String getMimeType(File f) {
        String file = f.toString();
        String type = "";
        if (file.endsWith(".txt")) {
            type = "text/txt";
        } else if (file.endsWith(".html") || file.endsWith("htm")) {
            type = "text/html; Charset=UTF-8";
        } else if (file.endsWith(".jpg")) {
            type = "image/jpg";
        } else if (file.endsWith(".png")) {
            type = "image/png";
        } else if (file.endsWith(".jpeg")) {
            type = "image/jpeg";
        } else if (file.endsWith(".gif")) {
            type = "image/gif";
        } else if (file.endsWith(".pdf")) {
            type = "application/pdf";
        } else if (file.endsWith(".mp3")) {
            type = "audio/mpeg";
        } else if (file.endsWith(".class")) {
            type = "application/octet-stream";
        } else if (file.endsWith(".mp4")) {
            type = "video/mp4";
        }
        return type;
    }
}

在评论中有一个方法response的可能解决方案,它工作正常!完美! 但我的目标是为response发送一个简单的文件“pageClient.html”,但我有一些问题需要这样做。

问题在于该功能:public void sendFile(File file, String fileType, String fileName)

我的代码的步骤是: 打开浏览器; 写链接:localhost:xxxx 并且服务器向我发送了homepage.html

看起来很简单: - (

但现在服务器只向我发送一个无效页面(浏览器,此外,下载它...) 有人可以帮我吗?!

1 个答案:

答案 0 :(得分:1)

尝试以下方法,我已根据评论方法web.config修改了sendFile()。 这应该有用。

response()

已编辑:较短版本而未在内存中加载文件

IOUtils来自Apache Commons IO库

public void sendFile(File file, String fileType, String fileName) {
    try {
        PrintStream send = new PrintStream(clientSocket.getOutputStream());
        // Buffer must not be to low, => fragments
        int length = 0; // (int) file.length();
        FileInputStream fileIn = new FileInputStream(fileName);
        byte[] bytes = new byte[1024];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        /* Write until bytes is empty */
        while ((length = fileIn.read(bytes)) != -1) {
            bos.write(bytes, 0, length);
            // send.write(bytes, 0, length);
            // send.flush();
        }
        bos.flush();
        bos.close();
        byte[] data1 = bos.toByteArray();

        String dataStr = new String(data1, "UTF-8");

        System.out.print(dataStr);
        send.println("HTTP/1.1 200 OK");
        send.println("Content-type: "+ fileType+ "; Charset=UTF-8");
        send.println("");
        send.println(dataStr);

        send.flush();
        send.close();

        fileIn.close();
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }
}