본문으로 건너뛰기

네트워크

레퍼런스 코드를 쭈욱 쳐보면서 느낌을 잡아보자

서버 / 클라이언트 두개로..

Server

public class ExampleNetworkServer {

public static void main (String[] args) throws IOException {

System.out.println("서버 : 대기");
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
System.out.println("서버 : 시작");

InetAddress inetAddr = socket.getInetAddress();
System.out.println("접속쪽의 IP 어드레스 : " + inetAddr.getHostAddress());

socket.close();
serverSocket.close();

System.out.println("처리종료");

}
}

이놈을 실행시켜 놓고

Client

public class ExampleNetworkClient {

public static void main (String[] args) throws IOException {

System.out.println("접속 시작");

Socket socket = new Socket("localhost", 9999);

InetAddress inetAddr = socket.getInetAddress();
System.out.println("접속하는곳의 IP 어드레스 : " + inetAddr.getHostAddress());

socket.close();

System.out.println("처리종료");

}
}
접속 시작
접속하는곳의 IP 어드레스 : 127.0.0.1
처리종료

서버쪽을 실행안하고 클라이언트만 실행해보면
이런식으로 익셉션이 발생한다

접속 시작
Exception in thread "main" java.net.ConnectException: 연결이 거부됨
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:579)
at java.base/sun.nio.ch.Net.connect(Net.java:568)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:633)
at java.base/java.net.Socket.connect(Socket.java:583)
at java.base/java.net.Socket.<init>(Socket.java:507)
at java.base/java.net.Socket.<init>(Socket.java:287)
at org.example.ExampleNetwork2.main(ExampleNetworkClient.java:13)

호스트 이름을 통해서 ip어드레스로 변환

public class Resolver {

public static void main(String[] args) throws UnknownHostException {

String hostName = "localhost";
InetAddress inetAddr = InetAddress.getByName(hostName);

System.out.println(hostName + " 의 IP어드레스 : " + inetAddr.getHostAddress());
}
}
localhost 의 IP어드레스 : 127.0.0.1

호스트명이 제대로 안되거나 하면 UnknownHostException 이 발생한다

Exception in thread "main" java.net.UnknownHostException: localhost1: 이름 혹은 서비스를 알 수 없습니다
at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:933)
at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1519)
at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:852)
at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1509)
at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1367)
at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1301)
at java.base/java.net.InetAddress.getByName(InetAddress.java:1251)
at org.example.Resolver.main(Resolver.java:11)

null 을 파라미터로 넣으면 ??

public class Resolver {

public static void main(String[] args) throws UnknownHostException {

String hostName = "localhost1";
InetAddress inetAddr = InetAddress.getByName(null); // 이렇게 null파라미터를 넣으면 127.0.0.1 !!

System.out.println(hostName + " 의 IP어드레스 : " + inetAddr.getHostAddress());
}
}
localhost1 의 IP어드레스 : 127.0.0.1

null 을 파라미터로 넣었을 경우에는 127.0.0.1 을 반환한다

IP어드레스를 호스트 명으로 변환

public class ReverseResolver {

public static void main(String[] args) throws UnknownHostException {

byte[] ipAddr = {127, 0, 0, 1};
InetAddress inetAddr = InetAddress.getByAddress(ipAddr);

System.out.println("127.0.0.1 의 호스트명은 : " + inetAddr.getHostName());
}
}
127.0.0.1 의 호스트명은 : localhost

중요한 포인트는 IP 어드레스는 각 자리가 0 ~ 255 이다
즉 최대 255.255.255.255 라는것.
근데 byte형은 -128 ~ 127 이 범위이다
그러므로 128이상의 숫자값이 들어가는 주소이면 byte 형으로 형변환을 해줘야 한다

통신이 도달 가능한지 확인

public class CheckReachable {

public static void main(String[] args) throws IOException {

String target = "192.168.0.100";
InetAddress inetAddr = InetAddress.getByName(target);

System.out.println(target + "으로 " + (inetAddr.isReachable(1000)
?
"도달가능"
:
"도달불가능"));
}
}
192.168.0.2으로 도달불가능

127.0.0.1로 주소를 바꾸고 실행하면 (도달 가능하면)

127.0.0.1으로 도달가능

isReachable(1000) 은 timeout 이다. 1000이면 1초후에 반환값이 오고 3000이면 3초후에 반환값이 온다

HTTP 통신의 응답코드를 취득

public class GetResponseCode {

public static void main(String[] args) throws IOException {

URL url = new URL(
"http://localhost:1313/"
+ "Docker/Docker-compose"
);

HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();

httpCon.setRequestMethod("GET");

System.out.println(
(HttpURLConnection.HTTP_OK == httpCon.getResponseCode())
? "정상" : "이상"
);

System.out.println(
"Response코드 [" + httpCon.getResponseCode() + "]"
);

httpCon.disconnect();
}
}
정상
Response코드 [200]

PathParameters 를 문자열 결합식으로 URL 에 + 로 결합해서 요청을 보낼 수 있구나

HTTP 통신을 자동적으로 리다이렉트 할지 안할지 설정

public class FollowRedirects {

public static void main(String[] args) throws IOException {

System.out.println("리다이렉트를 따를 경우");
FollowRedirects.sendRequest(true);

System.out.println("리다이렉트를 따르지 않을 경우");
FollowRedirects.sendRequest(false);

}

private static void sendRequest(boolean redirectFlg) throws IOException {

URL url = new URL(
"http://localhost:1313/"
+ "Docker/Docker-compose/"
);

// HTTP 접속을 시작
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();

// GET 리퀘스트로 셋팅
httpCon.setRequestMethod("GET");

httpCon.setInstanceFollowRedirects(redirectFlg);

System.out.println(
"Response 코드 [" + httpCon.getResponseCode() + "]"
);

BufferedReader reader = new BufferedReader(
new InputStreamReader(httpCon.getInputStream())
);

String line;

while (null != (line = reader.readLine())) {
System.out.println(line);
}

reader.close();

// HTTP 접속을 끊는다
httpCon.disconnect();
}
}
리다이렉트를 따를 경우
Response 코드 [200]
<!DOCTYPE html>
<html lang="ko"><head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
.
.
.
생략
.
.
다이렉트를 따르지 않을 경우
Response 코드 [200]
<!DOCTYPE html>
<html lang="ko"><head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
.
.
생략

예제가 좀 이상하다 -_-;;
오래된 책이라 그런가 ㅋ
암튼 설명좀 끄적..
HttpURLConnection.getResponseCode 메서드의 파라미터에 의해서 리다이렉트를 따를 것인지 그러지 않을 것인지 결정할 수 있다

음.. 원래는

다이렉트를 따르지 않을 경우
Response 코드 [302]

이렇게 나와야 정상 이라고 한다 -_-;; 그럼 그런 사이트를 준비해놔야 하는거잖아!?

HTTP GET 메서드 해보기

예제가 정말 옛날 예제이다.. POST 는 잘 작동조차 하지않아서 뺐다
그래도 이런스타일도 경우에 따라서는 써야할 상황이 올수도?

public class ConnectHttp {
public static void main(String[] args) throws IOException {
System.out.println("[GET]");
ConnectHttp.sendGetRequest();

}

private static void sendGetRequest() throws IOException {

URL url = new URL(
"http://hasune-bot.com/test"
);

// HTTP 접속 시작
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();

// Request 메서드 설정
httpCon.setRequestMethod("GET");

// 웹 서버로부터의 응답을 표시
displayResponse(httpCon);

httpCon.disconnect();

}

private static void displayResponse(HttpURLConnection httpCon) throws IOException {

System.out.println("웹 서버 로부터의 응답");

BufferedReader reader = new BufferedReader(
new InputStreamReader(httpCon.getInputStream())
);

String line;

while (null != (line = reader.readLine())) {
System.out.println(line);
}

reader.close();
}
}
[GET]
웹 서버 로부터의 응답
{"test":"ok"}