使用套接字获取图像的问题

时间:2013-11-17 08:58:28

标签: java

我正在使用套接字编写代理服务器,现在它似乎“工作”或多或少,但我现在遇到的问题是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的帮助!

2 个答案:

答案 0 :(得分:1)

您似乎不了解HTTP和HTML的工作原理。

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

<img src="logo.png"/>

因此它向URL http://google.com/logo.png发送新的HTTP请求。服务器发送包含徽标图像字节的响应。

如果您的代码只向http://google.com发送了一个请求,那么您将永远不会获得该徽标。

答案 1 :(得分:0)

HTTP代理比你在这里做的要简单得多。

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