January 13, 2022
๋คํธ์ํน์ด๋ ๋ ๋ ์ด์์ ์ปดํจํฐ๋ฅผ ์ผ์ด๋ธ๋ก ์ฐ๊ฒฐํ์ฌ ๋คํธ์ํฌ(network)๋ฅผ ๊ตฌ์ฑํ๋ ๊ฒ์ ๋งํ๋ค.
์๋ฐ์์ ์ ๊ณตํ๋ java.netํจํค์ง๋ฅผ ์ฌ์ฉํ๋ฉด ๋คํธ์ํฌ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ ํต์ ๋ถ๋ถ์ ์ฝ๊ฒ ์์ฑํ ์ ์๋ค.
ํด๋ผ์ด์ธํธ์ ์๋ฒ๋ ์ปดํจํฐ๊ฐ์ ๊ด๊ณ๋ฅผ ์ญํ ๋ก ๊ตฌ๋ถํ๋ ๊ฐ๋ ์ด๋ค.
์๋ฒ ๊ธฐ๋ฐ ๋ชจ๋ธ(server-based model)
P2P ๋ชจ๋ธ(peer-to-peer model)
InetAddress๋ ์๋ฐ์์ IP์ฃผ์๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํ ํด๋์ค๋ก ๋ง๋ค์ด์ก๋ค.
URL์ ์ธํฐ๋ท์ ์กด์ฌํ๋ ์ฌ๋ฌ ์๋ฒ๋ค์ด ์ ๊ณตํ๋ ์์์ ์ ๊ทผํ ์ ์๋ ์ฃผ์๋ฅผ ํํํ๊ธฐ ์ํ ๊ฒ์ผ๋ก โํ๋กํ ์ฝ://ํธ์คํธ๋ช : ํฌํธ๋ฒํธ/๊ฒฝ๋ก๋ช /ํ์ผ๋ช ?์ฟผ๋ฆฌ์คํธ๋ง#์ฐธ์กฐโ์ ํํ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
ํ๋กํ ์ฝ : ์์์ ์ ๊ทผํ๊ธฐ ์ํด ์๋ฒ์ ํต์ ํ๋๋ฐ ์ฌ์ฉ๋๋ ๊ท์ฝ(http)
ํธ์คํธ๋ช
(DomainName) : ์์์ ์ ๊ณตํ๋ ์๋ฒ์ ์ด๋ฆ
ํฌํธ๋ฒํธ : ํต์ ์ ์ฌ์ฉ๋๋ ์๋ฒ์ ํฌํธ๋ฒํธ
๊ฒฝ๋ก๋ช
(path) : ์ ๊ทผํ๋ ค๋ ์์์ด ์ ์ฅ๋ ์๋ฒ์ ์์น
์ฟผ๋ฆฌ : URL์์ ? ์ดํ์ ๋ถ๋ถ
์ฐธ์กฐ : URL์์ #์ดํ์ ๋ถ๋ถ
URL ๊ฐ์ ๊ฒฝ์ฐ ์์ฃผ ์ฌ์ฉ๋ ์ ์์ผ๋ฏ๋ก ํ์ํ ๋๋ง๋ค ๊ณต์๋ฌธ์์์ ์ฐพ์ ์ฐ๋๋ก ํ์.
URLConnection์ ์ดํ๋ฆฌ์ผ์ด์ ๊ณผ URL๊ฐ์ ํต์ ์ฐ๊ฒฐ์ ๋ํ๋ด๋ ํด๋์ค์ ์ต์์ ํด๋์ค๋ก ์ถ์ํด๋์ค์ด๋ค.
URL Connection์ ์ฌ์ฉํ์ฌ ํด๋น URL์ HeaderField, URL, ContentLength๋ฑ ๋ค์ํ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค. ๋ํ URL์ ์ฐ๊ฒฐํ์ฌ ํด๋น ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค.
ํ๋ฒ์ openStream์ ํธ์ถํ ๊ฒ์ URLConnection์ ์ป์๋ค getInputStream์ ํ๊ฒ ๊ณผ ๊ฐ๋ค.
URL url = "https://www.naver.com";
InputStream in = url.openStream();
/// ์๋ ์๋์ ๊ฐ๋ค.
URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();
์์ผ(socket)์ด๋ ํ๋ก์ธ์ค ๊ฐ์ ํต์ ์ ์ฌ์ฉ๋๋ ์์ชฝ ๋๋จ(endpoint)์ ์๋ฏธํ๋ค. ํ๋ก์ธ์ค๊ฐ์ ํต์ ์ ์ํด์๋ ์์ผ์ด ํ์ํ๋ค.
TCP์์ผ ํ๋ก๊ทธ๋๋ฐ์ ์๋ฒ์ ํด๋ผ์ด์ธํธ์ ํต์ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
๋ค์ํ๋ฒ ๋งํ๋ฉด
๊ฐ ์์ผ์ ๋ ๊ฐ์ ์คํธ๋ฆผ ์ฆ ์ ๋ ฅ์คํธ๋ฆผ๊ณผ ์ถ๋ ฅ์คํธ๋ฆผ์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ด ์คํธ๋ฆผ๋ค์ ์ฐ๊ฒฐ๋ ์๋ํธ ์์ผ์ ์คํธ๋ฆผ๊ณผ ๊ต์ฐจ์ฐ๊ฒฐ๋๋ค.
์ฑํ ๋ฐฉ ์์ ๊ฐ์ ๊ฒฝ์ฐ ์๋ฒ์ ์ ์ํ๋ ํด๋ผ์ด์ธํธ์ ์๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ์ฐ๋ ๋๋ฅผ ์ด์ฉํด์ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ณ๋ ฌ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค. ์๋ฒ๊ฐ ์ ์์ ์์ฒญํ ์์๋๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ฆ๊ฒ ์ ์์ ์์ฒญํ ํด๋ผ์ด์ธํธ๋ ์ค๋ ์๊ฐ์ ๊ธฐ๋ค๋ฆด ์ ์๋ค.
์๋ฒ
package Network;
import java.net.*;
import java.io.*;
import java.util.*;
public class TcpIpMultichatServer {
// ์๋ฒ์์ ๋ค์ด์ค๋ client๋ค์ Thread๋ฅผ ์์ฑํ์ฌ ํด๋น ์ ๋ณด๋ฅผ ๋ฃ์ด ๋ณด๊ดํ ๋งต
HashMap clients;
TcpIpMultichatServer(){
clients = new HashMap();
Collections.synchronizedMap(clients);
}
public void start(){
ServerSocket serverSocket = null;
Socket socket = null;
try{
//7777๋ฒ ํฌํธ์ ์๋ฒ ์์ผ์ ์ฐ๋ค.
serverSocket = new ServerSocket(7777);
System.out.println("์๋ฒ๊ฐ ์์๋์์ต๋๋ค.");
while(true){
// serverSocket์ ์ฐ๊ฒฐ์ ์๋ํ๋ฉด ํด๋น ์์ผ์ ์ฐ๊ฒฐ์ ํ์ฉํด์ค๋ค.
socket = serverSocket.accept();
System.out.println("["+socket.getInetAddress()+":"+socket.getPort()+"]์์์ ์ํ์์ต๋๋ค.");
// Thread๋ฅผ ์์ฑํ์ฌ ๋ค์ด์จ ์์ผ๊ณผ 1:1 ์ฐ๊ฒฐ์ ํ๋ ์์ผ์ ๋ง๋ค์ด์ค ์์ ์ด๋ค.
ServerReceiver thread = new ServerReceiver(socket);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// HashMap์ ์ ์ฅํ ๋ชจ๋ clients๋ค์๊ฒ ์ผ๊ด์ ์ผ๋ก message๋ฅผ ๋ณด๋ด์ฃผ๋ ํจ์
void sendToAll(String msg){
Iterator it = clients.keySet().iterator();
while(it.hasNext()){
try{
DataOutputStream out = (DataOutputStream)clients.get(it.next());
out.writeUTF(msg);
} catch (IOException e){}
}
}
// ์ฑํ
์๋ฒ๋ฅผ ์คํํ๋ mainํจ์
public static void main(String[] args){
new TcpIpMultichatServer();
}
// Client์ socket๊ณผ ์ฐ๊ฒฐํ๋ Thread
class ServerReceiver extends Thread{
Socket socket; // ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐํ ์์ผ
DataInputStream in;
DataOutputStream out;
// ์๋ฒ ์์ผ์ด ์์ฑํ ์ฐ๋ ๋์ input, outputStream ์ ์์ฑํด์ฃผ๋ ์์ฑ์
ServerReceiver(Socket socket){
this.socket = socket;
try{
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e){}
}
// ์ฐ๋ ๋์ ๋์
public void run(){
String name= "";
try{
// readUTFํจ์๋ ์ค์ผ๋์ฒ๋ผ ์๋๊ฐ ์
๋ ฅํ์ง ์์ผ๋ฉด ๊ณ์ ๊ธฐ๋ค๋ฆฐ๋ค.
// ์ฐ๋ฆฌ ์ฑํ
์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ ์ฐ๊ฒฐ ์ ๋จผ์ ์๊ธฐ ์ด๋ฆ์ ๋ณด๋ด๋ฏ๋ก, ๋ฐ์ ์ด๋ฆ์ ์ ์ฅ
name = in.readUTF();
// ์๋ก์ด ํด๋ผ์ด์ธํธ๊ฐ ์ ์ํ์์ ์๋ฆฐ๋ค.
sendToAll("#"+name+"๋์ด๋ค์ด์ค์
จ์ต๋๋ค.");
// clients Map์ ์๋ก์จ ํด๋ผ์ด์ธํธ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ฉฐ, outputStream๋ ๊ฐ์ด ์ ์ฅํ๋ค.
clients.put(name, out);
System.out.println("ํ์ฌ ์๋ฒ์ ์์ ์๋ " + clients.size() + "์
๋๋ค.");
while(in != null){
// ์ดํ client์ ์ ๋ณด๊ฐ ๋ค์ด์ฌ ๋๋ง๋ค ๊ณ์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฑํ
๋ฐฉ์ ๋ฟ๋ ค์ค๋ค.
// ์คํธ๋ฆผ์ด ๋ซํ๋ฉด in==null์ด ๋๋ค.
sendToAll(in.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// ์ฐ๊ฒฐ์ด ๋๊ธฐ๋ฉด ํด๋น ํด๋ผ์ด์ธํธ๊ฐ ๋๊ฐ๊ฒ์ ์๋ ค์ค๋ค.
sendToAll("#"+ name + "๋์ด ๋๊ฐ์
จ์ต๋๋ค.");
clients.remove(name);
System.out.println(" ํด๋น ์ ์ ๋ ์ ์์ ์ข
๋ฃํ์์ต๋๋ค.");
}
}
}
}
ํด๋ผ์ด์ธํธ
package Network;
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class TcpIpMultichatClient {
public static void main(String[] args){
if(args.length != 1){
System.out.println("USAGE: java TcpIpMultichatClient ๋ํ๋ช
");
}
try{
String serverIp = "127.0.0.1";
// serverIp์ 7777๋ฒ ํฌํธ๋ก ใ
๋
๊ฒฐํ๋ค.
Socket socket = new Socket(serverIp, 7777);
System.out.println("์๋ฒ์ ์ฐ๊ฒฐ ๋์์ต๋๋ค.");
// sender์ receiver ์ฐ๋ ๋๋ฅผ ๊ฐ๊ฐ ์์ฑํ๋ฉฐ, ์ฐ๊ฒฐ๋ ์์ผ์ผ๋ก ์คํธ๋ฆผ์ ์ฐ๊ฒฐํ๋ค.
Thread sender = new Thread(new ClientSender(socket, args[0]));
Thread receiver = new Thread(new ClientReceiver(socket));
sender.start();
receiver.start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// Sender, outputStream
static class ClientSender extends Thread{
Socket socket;
DataOutputStream out;
String name;
ClientSender(Socket socket, String name){
this.socket = socket;
try{
out = new DataOutputStream(socket.getOutputStream());
this.name = name;
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
Scanner scanner = new Scanner(System.in);
try{
// ์ฐ๊ฒฐ์ด ๋๋ฉด ๋จผ์ ์ด๋ฆ๋ถํฐ ๋ณด๋ด์ค๋ค.
if(out!=null){
out.writeUTF(name);
}
// ์ฐ๊ฒฐ์ด ๋๊ธฐ๊ธฐ ์ ๊น์ง Scanner์์ ์
๋ ฅ๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ค์ ๋ค์ ๋ณด๋ด์ค๋ค.
while(out!=null) out.writeUTF("[" + name + "]" + scanner.nextLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Reciever, inputStream
static class ClientReceiver extends Thread{
Socket socket;
DataInputStream in;
ClientReceiver(Socket socket){
this.socket = socket;
try{
in = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
// ๋ค์ด์ค๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ค์ ๋ฐ๋ก ์ถ๋ ฅํด์ค๋ค.
while(in != null){
try{
System.out.println(in.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
DatagramPacket์ ํค๋์ ๋ฐ์ดํฐ๋ก ๊ตฌ์ฑ๋์ด์๋ค.
์๋ฒ๋ก๋ถํฐ ์๋ฒ์๊ฐ์ ์ ์ก๋ฐ์ ์ถ๋ ฅํ๋ UDP ์์ผ ํด๋ผ์ด์ธํธ, ์๋ฒ ํ๋ก๊ทธ๋จ ์์ ์ด๋ค.
Server
package Network;
import java.net.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.text.SimpleDateFormat;
public class UdpServer {
public void start() throws IOException{
// ํฌํธ 7777๋ฒ์ ์ฌ์ฉํ๋ ์์ผ์ ์์ฑํ๋ค
DatagramSocket socket = new DatagramSocket(7777);
DatagramPacket inPacket, outPacket;
byte[] inMsg = new byte[100];
byte[] outMsg;
while(true){
//๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ธฐ ์ํ ํจํท์ ์์ฑํ๋ค.
inPacket = new DatagramPacket(inMsg, inMsg.length);
// ํจํท์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์์ (receive)ํ๋ค.
socket.receive(inPacket);
//์์ ํ ํจํท์ผ๋ก๋ถํฐ client์ IP์ฃผ์์ Port๋ฅผ ์ป๋๋ค.
InetAddress address = inPacket.getAddress();
int port = inPacket.getPort();
// ์๋ฒ์ ํ์ฌ ์๊ฐ์ ์๋ถ์ด ํํ [hh:mm:ss] ๋ก ๋ฐํํ๋ค
SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
String time = sdf.format(new Date());
outMsg = time.getBytes(); //time์ byte๋ฐฐ์ด๋ก ๋ณํ
// ํจํท์ ์์ฑํด์ Client์๊ฒ ์ ์ก(send)ํ๋ค.
outPacket = new DatagramPacket(outMsg, outMsg.length, address, port);
socket.send(outPacket);
}
}
public static void main(String[] args){
try{
new UdpServer().start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
package Network;
import java.net.*;
import java.io.*;
public class UdpClient {
public void start() throws IOException, UnknownHostException{
DatagramSocket datagramSocket = new DatagramSocket();
InetAddress serverAddress = InetAddress.getByName("127.0.0.1");
// ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๊ณต๊ฐ์ผ๋ก byte๋ฐฐ์ด์ ์์ฑํ๋ค.
byte[] msg = new byte[100];
DatagramPacket outPacket = new DatagramPacket(msg, 1, serverAddress, 7777);
DatagramPacket inPacket = new DatagramPacket(msg, msg.length);
datagramSocket.send(outPacket);
datagramSocket.receive(inPacket);
System.out.println("current server time : " + new String(inPacket.getData()));
datagramSocket.close();
}
public static void main(String[] args){
try{
new UdpClient().start();
} catch (Exception e) {
e.printStackTrace();
}
}
}