일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Java의정석
- 제네릭
- 스프링MVC
- java
- REGEXP_SUBSTR
- docker
- inflearn
- 서블릿
- Numpy
- 자바연습문제
- 이것이자바다
- 불친절한 SQL 프로그래밍
- 스프링 핵심원리
- Python
- 자바공부
- 자바의정석
- Secure Coding
- 항해플러스 백엔드
- 인프런
- 스프링입문
- 김영한
- 불친절한SQL프로그래밍
- JPA
- 스프링 부트와 JPA
- 자바의정석 연습문제
- 시큐어코딩
- 항해플러스
- Spring
- 분석함수
- 스프링
- Today
- Total
Continuous Challenge
[Java의 정석_연습문제 풀이] Chapter16. 네트워킹 본문
[16-1] ip주소가 192.168.10.100이고 서브넷 마스크(subnet mask)가 255.255.255.0일 때, 네트워크 주소와 호스트 주소를 계산하여 화면에 출력하는 프로그램을 작성하시오. 단, 비트연산자를 사용해서 계산해야 한다.
[실행결과]
네트워크 주소 : 192.169.10.0.
호스트 주소 : 0.0.0.100.
답
public class Exercise16_1 {
public static void main(String[] args) {
byte[] ip = { (byte) 192, (byte) 168, (byte) 10, (byte) 100 };
byte[] subnet = { (byte) 255, (byte) 255, (byte) 255, (byte) 0 };
byte[] nwAddress = new byte[4]; // 네트워크 주소
byte[] hostAddress = new byte[4]; // 호스트 주소
System.out.println("네트워크 주소");
for (int i = 0; i < ip.length; i++) {
nwAddress[i] = (byte) (ip[i] & subnet[i]); // &연산을 수행한다.
System.out.print(nwAddress[i] >= 0 ? nwAddress[i]
: nwAddress[i] + 256);
System.out.print(".");
}
System.out.println();
System.out.println("호스트 주소 : ");
for (int i = 0; i < ip.length; i++) {
hostAddress[i] = (byte) (ip[i] & ~subnet[i]); // &연산을 수행한다.
System.out.print(hostAddress[i] >= 0 ? hostAddress[i]
: hostAddress[i] + 256);
System.out.print(".");
}
System.out.println();
}
}
해설 : 바이트 배열에 ip주소와 서브넷 마스크를 저장한 다음에 반복문을 이용해서 1byte씩 &연산을 하면 호스트 주소를 얻을 수 있다. 그리고 서브넷 마스크에 '~' 연산을 취한 다음에 ip와 &연산을 취하면 네트워크 주소를 얻을 수 있다.
모든 bit의 값이 1인 1byte의 데이터가 있다고 할 때, 왼쪽에서 첫 번째 비트를 부호로 인식하지 않으면 부호없는 1byte가 되어 범위는 0~255이므로 이 값은 최대값이 255가 되지만, 부호로 인식하는 경우 범위는 -128~127이 되고, 이 값은 0보다 1 작은 값인 -1이 된다.
결국 같은 데이터이지만 자바의 자료형인 byte의 범위가 부호있는 1byte 정수의 범위인 -128~127이기 때문에 -1로 인식한다는 것이다. 그래서 이 값을 0~255사이의 값으로 변환하려면 256을 더해주어야 한다.
[16-2] 다음 중 TCP의 특징이 아닌 것은?
a. 전화와 같은 1:1 연결기반의 프로토콜이다.
b. 데이터의 전송순서가 보장된다.
c. UDP보다 전송속도가 빠르다.
d. 데이터의 수신여부를 확인한다.
답 : c
|
TCP |
UDP |
연결방식 |
연결기반(connection-oriented) - 연결 후 통신 (전화기) - 1:1 통신방식 |
비연결기반(connectionless-oriented) - 연결없이 통신(소포) - 1:1, 1:n, n:n 통신방식 |
특징 |
데이터의 경계를 구분안함 (byte-stream) 신뢰성있는 데이터 전송 - 데이터의 전송순서가 보장됨 - 데이터의 수신여부를 확인함 (데이터가 손실되면 재전송됨) - 패킷을 관리할 필요가 없음 UDP보다 전송속도가 느림 |
데이터의 경계를 구분함 (datagram) 신뢰성없는 데이터 전송 - 데이터의 전송순서가 바뀔 수 있음 - 데이터의 수신여부를 확인 안 함 (데이터가 손실되어도 알 수 없음) - 패킷을 관리해주어야 함 TCP보다 전송속도가 빠름 |
관련 클래스 |
Socket ServerSocket |
DatagramSocket DatagramPacket MulticastSocket |
[16-3] TextField에 URL을 입력하고 Enter키를 누르면 해당 페이지의 소스를 보여주는 'Source Viwer' 프로그램이다. 예제 15-4를 참고해서 (1)에 알맞은 코드를 넣어 완성하시오.
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class SourceViewer extends Frame {
TextField tf = new TextField();
TextArea ta = new TextArea();
SourceViewer(String title) {
super(title);
add(tf, "North");
add(ta, "Center");
tf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
displaySource();
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
setBounds(500, 200, 500, 300);
setVisible(true);
}
void displaySource() {
URL url = null;
BufferedReader input = null;
String address = tf.getText().trim();
String line = "";
ta.setText("");
try {
if (!address.startsWith("http://"))
address = "http://" + address;
/*
* (1) 알맞은 코드를 넣어 완성하시오.
*/
input.close();
} catch (Exception e) {
ta.setText("유효하지 않은 URL입니다.");
}
} // displaySource()
public static void main(String[] args) {
SourceViewer mainWin = new SourceViewer("Source Viewer");
}
}
답
url = new URL(address);
input = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
while((line=input.readLine()) != null) {
ta.append(line);
ta.append("\n");
}
해설 : URL클래스를 이용해서 해당 URL으로부터 데이터를 읽어오는 문제이다.
[16-4] 다음의 코드는 TCP통신을 하는 예제16-6, 16-7을 결합하여 GUI채팅프로그램을 작성한 것이다. (1)~(4)에 알맞은 코드를 넣어 프로그램을 완성하시오.
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class ChatServer extends Frame {
String nickname = "";
DataOutputStream out;
DataInputStream in;
Panel p = new Panel();
TextArea ta = new TextArea();
TextField tf = new TextField();
ChatServer(String nickname) {
super("Chatting");
this.nickname = nickname;
p.setLayout(new BorderLayout());
p.add(tf, "Center");
add(ta, "Center");
add(p, "South");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
EventHandler handler = new EventHandler();
ta.addFocusListener(handler);
tf.addFocusListener(handler);
tf.addActionListener(handler);
ta.setEditable(false);
setBounds(200, 200, 300, 200);
setVisible(true);
tf.requestFocus();
}
void startServer() {
ServerSocket serverSocket = null;
Socket socket = null;
try {
/*
* (1) 아래의 로직에 맞게 코드를 작성하시오.
* 1. 서비소켓을 생성하여 7777번 포트와 결합시킨다.
* 2. ta에 "서버가 준비되었습니다." 라고 보여준다.
* 3. 상대방의 연결을 기다린다.
* 4. ta에 "상대방과 연결되었습니다." 라고 보여준다.
* ta.append("\r\n" +"상대방과 연결되었습니다.");
* 5. 반복문을 이용해서 입력스트림이 null이 아닌 동안
* 입력스트림으로부터 데이터를 읽어서 변수 msg에 저장한다.
*/
ta.append("\r\n" + msg);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("USAGE : java ChatServer NICKNAME");
System.exit(0);
}
ChatServer chatWin = new ChatServer(args[0]);
chatWin.startServer();
} // main
class EventHandler extends FocusAdapter implements ActionListener {
public void actionPerformed(ActionEvent ae) {
String msg = tf.getText();
if ("".equals(msg))
return;
/*
* (2) 알맞은 코드를 넣어 완성하시오.
*/
ta.append("\r\n" + nickname + ">" + msg);
tf.setText("");
}
public void focusGained(FocusEvent e) {
tf.requestFocus();
}
} // class EventHandler
} // class
답
(1)
serverSocket = new ServerSocket(7777);
ta.setText("서버가 준비되었습니다.");
socket = serverSocket.accept();
ta.append("\r\n" +"상대방과 연결되었습니다.");
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
while(in!=null) {
try {
String msg = in.readUTF();
ta.append("\r\n" + msg);
} catch(IOException e) {}
}
(2)
if(out!=null) {
try{
out.writeUTF(nickname+">"+msg);
}catch(IOException e) {}
}
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class ChatClient extends Frame {
String nickname = "";
String serverIp = "";
int serverPort = 0;
DataOutputStream out;
DataInputStream in;
Panel p = new Panel();
TextArea ta = new TextArea();
TextField tf = new TextField();
ChatClient(String nickname, String serverIp, String serverPort) {
super("Chatting with " + serverIp + ":" + serverPort);
this.nickname = nickname;
this.serverIp = serverIp;
this.serverPort = Integer.parseInt(serverPort);
setBounds(600, 200, 300, 200);
p.setLayout(new BorderLayout());
p.add(tf, "Center");
add(ta, "Center");
add(p, "South");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
EventHandler handler = new EventHandler();
ta.addFocusListener(handler);
tf.addFocusListener(handler);
tf.addActionListener(handler);
ta.setEditable(false);
setVisible(true);
tf.requestFocus();
}
void startClient() {
try {
/* (3) 아래의 로직에 맞게 코드를 작성하시오.
* 1. 소켓을 생성하여 serverIp의 serverPort에 연결한다.
* 2. ta에 "상대방과 연결되었습니다."라고 보여준다
* ta.setText("상대방과 연결되었습니다.");
* 3. 연결된 상대방 소켓의 입력스트림과 출력스트립을 얻어온다.
* 4. 반복문을 이용해서 입력스트림이 null이 아닌 동안
* 입력스트림으로부터 데이터를 읽어서 변수 msg에 저장한다.
*/
ta.append("\r\n" + msg);
} catch(ConnectException ce) {
ta.setText("상대방과 연결할 수 없습니다.");
ce.printStackTrace();
} catch(IOException ie) {
ie.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 3) {
System.out.println("USAGE : java ChatClient NICKNAME SERVER_IP SERVER_PORT");
System.exit(0);
}
ChatClient chatWin = new ChatClient(args[0], args[1], args[2]);
chatWin.startClient();
} // main
class EventHandler extends FocusAdapter implements ActionListener {
public void actionPerformed(ActionEvent ae) {
String msg = tf.getText();
if ("".equals(msg))
return;
/*
* (4) 알맞은 코드를 넣어 완성하시오.
*/
ta.append("\r\n" + nickname + ">" + msg);
tf.setText("");
}
public void focusGained(FocusEvent e) {
tf.requestFocus();
}
} // class EventHandler
} // class
답
(3)
Socket socket = new Socket(serverIp, serverPort);
ta.setText("상대방과 연결되었습니다.");
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
while(in!=null){
try{
String msg = in.readUTF();
ta.append("\r\n"+msg);
}catch(IOException e) {}
}
(4)
if(out!=null){
try{
out.writeUTF(nickname+">"+msg);
}catch(IOException e) {}
}
'Study > Java의 정석' 카테고리의 다른 글
[Java의 정석_연습문제 풀이] Chapter15. 입출력(I/O) (0) | 2019.11.11 |
---|---|
[Java의 정석_연습문제 풀이] Chapter14. 람다와 스트림 (0) | 2019.11.06 |
[Java의 정석_연습문제 풀이] Chapter13 쓰레드 (0) | 2019.11.06 |
[Java의 정석_연습문제 풀이] Chapter12 Generics, Enumeration, Annotation(지네릭스, 열거형, 애너테이션) (0) | 2019.11.05 |
[Java의 정석_연습문제 풀이] Chapter11 컬렉션 프레임워크 (0) | 2019.11.05 |