통신
IP
원격으로 pc에 접속하기 위해선 ip가 필요하다 ip는 (1byte x 4)의 체계를 갖추고 있다.
ip는 0~255까지 정수 4자리로 이루어져 있다. ipv6은 주소로 16진수 4자리수 ipv9도 있긴한데 중국에서만 사용한다.
공인IP - 진짜IP 인터넷에서 사용자 식별을 위한 IP
사설IP - 공유기에 묶여서 등장하는 IP와 같이 별도의 네트워크에서 사용되는 IP, 외부에서 접근은 불가능하며 중복이 가능하다.
유동IP
개인사용자를 위해서 임의의 비어있는 ip를 받아 사용하는 것 가정에서는 사설IP면서 유동IP 인 것
자동으로 게이트웨이, 서브넷마스크, DNS를 자동할당 해줘서 인터넷과 연결하기 쉽도록 해주는게 DHCP 서버이다.
일반적으로 공유기가 해당 기능을 수행해줌
고정IP
학교,회사 등 관공서에서는 DHCP를 지원하지 않기 때문에 직접 설정을 해줘야 인터넷을 사용 할 수 있게 된다.
게이트웨이, DNS, 서브넷 마스크를 직접 기입 해줘야 인터넷을 사용 할 수 있다.
또한 변경되어서도 안되기 때문에 고정 IP를 이용해야한다.
DNS - Domain Name Server
원칙은 ip를 통해서 접속해야하는 것이 맞으나 전부 기억할 수 없기에
Domain을 지정해서 naver.com와 같은 값을 입력하여 해당 pc에 접속 할 수 있도록 함.
naver.com을 입력하는 순간 DNS에 해당 이름을 찾아 달라고 요청하는데
그러면 DNS에서 ip를 알려주고 우리는 받은 ip를 통해 네이버에 접속할 수 있게 되는 것
DNS서버의 주소는 통신사를 무엇을 사용하느냐에 따라 달라지게된다.
host
windows의 hosts파일에 저장되어있는 Domain과 ip가 있을 경우 DNS서버에 가서 안물어보고 바로 해당 ip로 가게 된다.
이를 이용하여 hosts 파일을 위변조하여 피싱사이트에 접속되도록 할 수 있게 된다.
그렇기에 공용으로 사용되는 컴퓨터에서 모든 내용을 100% 신뢰하기 어렵게 된다.
InetAddress
public class Ex01 {
public static void main(String[] args) {
java.net.InetAddress addr1 = null;
java.net.InetAddress addr2 = null;
java.net.InetAddress addr3 = null;
// addr1 = new InetAddress(); // default 생성자가 없다.
try {
// 도메인 이름을 통한 연결
addr1 = InetAddress.getByName("naver.com");
System.out.println(addr1.getHostName()); // naver.com
System.out.println(addr1.getHostAddress()); // 223.130.195.95
System.out.println("======");
// IP를 통한 연결 (ipv4) - (1byte x 4) 의 체계를 갖추고 있다.
byte[] arr1 = {(byte)223,(byte)130,(byte)195,95}; // byte배열을 받음
addr2 = InetAddress.getByAddress(arr1);
System.out.println(addr2.getHostAddress());
System.out.println("======");
// 내 ip 192.168.240.119
// byte[] arr2 = {(byte)192,(byte)168,(byte)240,119};
byte[] arr2 = {127,0,0,1}; // localhost
// addr3 = InetAddress.getByAddress(arr2);
// addr3 = InetAddress.getByName("DESKTOP-O5AJ5VH");
addr3 = InetAddress.getByName("localhost");
System.out.println(addr3.getHostName());
System.out.println(addr3.getHostAddress());
System.out.println("======");
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
URL
public class Ex03 {
public static void main(String[] args) {
// URL vs URI
// 프로토콜://도메인:포트번호/경로/../경로?쿼리스트링#ref(앵커)
String msg = "";
msg = "https://namu.wiki/w/%EB%A7%A4%EB%8B%88%20%ED%8C%8C%ED%80%B4%EC%95%84%EC%98%A4#s-8";
java.net.URL url = null;
try {
url = new URL(msg);
System.out.println("protocol : " + url.getProtocol());
System.out.println("domain : " + url.getHost());
System.out.println("port : " + url.getPort());
System.out.println("default port : " + url.getDefaultPort());
System.out.println("file : " + url.getFile());
System.out.println("path : " + url.getPath());
System.out.println("queryString : " + url.getQuery());
System.out.println("ref : "+ url.getRef());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
웹크롤링
public class Ex04 {
public static void main(String[] args) {
File file = new File("7zip.exe");
URL url = null;
InputStream is = null;
// InputStreamReader isr = null;
// BufferedReader br = null;
//byte stream
OutputStream os = null;
// 문자열인 경우
// Writer fw = null;
// PrintWriter pw = null;
try {
os = new FileOutputStream(file);
// fw = new FileWriter(file);
// pw = new PrintWriter(fw);
url = new URL("https://www.7-zip.org/a/7z2201-x64.exe");
URLConnection conn = url.openConnection();
is = conn.getInputStream();
// isr = new InputStreamReader(is);
// br = new BufferedReader(isr);
// String msg = null;
// while((msg=br.readLine())!=null){
// os.(msg);
// }
int su = -1;
while((su=is.read())!=-1) {
os.write(su);
}
System.out.println("크롤링 완료");
// if(br!=null)br.close();
// if(isr!=null)is.close();
if(is!=null)is.close();
if(os!=null)os.close();
// if(pw!=null)pw.close();
// if(fw!=null)fw.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
소켓통신
Client
public class Client extends Frame implements ActionListener{
TextField tf = new TextField();
static TextArea ta = new TextArea();
static PrintWriter pw;
public Client() {
setLayout(new BorderLayout());
add(ta, BorderLayout.CENTER);
add(tf, BorderLayout.SOUTH);
tf.addActionListener(this);
setBounds(100,100,300,400);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
String msg = tf.getText();
pw.println(msg);
pw.flush();
tf.setText("");
}
public static void main(String[] args) {
Client client = new Client();
String url = "192.168.240.119";
int port = 8080;
Socket sock = null;
InputStream is = null;
OutputStream os = null;
InputStreamReader isr = null;
OutputStreamWriter osw = null;
BufferedReader br = null;
try {
sock = new Socket(url, port);
is = sock.getInputStream();
os = sock.getOutputStream();
isr = new InputStreamReader(is);
osw = new OutputStreamWriter(os);
br = new BufferedReader(isr);
pw = new PrintWriter(osw);
String msg = null;
while(true) {
msg = br.readLine(); // 계속 읽어오는데
if(msg.equals("exit"))break;
ta.append(msg + "\n"); // 읽어온 값을 ta에 넣어주는 것
}
if(pw!=null)pw.close();
if(br!=null)br.close();
if(osw!=null)osw.close();
if(isr!=null)isr.close();
if(os!=null)os.close();
if(is!=null)is.close();
if(sock!=null)sock.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
public class Server {
public static void main(String[] args) {
List<PrintWriter> list = new ArrayList<PrintWriter>();
ServerSocket serve = null;
try {
serve = new ServerSocket(8080);
while (true) {
final Socket sock = serve.accept();
Thread thr = new Thread(new Runnable() {
@Override
public void run() {
InputStream is = null;
OutputStream os = null;
InputStreamReader isr = null;
OutputStreamWriter osw = null;
BufferedReader br = null;
PrintWriter pw = null;
InetAddress addr = null;
try {
addr = sock.getInetAddress();
is = sock.getInputStream();
os = sock.getOutputStream();
isr = new InputStreamReader(is);
osw = new OutputStreamWriter(os);
br = new BufferedReader(isr);
pw = new PrintWriter(osw);
list.add(pw);
String msg = null;
while((msg=br.readLine())!=null) {
msg = "["+addr.getHostAddress()+ "]" +msg;
for (int i = 0; i < list.size(); i++) {
PrintWriter w = list.get(i);
w.println(msg);
w.flush();
}
System.out.println(msg);
}
if(pw!=null) pw.close();
if(br!=null) br.close();
if(osw!=null) osw.close();
if(isr!=null) isr.close();
if(is!=null) is.close();
if(os!=null) os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thr.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
네트워크 모델 (OSI 7계층 과 네트워크 4계층)
1-2 계층은 하드웨어 영역
3-4 계층은 운영체제 영역
5-7 계층은 프로그램 영역
TCP 방식 연결
연결지향방식으로 데이터 패킷을 보내는데 서로 응답을 주고 받음으로써 연결을 확인하는 방식
서버로 요청을 보내고 응답을 받고 다시 또 응답을 잘받았다는 요청을 보내면서 데이터패킷을 일부 보내는 과정이 반복된다.
서버에서도 응답을 잘 받았다는 요청을 받음으로써 요청을 받을 준비를 한다. 이후 패킷을 받을 때마다 받았다는 응답을 보낸다.
장점은 안전하다. loss가 없다. 서버로 부터 응답을 못받으면 정상적인 응답을 받을 때 까지는 패킷을 다시 보낸다.
단점은 느리다. 뭐하나 보낼 때마다 계속 응답을 확인하기 때문
UDP 방식 연결
패킷을 일방적으로 보내는 방식. 각 패킷마다 도착지점을 가지고 있다.
장점은 속도가 빠르다.
단점은 loss가 있을 수 있으며 데이터에 대한 무결성이 확보 되지 않는다. 신뢰도가 떨어진다.
브로드캐스트상황 - 인터넷 전화,온라인 게임,멀티미디어 스트리밍 등과 같은 실시간으로 데이터를 송/수신하는 서비스에 있어 많이 이용된다.
UDP 통신 구현
Sender
public class Sender {
// UDP 통신
public static void main(String[] args) {
DatagramSocket sock = null;
DatagramPacket packet = null;
InetAddress addr = null;
byte[] arr = {127,0,0,1};
try {
addr = InetAddress.getByAddress(arr);
sock = new DatagramSocket();
packet = new DatagramPacket("abcdefghqrs".getBytes(), 9, addr, 8080);
sock.send(packet);
packet = new DatagramPacket("1234".getBytes(), 4, addr, 8080);
sock.send(packet);
if(sock!=null)sock.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Receiver
public class Receiver {
public static void main(String[] args) {
DatagramSocket sock = null;
DatagramPacket packet = null;
byte[] buf = new byte[16];
try {
sock = new DatagramSocket(8080);
packet = new DatagramPacket(buf, 8);
sock.receive(packet);
buf = packet.getData();
// byte[] buf2 = packet.getData();
// System.out.println(buf == buf2); //true
System.out.println(Arrays.toString(buf));
packet = new DatagramPacket(buf, 4);
sock.receive(packet);
packet.getData();
System.out.println(new String(buf));
if(sock!=null)sock.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
'회고록(TIL&WIL)' 카테고리의 다른 글
2023.01.10 Java Socket I/O - 마피아게임 (KPT 회고) (0) | 2023.01.16 |
---|---|
TIL 2023.01.06 리눅스 (0) | 2023.01.16 |
WIL 2023.01.02 ~ 2023.01.05 java 공부 (1) | 2023.01.09 |
WIL 2022.12.26 ~ 2022.12.30 java 공부 (0) | 2023.01.02 |
TIL 2022.12.28 내가 쓰는 단축키 모음집 (0) | 2022.12.28 |