2010-12-08 4 views
4

현재 소켓 프로그래밍을 배우고 있으며 도움이 필요한 문제가 발생했습니다. 내가하려고하는 것은 웹 호스트에 연결하고 기본 페이지를 다운로드 한 다음 호스트와의 연결을 끊는 Java 클래스를 작성하는 것입니다. 이 작업을하기 위해 URLConnection을 사용하는 것이 더 간단하다는 것을 알고 있지만 소켓 클래스를 배우려고합니다. 웹 서버에 성공적으로 연결했지만 페이지를 가져 오는 데 어려움이 있습니다. 이것은 내가 지금까지 작업 (그리고 작동하지) 않은 것입니다 :소켓이있는 웹 페이지 얻기

import java.io.*; 
import java.net.*; 
import java.lang.IllegalArgumentException; 
public class SocketsFun{ 
    public static void main(String[] myArgs){ 
     // Set some variables 
     String theServer = null; 
     String theLine = null; 
     int thePort = 0; 
     Socket theSocket = null; 
     boolean exit = false; 
     boolean socketCheck = false; 
     BufferedReader theInput = null; 

     // Grab the server and port number 
     try{ 
      theServer = myArgs[0]; 
      thePort = Integer.parseInt(myArgs[1]); 
      System.out.println("Opening a connection to " + theServer + " on port " + thePort); 
     } catch(ArrayIndexOutOfBoundsException aioobe){ 
      System.out.println("usage: SocketsFun host port"); 
      exit = true; 
     } catch(NumberFormatException nfe) { 
      System.out.println("usage: SocketsFun host port"); 
      exit = true; 
     } 

     if(!exit){ 
      // Open the socket 
      try{ 
       theSocket = new Socket(theServer, thePort); 
      } catch(UnknownHostException uhe){ 
       System.out.println("* " + theServer + " does not exist"); 
      } catch(IOException ioe){ 
       System.out.println("* " + "Connection Refused"); 
      } catch(IllegalArgumentException iae){ 
       System.out.println("* " + thePort + " Not A Valid TCP/UDP Port."); 
      } 

      // Print out some stuff 
      try{ 
       System.out.println("Connected Socket: " + theSocket.toString()); 
      } catch(Exception e){ 
       System.out.println("* " + "No Open Socket"); 
      } 

      try{ 
       theInput = new BufferedReader(new InputStreamReader(theSocket.getInputStream())); 
       while ((theLine = theInput.readLine()) != null){ 
        System.out.println(theLine); 
       } 
       theInput.close(); 
      } catch(IOException ioe){ 
       System.out.println("* " + "No Data To Read"); 
      } catch(NullPointerException npe){ 
       System.out.println("* " + "No Data To Read"); 
      } 

      // Close the socket 
      try{ 
       socketCheck = theSocket.isConnected(); 
      } catch(NullPointerException npe){ 
       System.out.println("* " + "No Socket To Close"); 
      } 
     } 
    } 
} 

내가 걸려 모든 "컬" "살쾡이 - 덤프"에서 출력, 또는 "wget을 될 일을 뱉어이 클래스이다 "등 모든 도움을 주시면 대단히 감사하겠습니다.

+2

제쳐두고, 당신이하고있는 일에 대해 정말로 확신하지 않는 한'NullPointerException'을 잡아 내지 않기를 강력히 권장합니다. 'NullPointerException'은 대개 중대한 버그를 나타내며 스택 트레이스가있는 barf 프로그램을 사용하는 것이 일반적으로 매우 유용합니다. –

답변

6

올바른 생각을했지만 HTTP 요청을 제출하지 않았습니다. 보내기 :

GET/HTTP/1.1\r\nHost: <hostname\r\n\r\n

이 당신은 유사한 형식 다음 응답 받아야 형식을

[METHOD] [PATH] HTTP/1.1 [CRLF] 
Host: [HOSTNAME] [CRLF] 
OTHER: HEADERS [CRLF] 
[CRLF]

다음 - 헤더, 빈 줄, 데이터를. 자세한 내용은 HTTP 프로토콜을 참조하십시오.

EDIT 아마도 HTTP 요청 구문을 시작하는 데 도움이 될 것입니다. 그것은 매우 간단하고 일반적으로 알기에 좋은 것입니다. 터미널을 열고 netcat (권장) 또는 telnet을 사용하십시오. netcat google.com 80 또는 telnet google.com 80. 유형 : 당신이 요청 구문에 대한 느낌을 일단

HTTP/1.1 301 Moved Permanently 
Location: http://www.google.com/ 
Content-Type: text/html; charset=UTF-8 
Date: Thu, 09 Dec 2010 00:03:39 GMT 
Expires: Sat, 08 Jan 2011 00:03:39 GMT 
Cache-Control: public, max-age=2592000 
Server: gws 
Content-Length: 219 
X-XSS-Protection: 1; mode=block 

<HTML&<HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> 
<TITLE>301 Moved</TITLE></HEAD><BODY> 
<H1>301 Moved</H1> 
The document has moved 
<A HREF="http://www.google.com/">here</A>. 
</BODY></HTML>

, 그냥 다음, 소켓이 쓰기까지 라인을 읽어

GET/HTTP/1.1[ENTER] 
Host: google.com[ENTER] 
[ENTER]

나는 응답 (두 번째 수익을 folloowing)를 얻을 당신이하는 것처럼 서버가 닫힙니다.

+0

다음을 시도했지만 기쁨. 내가 도대체 ​​뭘 잘못하고있는 겁니까? \t \t \t // 서버에 \t \t \t 시도 { \t \t \t \t theOutput = 새로운 BufferedWriter로 (새의 OutputStreamWriter (theSocket.getOutputStream())) 요청을 보내기; \t \t \t \t 출력.쓰기 (httpHeader); \t \t \t} 캐치 (IOException이 IOE) { \t \t \t \t에서 System.out.println ("*"+ "소켓에 쓸 수 없습니다"); \t \t \t – Brian

+0

위의 편집 내용을 참조하십시오. 무슨 문제 있니? httpHeader의 내용은 무엇입니까? – Robert

+0

나는 서버에서 아무것도 얻지 못하고있다. 나는 이것을 "localhost"에 대해 실행하고 Wireshark를 사용하여 트랜잭션을 살펴 보았습니다. 그래서 어떤 일이 일어나고 있지만 서버에서 출력이 나오지 않습니다. 또한, httpHeader String = "GET/HTTP/1.1 \ r \ nHost :"+ theHost + "\ r \ n \ r \ n"; – Brian

0

소켓의 출력 스트림에 무엇인가를 써야합니다. 웹 서버는 아무 것도 보내기 전에 클라이언트의 요청을 기다립니다. "GET"을 쓰면 서버에 기본 페이지를 반환 할 것인지 묻습니다.

서버가 영원히 기다릴 수 있도록 코드에 아무 것도 쓰지 않습니다.

+0

글쎄요, 몇 분에서 몇 초까지 시간이 걸릴 것입니다. 그렇습니다. – Robert

+0

예. "영원히"여기 조금 비 유적이다 :) –