Java 如何通过同一套接字连接发送图像和文本

Java 如何通过同一套接字连接发送图像和文本,java,sockets,http,bufferedinputstream,Java,Sockets,Http,Bufferedinputstream,我有一个(非常难看的)方法,从一个网站上获取一个页面和页面上的所有图像。获取网页完全没有问题。但当我拿到这些图片时,它们都显得很奇怪,而且肯定不像它们发送到的地方。 我用于测试的uri是这样的:这个网页非常简单,包含了测试所需的一切 使用\r\n或\r\n作为结束符会产生不同的结果,\r\n甚至无法打开图像 public static String GET(String uri, int port) throws IOException { String domain = ur

我有一个(非常难看的)方法,从一个网站上获取一个页面和页面上的所有图像。获取网页完全没有问题。但当我拿到这些图片时,它们都显得很奇怪,而且肯定不像它们发送到的地方。 我用于测试的uri是这样的:这个网页非常简单,包含了测试所需的一切

使用\r\n或\r\n作为结束符会产生不同的结果,\r\n甚至无法打开图像

public static String GET(String uri, int port) throws IOException {

        String domain = uri.split("/",2)[0];
        String filename = uri.split("/",2)[1];
        Socket socket = new Socket(domain, port);


        // send the command to the server.
        System.out.println(socket.isConnected());
        DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String request = "GET " +"/"+ filename + " HTTP/1.1 "+"\r\n"+"Host: " + domain + "\r\n\r\n";
        System.out.println(request);
        outToServer.writeBytes(request);

        //create a file to write in.
        File file = new File(domain+".txt");
        // if file doesnt exists, then create it
        if (!file.exists()) {
            file.createNewFile();
        }
        PrintWriter writer = new PrintWriter(file);
        writer.print("");
        writer.close();

        int characterCounter=100;
        while(characterCounter >= 0){
            String serverSentence = inFromServer.readLine();
            System.out.println(serverSentence);
            if (serverSentence.startsWith("Content-Length:")){
                characterCounter = Integer.parseInt(serverSentence.replace("Content-Length: ",""));
            }
            if ( !serverSentence.startsWith("Cache-Control: ") && !serverSentence.startsWith("Content-Type: ") && !serverSentence.startsWith("Date: ") && !serverSentence.startsWith("Etag: ")
                    && !serverSentence.startsWith("Expires: ") && !serverSentence.startsWith("Last-Modified: ") && !serverSentence.startsWith("Server: ") && !serverSentence.startsWith("Vary: ")
                    && !serverSentence.startsWith("X-Cache: ") && !serverSentence.startsWith("Content-Length: ") ){
                characterCounter = characterCounter - serverSentence.length()-1;
            }

            //write in the file
            FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(serverSentence+"\r\n");
            bw.close();
        }


        Document doc = Jsoup.parse(file, "UTF-8");
        Elements imgs = doc.getElementsByTag("img");

        System.out.println(imgs);


        for (Element link : imgs) {
            String source = link.attr("src");

            source = source.replace("http://"+domain+"", "");

            System.out.println(source);


            //create a file to write in.
            File image = new File(source.replace("/", "."));
            // if file doesnt exists, then create it
            if (!image.exists()) {
                image.createNewFile();
            }

            PrintWriter imageWriter = new PrintWriter(image);
            imageWriter.print("");
            imageWriter.close();

            String requestImage = "GET "+ source + " HTTP/1.1 "+"\r\n"+"Host: " + domain + "\r\n\r\n";
            System.out.println(requestImage);
            outToServer.writeBytes(requestImage);

            boolean flag = false;
            String previousServerSentence = "something not empty";
            characterCounter=100;
            while(characterCounter > 0){
                String serverSentence = inFromServer.readLine();
                System.out.println(serverSentence);
                if (serverSentence.startsWith("Content-Length:")){
                    characterCounter = Integer.parseInt(serverSentence.replace("Content-Length: ",""));
                }

                if (!flag){
                    if ( previousServerSentence.matches("") && !serverSentence.matches("")){
                        flag = true;
                    }
                }

                if ( (!serverSentence.startsWith("Cache-Control: ") && !serverSentence.startsWith("Content-Type: ") && !serverSentence.startsWith("Date: ") && !serverSentence.startsWith("Etag: ")
                        && !serverSentence.startsWith("Expires: ") && !serverSentence.startsWith("Last-Modified: ") && !serverSentence.startsWith("Server: ") && !serverSentence.startsWith("Vary: ")
                        && !serverSentence.startsWith("X-Cache: ") && !serverSentence.startsWith("Content-Length: ") && !serverSentence.startsWith("ETag: ") && !serverSentence.startsWith("Accept-Ranges: ")
                        && !serverSentence.startsWith("Accept-Language: ") && !serverSentence.startsWith("Accept-Datetime: ") && !serverSentence.startsWith("Authorization: ") 
                        && !serverSentence.startsWith("Connection: ") && !serverSentence.startsWith("Content-Language: ") && !serverSentence.startsWith("Content-Length: ") 
                        && !serverSentence.startsWith("Content-Location: ")  && !serverSentence.startsWith("Content-MD5: ")  && !serverSentence.startsWith("Content-Range: ")
                        && !serverSentence.startsWith("Content-Type: ")  && !serverSentence.startsWith("Date: ")  && !serverSentence.startsWith("expect: ")
                        && !serverSentence.startsWith("From: ") && !serverSentence.startsWith("Host: ") && !serverSentence.startsWith("If-Match: ") && !serverSentence.startsWith("If-Modified-Since: ")
                        && !serverSentence.startsWith("Accept: ") && !serverSentence.startsWith("Accept-Charset: ") && !serverSentence.startsWith("Accept-Encoding: ")
                        && !serverSentence.startsWith("Age: ") && !serverSentence.startsWith("Allow: ") && !serverSentence.startsWith("Content-Encoding: ")
                        && !serverSentence.startsWith("If-None-Match: ") && !serverSentence.startsWith("If-Range: ") && !serverSentence.startsWith("If-Unmodified-Since: ")
                        && !serverSentence.startsWith("Last-Modified: ") && !serverSentence.startsWith("Location: ") && !serverSentence.startsWith("Max-Forwards: ")
                        && !serverSentence.startsWith("Pragma: ") && !serverSentence.startsWith("Proxy-Authenticate: ") && !serverSentence.startsWith("Proxy-Authorization: ")
                        && !serverSentence.startsWith("Range: ") && !serverSentence.startsWith("Referer: ") && !serverSentence.startsWith("Retry-After: ")
                        && !serverSentence.startsWith("Server: ") && !serverSentence.startsWith("TE: ") && !serverSentence.startsWith("Trailer: ")
                        && !serverSentence.startsWith("Transfer-Encoding: ") && !serverSentence.startsWith("Upgrade: ") && !serverSentence.startsWith("User-Agent: ")
                        && !serverSentence.startsWith("Via: ") && !serverSentence.startsWith("Warning: ") && !serverSentence.startsWith("WWW-Authenticate: "))
                        && flag){
                    characterCounter = characterCounter - serverSentence.length()-1;
                    //write in the file

                    FileWriter fw = new FileWriter(image.getAbsoluteFile(),true);
                    BufferedWriter bw = new BufferedWriter(fw);
                    bw.write(serverSentence+"\r");
                    bw.close();


                }

                previousServerSentence = serverSentence;
            }


        }
        return null;
    }

第一个图像用于\r作为端点,第二个图像用于\n作为端点,最后一个图像是原始图像。我完全不知道为什么图像会被搞得这么糟

所以我的问题是:为什么会发生这种情况,我该如何解决

编辑:

publicstaticstringget(stringuri,int-port)抛出IOException{
/*
*网页的检索
*/
String domain=uri.split(“/”,2)[0];
字符串filename=uri.split(“/”,2)[1];
套接字=新套接字(域、端口);
//将命令发送到服务器。
System.out.println(socket.isConnected());
DataOutputStream outToServer=新的DataOutputStream(socket.getOutputStream());
BufferedReader INFOROMSERVER=新的BufferedReader(新的InputStreamReader(socket.getInputStream());
String request=“GET”+“/”+filename+”HTTP/1.1“+”\r\n“+”主机:“+domain+”\r\n\r\n”;
系统输出打印项次(请求);
outToServer.writeBytes(请求);
//创建要写入的文件。
文件文件=新文件(域+“.txt”);
//如果文件不存在,则创建它
如果(!file.exists()){
createNewFile();
}
PrintWriter=新的PrintWriter(文件);
作者:印刷体(“”);
writer.close();
int characterCounter=100;
而(字符计数器>=0){
字符串ServerSession=INFOROMSERVER.readLine();
System.out.println(服务器语句);
if(server句子.startsWith(“内容长度:”){
characterCounter=Integer.parseInt(server句子.replace(“内容长度:”,“”));
}
如果(!ServerSession.StartWith(“缓存控制:”)&&!ServerSession.StartWith(“内容类型:”)&&!ServerSession.StartWith(“日期:”)&&!ServerSession.StartWith(“Etag:”)
&&!ServerSession.StartWith(“Expires:”)和&!ServerSession.StartWith(“Last Modified:”)和&!ServerSession.StartWith(“Server:”)和&!ServerSession.StartWith(“Variable:”)
&&!ServerSession.startsWith(“X-Cache:”)和&!ServerSession.startsWith(“内容长度:”){
characterCounter=characterCounter-ServerSession.length()-1;
}
//写入文件
FileWriter fw=新的FileWriter(file.getAbsoluteFile(),true);
BufferedWriter bw=新的BufferedWriter(fw);
write(服务器语句+“\r\n”);
bw.close();
}
/*
*检索网页上位于同一域的所有嵌入图像。
*/
documentdoc=Jsoup.parse(文件“UTF-8”);
元素imgs=doc.getElementsByTag(“img”);
系统输出打印项次(imgs);
用于(元素链接:imgs){
字符串源=link.attr(“src”);
source=source.replace(“http://“+domain+”,”);
系统输出打印项次(来源);
//创建要写入的文件。
文件映像=新文件(source.replace(“/”,“));
//如果文件不存在,则创建它
如果(!image.exists()){
image.createNewFile();
}
//初始化流。
最终文件输出流文件输出流=新文件输出流(图像);
final InputStream InputStream=socket.getInputStream();
//标题结束标志。
布尔头指向=假;
String requestImage=“GET”+source+”HTTP/1.1“+”\r\n“+”主机:“+domain+”\r\n\r\n”;
System.out.println(requestImage);
outToServer.writeBytes(requestImage);
int buffersize=1000000;
字节[]字节=新字节[buffersize];
整数长度;
而((长度=inputStream.read(字节))!=-1){
//如果已经到达头的末尾,则按正常方式将字节写入文件。
如果(有标题){
fileOutputStream.write(字节,0,长度);
}
//这将通过比较当前字节和接下来的3个字节来定位标头的结尾
//HTTP头的结尾为“\r\n\r\n”(以整数表示为13 10)。
//如果到达报头的末尾,则该标志将设置为true,并且报头中的剩余数据
//当前缓冲的字节数组写入文件。
否则{
对于(int i=0;i
这是我现在的结果:

我可以得到部分图片,但不能得到整个图片。玩buffersize会让我走得更远,甚至更远

我发现了错误。它只是和一些维度有关。 最终工作代码:

public static String GET(String uri, int port) throws IOException {

    /*
     * Retrieval of the webpage
     */

    String domain = uri.split("/",2)[0];
    String filename = uri.split("/",2)[1];
    Socket socket = new Socket(domain, port);


    // send the command to the server.
    System.out.println(socket.isConnected());
    DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    String request = "GET " +"/"+ filename + " HTTP/1.1 "+"\r\n"+"Host: " + domain + "\r\n\r\n";
    System.out.println(request);
    outToServer.writeBytes(request);

    //create a file to write in.
    File file = new File(domain+".txt");
    // if file doesnt exists, then create it
    if (!file.exists()) {
        file.createNewFile();
    }
    PrintWriter writer = new PrintWriter(file);
    writer.print("");
    writer.close();

    int characterCounter=100;
    while(characterCounter >= 0){
        String serverSentence = inFromServer.readLine();
        System.out.println(serverSentence);
        if (serverSentence.startsWith("Content-Length:")){
            characterCounter = Integer.parseInt(serverSentence.replace("Content-Length: ",""));
        }
        if ( !serverSentence.startsWith("Cache-Control: ") && !serverSentence.startsWith("Content-Type: ") && !serverSentence.startsWith("Date: ") && !serverSentence.startsWith("Etag: ")
                && !serverSentence.startsWith("Expires: ") && !serverSentence.startsWith("Last-Modified: ") && !serverSentence.startsWith("Server: ") && !serverSentence.startsWith("Vary: ")
                && !serverSentence.startsWith("X-Cache: ") && !serverSentence.startsWith("Content-Length: ") ){
            characterCounter = characterCounter - serverSentence.length()-1;
        }

        //write in the file
        FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(serverSentence+"\r\n");
        bw.close();
    }

    /*
     * Retrieval of all the embedded images on the webpage that are on the same domain.
     */

    Document doc = Jsoup.parse(file, "UTF-8");
    Elements imgs = doc.getElementsByTag("img");

    System.out.println(imgs);


    for (Element link : imgs) {

        // Getting the link ready for GET query.

        String source = link.attr("src");

        source = source.replace("http://"+domain+"", "");

        System.out.println(source);

        //create a file to write in.
        File image = new File(source.replace("/", "."));
        // if file doesnt exists, then create it
        if (!image.exists()) {
            image.createNewFile();
        }

        String requestImage = "GET "+ source + " HTTP/1.1 "+"\r\n"+"Host: " + domain + "\r\n\r\n";
        System.out.println(requestImage);
        outToServer.writeBytes(requestImage);

        // Initialize the streams.
        final FileOutputStream fileOutputStream = new FileOutputStream(image);
        final InputStream inputStream = socket.getInputStream();

        // Header end flag.
        boolean headerEnded = false;

        int buffersize = 10000;
        byte[] bytes = new byte[buffersize];
        int length;
        while ((length = inputStream.read(bytes)) != -1) {
            // If the end of the header had already been reached, write the bytes to the file as normal.
            if (headerEnded){
                fileOutputStream.write(bytes, 0, length);
            }
            // This locates the end of the header by comparing the current byte as well as the next 3 bytes
            // with the HTTP header end "\r\n\r\n" (which in integer representation would be 13 10 13 10).
            // If the end of the header is reached, the flag is set to true and the remaining data in the
            // currently buffered byte array is written into the file.
            else {
                for (int i = 0; i < length-3; i++) {
                    if (bytes[i] == 13 && bytes[i + 1] == 10 && bytes[i + 2] == 13 && bytes[i + 3] == 10) {
                        headerEnded = true;
                        fileOutputStream.write(bytes, i+4 , length-i-4);
                        break;
                    }
                }
            }
        }

        inputStream.close();
        fileOutputStream.close();

    }
    socket.close();
    return null;
}
publicstaticstringget(stringuri,int-port)抛出IOException{
/*
*网页的检索
*/
s
public static String GET(String uri, int port) throws IOException {

    /*
     * Retrieval of the webpage
     */

    String domain = uri.split("/",2)[0];
    String filename = uri.split("/",2)[1];
    Socket socket = new Socket(domain, port);


    // send the command to the server.
    System.out.println(socket.isConnected());
    DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    String request = "GET " +"/"+ filename + " HTTP/1.1 "+"\r\n"+"Host: " + domain + "\r\n\r\n";
    System.out.println(request);
    outToServer.writeBytes(request);

    //create a file to write in.
    File file = new File(domain+".txt");
    // if file doesnt exists, then create it
    if (!file.exists()) {
        file.createNewFile();
    }
    PrintWriter writer = new PrintWriter(file);
    writer.print("");
    writer.close();

    int characterCounter=100;
    while(characterCounter >= 0){
        String serverSentence = inFromServer.readLine();
        System.out.println(serverSentence);
        if (serverSentence.startsWith("Content-Length:")){
            characterCounter = Integer.parseInt(serverSentence.replace("Content-Length: ",""));
        }
        if ( !serverSentence.startsWith("Cache-Control: ") && !serverSentence.startsWith("Content-Type: ") && !serverSentence.startsWith("Date: ") && !serverSentence.startsWith("Etag: ")
                && !serverSentence.startsWith("Expires: ") && !serverSentence.startsWith("Last-Modified: ") && !serverSentence.startsWith("Server: ") && !serverSentence.startsWith("Vary: ")
                && !serverSentence.startsWith("X-Cache: ") && !serverSentence.startsWith("Content-Length: ") ){
            characterCounter = characterCounter - serverSentence.length()-1;
        }

        //write in the file
        FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(serverSentence+"\r\n");
        bw.close();
    }

    /*
     * Retrieval of all the embedded images on the webpage that are on the same domain.
     */

    Document doc = Jsoup.parse(file, "UTF-8");
    Elements imgs = doc.getElementsByTag("img");

    System.out.println(imgs);


    for (Element link : imgs) {

        // Getting the link ready for GET query.

        String source = link.attr("src");

        source = source.replace("http://"+domain+"", "");

        System.out.println(source);

        //create a file to write in.
        File image = new File(source.replace("/", "."));
        // if file doesnt exists, then create it
        if (!image.exists()) {
            image.createNewFile();
        }

        String requestImage = "GET "+ source + " HTTP/1.1 "+"\r\n"+"Host: " + domain + "\r\n\r\n";
        System.out.println(requestImage);
        outToServer.writeBytes(requestImage);

        // Initialize the streams.
        final FileOutputStream fileOutputStream = new FileOutputStream(image);
        final InputStream inputStream = socket.getInputStream();

        // Header end flag.
        boolean headerEnded = false;

        int buffersize = 10000;
        byte[] bytes = new byte[buffersize];
        int length;
        while ((length = inputStream.read(bytes)) != -1) {
            // If the end of the header had already been reached, write the bytes to the file as normal.
            if (headerEnded){
                fileOutputStream.write(bytes, 0, length);
            }
            // This locates the end of the header by comparing the current byte as well as the next 3 bytes
            // with the HTTP header end "\r\n\r\n" (which in integer representation would be 13 10 13 10).
            // If the end of the header is reached, the flag is set to true and the remaining data in the
            // currently buffered byte array is written into the file.
            else {
                for (int i = 0; i < length-3; i++) {
                    if (bytes[i] == 13 && bytes[i + 1] == 10 && bytes[i + 2] == 13 && bytes[i + 3] == 10) {
                        headerEnded = true;
                        fileOutputStream.write(bytes, i+4 , length-i-4);
                        break;
                    }
                }
            }
        }

        inputStream.close();
        fileOutputStream.close();

    }
    socket.close();
    return null;
}