Java 使用套接字获取图像时出现问题

Java 使用套接字获取图像时出现问题,java,Java,我正在使用套接字编写一个代理服务器,现在它似乎或多或少“工作”,但我现在遇到的问题是URL的图像没有返回到浏览器,只返回文本 代码如下: //create inputstream to receive the web page from the host BufferedInputStream inn = new BufferedInputStream(clientURLSocket.getInputStream()); //create outputstream to send the

我正在使用套接字编写一个代理服务器,现在它似乎或多或少“工作”,但我现在遇到的问题是URL的图像没有返回到浏览器,只返回文本

代码如下:

//create inputstream to receive the web page from the host
BufferedInputStream inn = new    BufferedInputStream(clientURLSocket.getInputStream());
//create outputstream to send the web page to the client
BufferedOutputStream outt = new BufferedOutputStream(clientSocket.getOutputStream());
URL u = new URL("http://"+url);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
   byte[] chunk = new byte[1024];
   int bytesRead;
   InputStream stream = u.openStream();
   while ((bytesRead = stream.read(chunk)) > 0) {
      outputStream.write(chunk, 0, bytesRead);
   }
} catch (IOException e) {
   e.printStackTrace();
}
outt.write(outputStream.toByteArray());
outt.flush();
也许ByteArrayOutputStream不适合接收图像

编辑(很抱歉反应太晚):

这是我的新代码:

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class Server {


public void startServer() {
    final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);

    Runnable serverTask = new Runnable() {
        @Override
        public void run() {
            try {
                @SuppressWarnings("resource")
                ServerSocket serverSocket = new ServerSocket(8080);
                while (true) {
                    Socket clientSocket = serverSocket.accept();
                    Socket clientURLSocket = serverSocket.accept();
                    clientProcessingPool.submit(new ClientTask(clientSocket));
                    clientProcessingPool.submit(new ClientTask(clientURLSocket));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };
    Thread serverThread = new Thread(serverTask);
    serverThread.start();

}

private class ClientTask implements Runnable {
    private Socket clientSocket;
    private Socket clientURLSocket;

    private ClientTask(Socket clientSocket) {
        this.clientSocket = clientSocket;
        this.clientURLSocket = clientSocket;
    }

    @Override
    public void run() {

        try {

            String url = null;
            String curl = null;
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));


            String buffer;
            while ((buffer = in.readLine()) != null) {
                //System.out.println(buffer);
                if(buffer.contains("GET"))
                {
                    String[] splitText = buffer.split(" ");
                    curl = splitText[1];
                    System.out.println(curl);
                    }
                if(buffer.contains("Host"))
                    {
                    //parse the host
                    url = buffer.replace("Host: ", "");
                    System.out.println(url);
                    }

                if (buffer.isEmpty()) break;
                }

            //String IP = InetAddress.getByName(url).getHostAddress().toString();                

            //new socket to send the information over

            clientURLSocket = new Socket(url, 80);

          //get data from a URL

        /*    URL host = new URL("http://"+url);

            URLConnection urlConnection = host.openConnection();
            InputStream input = urlConnection.getInputStream();

            int data = input.read();
            while(data != -1){
                System.out.print((char) data);
                data = input.read();
            }
            input.close();*/


            //create inputstream to receive the web page from the host
            BufferedInputStream inn = new BufferedInputStream(clientURLSocket.getInputStream());
            //create outputstream to send the web page to the client
            BufferedOutputStream outt = new BufferedOutputStream(clientSocket.getOutputStream());

                URL u = new URL(curl);
                HttpURLConnection connection = null;
                connection = (HttpURLConnection) u.openConnection();
                connection.connect();
                //ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

                try {
                    byte[] chunk = new byte[1024];
                    int bytesRead;
                    InputStream stream = connection.getInputStream();

                    while ((bytesRead = stream.read(chunk)) > 0) {
                        //outputStream.write(chunk, 0, bytesRead);
                        outt.write(chunk, 0, bytesRead);
                        outt.flush();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }

                //outt.write(outputStream.toByteArray());
                //outt.flush();


            outt.close();
            inn.close();
            clientURLSocket.close();
          /*  
            out.close();
            in.close();
            clientSocket.close();

   */
        } catch (IOException e) {
            e.printStackTrace();

        }
    }
}
}

现在的问题是google.com运行良好(它显示了所有的图像和文本),但例如youtube.com运行不好(它也显示了文本和图像,但网络没有完全显示出来,而且是无序的)

我在这段代码中遗漏了什么


顺便说一下,谢谢EJP&JB Nizet的帮助

您似乎不明白HTTP和HTML是如何工作的

当您使用浏览器转到时,将发送第一个请求以获取HTML页面。服务器响应包含HTML标记,并且仅包含该标记。然后浏览器读取并解析此HTML标记,并查看它是否包含(例如)


因此,它向URL发送一个新的HTTP请求。服务器发送包含徽标图像字节的响应


如果您的代码只向发送一个请求,您将永远无法获得徽标

HTTP代理比您在这里所做的要简单得多


您应该连接到connect命令中指定的URL。不解析GET和HOST头。处理完CONNECT命令后,剩下的只是来回复制字节

您根本不需要ByteArrayOutputStream。只需读取输入套接字并写入输出套接字。您使用ByteArrayOutputStream所做的只是增加不必要的延迟。嗨,EJP,谢谢您的回答,但我仍然遇到同样的问题,我已经删除了ByteArrayOutputStream,现在我直接在BufferedOutputStream上写入:outt.write(chunk,0,bytesRead);究竟是什么问题?你确定图像检索是通过这个代码进行的吗?嗨,问题是当我连接到google.com(例如)时,我只得到文本,而没有得到google徽标(图像)。问题是我不知道我做错了什么…你能回答我的问题吗?“您确定图像检索要通过此代码进行吗?”下面是另一个问题:您是否正在执行
httpconnect
命令?你是否以正常的方式告诉客户端这个HTTP代理的存在?那么,我必须向URL发送几个请求?我该怎么做?我必须遵循什么过程?您必须向要检索的每个资源的URL发送请求。如果需要该页面,请向该页面的URL发送请求。如果需要徽标,请向徽标的URL发送请求。如果你能为一个URL做这件事,你应该能为210或10000做这件事。请查看我发布的新代码,现在我得到另一个错误。
<img src="logo.png"/>