개발/국비교육

(국비교육) 24 - 네트워크 + 아이피 주소 찍기 + 소켓 통신 + 채팅 만들기 + 서블릿으로 게시판 만들

개발하는 인사담당자 2023. 7. 4. 17:00

■ 네트워크

 

네트워크 : 컴퓨터 두 대 이상을 하나의 케이블로 연결함
java.net

* 서버와 클라이언트
- 컴퓨터간의 관계 / 하나의 서버에 여러 클라이언트가 연결된 형태
- 서버 : 서비스를 제공합니다.
- 클라이언트 : 서버가 제공하는 서비스를 제공받는다.
- P2P : 클라이언트가 서버 역할을 동시에 수행하는 것

 

* IP : 네트워크 상에서 고유한 자신의 주소.

- IPV4 : 173.100.116.50  / 192.168.0.1
- IPV6 (128비트) FFED:0:0:0:0:BA98:3210:4562

* port

ftp: 21  ssh: 22  http: 80  mariadb: 3306  oracle: 1502  mail: 25 

 

■ 아이피 주소 찍어보기

 

자바에서 IP 주소를 표현할때 사용하는 클래스

InetAddress import 하여 부르기

그리고 이를 배열에 넣어주는 변수도 선언

 

 

네이버 아이피 주소 얻어오기

아래는 try catch 로 잡아준다.

 

■ 내 아이피 주소 찍기

 

 

getLocalHost() : 내 아이피 찍기

 

package jul04;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Iterator;

//Net
/*
 * 네트워크 : 컴퓨터 두 대 이상을 하나의 케이블로 연결함
 * java.net
 * 
 * 서버와 클라이언트
 * 컴퓨터간의 관계 / 하나의 서버에 여러 클라이언트가 연결된 형태
 * 서버 : 서비스를 제공합니다.
 * 클라이언트 : 서버가 제공하는 서비스를 제공받아요. 
 * 
 * P2P : 클라이언트가 서버 역할을 동시에 수행하는 것.
 * 
 * ip : 네트워크 상에서 고유한 자신의 주소
 * IPV4 : 173.100.116.50  / 192.168.0.1
 * IPV6 (128비트) FFED:0:0:0:0:BA98:3210:4562
 * 
 * port
 * ftp: 21  ssh: 22  http: 80  mariadb: 3306  oracle: 1502  mail: 25 
 */

public class Net01 {
	public static void main(String[] args) {
		InetAddress ip = null;
		InetAddress[] ipArr = null;

		try {
			ip = InetAddress.getByName("www.naver.com");
			System.out.println("getHostName : " + ip.getHostName());
			System.out.println("getHostAddr : " + ip.getHostAddress());
			System.out.println("문자열로 보기 : " + ip.toString());

			byte[] ipAddr = ip.getAddress();
			System.out.println("getHostAddr : " + Arrays.toString(ipAddr));
			String result = "";
			for (int i = 0; i < ipAddr.length; i++) {
				result += ipAddr[i] < 0 ? ipAddr[i] + 256 : ipAddr[i];
				result += ".";
			}
			System.out.println("getAddr() + 256 : " + result);

		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		
		System.out.println("==================================================");
		//내 아이피 찍기
		try {
			ip = InetAddress.getLocalHost();
			System.out.println("getHostName : " + ip.getHostName());
			System.out.println("getHostAddr : " + ip.getHostAddress());
			System.out.println("문자열로 : " + ip.toString());
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		
	}
}

 

■ 원하는 url 정보 모두 가져오기

 

 

스트림 만들고 -> 스트림 리더 만들고 -> 버퍼 리더 만들어준다. 

 

package jul04;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class NetStream {
	public static void main(String[] args) {
		
		URL url = null;
		BufferedReader br = null;
		String address = "https://blog.naver.com/wisejia"; //443 보안서버
		
		try {
			url = new URL(address);
			InputStream ins = url.openStream();
			br = new BufferedReader(new InputStreamReader(ins));
			String line = "";
			while ((line = br.readLine()) !=null) {
				System.out.println(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

 

■ URL 주소로 정보 얻어오기

 

package jul04;

import java.net.MalformedURLException;
import java.net.URL;

//URL 주소로 정보 얻어오기
public class URLNet01 {
	public static void main(String[] args) {
		
		URL url;
		try {
			url = new URL("https://www.clien.net/service/board/news/18166800?od=T31&po=0&category=0&groupCd=");
			System.out.println("url.getAuthority : " + url.getAuthority());
			System.out.println("url.getContent : " + url.getContent());
			System.out.println("url.getDefaultPort : " + url.getDefaultPort());
			System.out.println("url.getFile : " + url.getFile());
			System.out.println("url.getHost() : " + url.getHost());
			System.out.println("url.getPath() : " + url.getPath());
			System.out.println("url.getProtocol() : " + url.getProtocol());
			System.out.println("url.getQuery() : " + url.getQuery());
			System.out.println("url.getRef() : " + url.getRef());
			System.out.println("url.getUserInfo() : " + url.getUserInfo());
			System.out.println("url.toExternalForm() : " + url.toExternalForm());
			System.out.println("url.toURI() : " + url.toURI());

		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}

 

■ 소켓통신

 

 

소켓을 이용하는 통신 프로그램
소켓 : 프로세스간 통신에 사용되는 양 끝단을 이야기합니다.

java.net 안에 있습니다. tcp/udp 를 사용하는 소켓프로그램이 대표적입니다.
TCP/IP

 

소켓 : TCP/IP 기반 네트워크 통신에서 데이터 송수신의 마지막 접점을 말합니다.

소켓 통신은 이러한 소켓을 통해 서버와 클라이언트 간 통신을 주고받는

양방향 연결 지향성 통신을 말합니다.

소켓통신은 보통 지속적으로 연결을 유지하면서 실시간으로 데이터를

주고 받아야 하는 경우 사용됩니다.

 

소켓은 서버/클라이언트 소켓으로 구분됩니다.

소켓간 통신을 위해서는 네트워크 간 클라이언트와 서버에 해당하는

컴퓨터를 식별하기 위한 IP주소와 해당 컴퓨터 내에서 현재 통신에

사용되는 응용 프로그램을 식별하기 위한 포트번호가 사용됩니다.


UDP : 유튜브 : 연결이 확인되면 무조건 전송만 합니다.
TCP : 데이터를 전송하기 전에 먼저 상대편과 연결한 후 데이터를 전송합니다.
전송되었는지 확인하고 실패 시 재전송을 하여 다시 확인합니다.

UDP 보다는 느리지만 완벽하게 전송 받을 수 있다. 

 

package socket;
//소켓통신
/*
 * 소켓을 이용하는 통신 프로그램
 * 소켓 : 프로세스간 통신에 사용되는 양 끝단을 이야기합니다.
 * java.net 안에 있습니다. tcp/udp 를 사용하는 소켓프로그램이 대표적입니다.
 * TCP/IP
 * 소켓 : TCP/IP 기반 네트워크 통신에서 데이터 송수신의 마지막 접점을 말합니다.
 * 		  소켓 통신은 이러한 소켓을 통해 서버와 클라이언트 간 통신을 주고받는
 * 		  양방향 연결 지향성 통신을 말합니다.
 * 		  소켓통신은 보통 지속적으로 연결을 유지하면서 실시간으로 데이터를
 * 		  주고 받아야 하는 경우 사용됩니다.
 * 
 * 		  소켓은 서버/클라이언트 소켓으로 구분됩니다.
 * 		  소켓간 통신을 위해서는 네트워크 간 클라이언트와 서버에 해당하는
 * 		  컴퓨터를 식별하기 위한 IP주소와 해당 컴퓨터 내에서 현재 통신에
 *  	  사용되는 응용 프로그램을 식별하기 위한 포트번호가 사용됩니다.
 * 
 * 
 * UDP : 유튜브 : 연결이 확인되면 무조건 전송만 합니다.
 * TCP : 데이터를 전송하기 전에 먼저 상대편과 연결한 후 데이터를 전송합니다.
 * 		 전송되었는지 확인하고 실패 시 재전송을 하여 다시 확인합니다.
 * 
 */

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;


public class Socket01 {
	public static String getTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
		return sdf.format(new Date());
	}
	
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		try {
			serverSocket = new ServerSocket(5000);
			System.out.println(getTime() + "접속되었습니다.");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		while (true) {
			System.out.println(getTime() + "접속 대기중 ...");
			try {
				Socket socket = serverSocket.accept();
				System.out.println(getTime() + " " + socket.getInetAddress() + "로부터 요청이 들어욤.");
				OutputStream outputStream = socket.getOutputStream();
				DataOutputStream dataout = new DataOutputStream(outputStream);
				
				//원격 소켓 보내기
				dataout.writeUTF(getTime() + "서버에서 온 메시지 입니다.");
				System.out.println(getTime() + "데이터를 전송했습니다.");
				
				dataout.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
	}

}
package socket;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientSocket {
	public static void main(String[] args) {
		String serverIP = "127.0.0.1"; //localhost
		System.out.println("서버에 연결 중입니다." + serverIP);
		
		Socket socket = null;
		try {
			socket = new Socket(serverIP, 5000);
			
			InputStream in = socket.getInputStream();
			DataInputStream dis = new DataInputStream(in);
			
			System.out.println("서버에서 보내온 메시지 : " + dis.readUTF());
			System.out.println("연결종료");
			dis.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

 

■ 채팅 만들기

 

package chatting;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client01 {
   public static void main(String[] args) {
      Scanner sc = null;
      Socket socket = null;

      try {
         sc = new Scanner(System.in);
         socket = new Socket("localhost", 5000);

         // 출력작업
         OutputStream os = socket.getOutputStream();
         OutputStreamWriter osw = new OutputStreamWriter(os);
         BufferedWriter bw = new BufferedWriter(osw);

         String txt = "";

         while (true) {
            System.out.print("내용");
            txt = sc.nextLine();
            bw.write(txt + "\n");
            bw.flush();
         }

      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         if (socket != null) {
            try {
               socket.close();
            } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
         }
         sc.close();
      }

   }
}
package chatting;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server01 {
	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		
		try {
			System.out.println("서버 실행합니다.");
			serverSocket = new ServerSocket(5000);
			Socket s = serverSocket.accept();
			System.out.println("접속 성공");
			
			InputStream is = s.getInputStream();
			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader br = new BufferedReader(isr);
			
			while (true) {
				System.out.println(br.readLine());
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(serverSocket != null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
}
package chatting;

import java.awt.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.*;

public class Client02 implements ActionListener, Runnable {

	private Socket socket;
	private ObjectInputStream ois;
	private ObjectOutputStream oos;
	private JFrame jframe; // 윈도우 창
	private JTextField jtf; // 채팅 입력란
	private JTextArea jta; // 채팅 내용 보여주는 객체
	private JLabel jlb1, jlb2; // 라벨
	private JPanel jp1, jp2; // 판넬
	private String ip; // IP 주소를 저장할 변수
	private String id; // 닉네임 저장할 변수
	private JButton jbtn; // 종료버튼

	public Client02(String argId) {
		ip = "172.30.1.19";
		id = argId;
		jframe = new JFrame("멀티 채팅 ver 1.1");
		// 아래에 붙는 코드
		jp1 = new JPanel();
		jp1.setLayout(new BorderLayout());
		jtf = new JTextField(30); // 30문자
		jbtn = new JButton("종료"); // 종료 버튼 생성
		jp1.add(jbtn, BorderLayout.EAST);
		jp1.add(jtf, BorderLayout.CENTER);
		// 위쪽에 붙이는 판넬 코드
		jp2 = new JPanel(); // 위쪽에 붙는 판넬
		jp2.setLayout(new BorderLayout());
		jlb1 = new JLabel("대화명 : [[" + id + "]]"); // IP주소 : 127.0.0.1
		jlb1.setBackground(Color.YELLOW);
		jlb2 = new JLabel("IP 주소 : " + ip); // IP주소 : 127.0.0.1
		jlb2.setBackground(Color.GREEN);
		jp2.add(jlb1, BorderLayout.CENTER);
		jp2.add(jlb2, BorderLayout.EAST);
		// 프레임에 붙이는 코드
		jta = new JTextArea("", 10, 50);
		jta.setBackground(Color.ORANGE);
		JScrollPane jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		jframe.add(jp1, BorderLayout.SOUTH);
		jframe.add(jp2, BorderLayout.NORTH);
		jframe.add(jsp, BorderLayout.CENTER);
		// 감지기 붙이는 코드
		jtf.addActionListener(this);
		jbtn.addActionListener(this);
		// x클릭시 처리하는 코드 등 정의
		jframe.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				try {
					oos.writeObject(id + "#exit");
				} catch (Exception ee) {
					ee.printStackTrace();
				}
				System.exit(0); // 프로그램종료
			} //

			@Override
			public void windowOpened(WindowEvent e) { // 이벤트 처리
				jtf.requestFocus(); // jtf에 포커스를 놓는다.
			}
		}); // 윈도우 이벤트 처리 끝
		jta.setEditable(false); // 편집 X , 채팅 내용 보여주기만 함
		jframe.pack(); // 자동 크기 지정
		jframe.setResizable(false); // 창 크기 변경 X
		jframe.setVisible(true); // 보이기
	} // 생성자

	@Override
	public void actionPerformed(ActionEvent e) {
		Object obj = e.getSource(); // 이벤트 발생 위치 열기
		String msg = jtf.getText(); // 채팅 내용 입력 받기
		if (obj == jtf) {
			if (msg == null || msg.length() == 0) {
				// 경고창
				JOptionPane.showMessageDialog(jframe, "글을 쓰세요", "경고", JOptionPane.WARNING_MESSAGE);
			} else { // 내용을 입력하고 엔터한 경우
				try {
					oos.writeObject(id + "#" + msg);
				} catch (Exception ee) {
					ee.printStackTrace();
				}
				jtf.setText(""); // jtf를 지운다.
			} // else : 내용 0
		} else if (obj == jbtn) { // 종료 버튼 클릭
			try {
				oos.writeObject(id + "#exit");
			} catch (Exception ee) {
				ee.printStackTrace();
			}
			System.exit(0);
		}
	}

	public void init() {
		try {
			socket = new Socket(ip, 5000);
			System.out.println("서버에 접속되었습니다... 주인님^^");
			oos = new ObjectOutputStream(socket.getOutputStream());
			ois = new ObjectInputStream(socket.getInputStream());
			Thread t = new Thread(this);
			t.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		Scanner sc = new Scanner(System.in);
		String name = "";
		do {
			System.out.println("이름을 입력하세요.(3글자 이상)");
			name = sc.next();
		} while (name.length() < 3);
		
		Client02 cc = new Client02(name);
		cc.init();
		sc.close();
	}

	@Override
	public void run() {
		String message = null;
		String[] receiveMsg = null;
		boolean isStop = false;
		while (!isStop) {
			try {
				message = (String) ois.readObject(); // 채팅내용
				receiveMsg = message.split("#");
			} catch (Exception e) {
				e.printStackTrace();
				isStop = true; // 반복문 종료로 설정
			}
			System.out.println(receiveMsg[0] + " : " + receiveMsg[1]);
			if (receiveMsg[1].equals("exit")) {
				if (receiveMsg[0].equals(id)) {
					System.exit(0);
				} else {
					jta.append(receiveMsg[0] + "님이 종료했습니다\n");
					// 커서를 현재 채팅 내용의 자리에 보여준다.
					jta.setCaretPosition(jta.getDocument().getLength());
				}
			} else {
				jta.append(receiveMsg[0] + " : " + receiveMsg[1] + "\n"); // 홍길 : 안녕
				// 커서를 현재 채팅 내용의 자리에 보여준다.
				jta.setCaretPosition(jta.getDocument().getLength());
			}
		}
	}

}
package chatting;

import java.awt.*;
import java.io.*; //  입출력이 일어난다.
import java.net.*; //  네트워크 프로그램.
import java.util.*; //  ArrayList 사용(클라이언트를 담는 역할)
import javax.swing.*;

public class Server02 extends JFrame {
	private ArrayList<MultiServerThread> list;
	private Socket socket;
	JTextArea ta;
	JTextField tf;

	public Server02() {
		// 화면 디자인 코드
		setTitle("채팅 서버 ver 1.1");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		ta = new JTextArea();
		add(new JScrollPane(ta));
		tf = new JTextField();
		tf.setEditable(false);
		add(tf, BorderLayout.SOUTH);
		setSize(300, 300);
		setVisible(true);

		// 채팅 관련 코드
		list = new ArrayList<MultiServerThread>();
		try {
			ServerSocket serverSocket = new ServerSocket(5000);
			MultiServerThread mst = null;// 한 사용자 담당할 채팅 객체
			boolean isStop = false; // 깃발 값
			tf.setText("서버 정상 실행중입니다. 주인님^^\n");
			while (!isStop) {
				socket = serverSocket.accept();// 클라이언트별 소켓 생성
				mst = new MultiServerThread();// 채팅 객체 생성
				list.add(mst);// ArrayList에 채팅 객체 하나 담는다.
				mst.start();// 쓰레드 시작
			} // while
		} catch (IOException e) {
			e.printStackTrace();
		} // catch
	}// 생성자

	public static void main(String[] args) {
		new Server02();
	}// main

	// 내부 클래스
	class MultiServerThread extends Thread {
		private ObjectInputStream ois;
		private ObjectOutputStream oos;

		@Override
		public void run() {
			boolean isStop = false; // flag value(깃발 값)
			try {
				ois = new ObjectInputStream(socket.getInputStream());
				oos = new ObjectOutputStream(socket.getOutputStream());
				String message = null; // 채팅 내용을 저장할 변수
				while (!isStop) {
					message = (String) ois.readObject();// 클라이언트 입력 받기
					String[] str = message.split("#");// 홍길동#방가방가
					if (str[1].equals("exit")) { // 홍길동#exit, 종료하겠다는 뜻
						broadCasting(message);// 모든 사용자에게 내용 전달
						isStop = true; // 종료
					} else {
						broadCasting(message);// 모든 사용자에게 채팅 내용 전달
					} // else
				} // while
				list.remove(this);// 홍길동을 뺀다.
				ta.append(socket.getInetAddress() + " IP 주소의 사용자께서 종료하셨습니다.\n");
				tf.setText("남은 사용자 수 : " + list.size());
			} catch (Exception e) {
				list.remove(this);// 장길산을 뺀다.
				ta.append(socket.getInetAddress() + " IP 주소의 사용자께서 비정상 종료하셨습니다.");
				tf.setText("남은 사용자 수 : " + list.size());
			} // catch
		}// run

		public void broadCasting(String message) {// 모두에게 전송
			for (MultiServerThread ct : list) {
				ct.send(message);
			} // for
		}// broadCasting

		public void send(String message) { // 한 사용자에게 전송
			try {
				oos.writeObject(message);
			} catch (IOException e) {
				e.printStackTrace();
			} // catch
		}// send
	}// 내부 클래스

}// end

 

■ 서블릿을 활용한 보드 열기

 

 

list 라는 이름으로 boardList 를 보낸다.

 

 

사이즈 늘어나는 것 방지 

 

 

 

 

 

https://www.devkuma.com/docs/jsp-servlet/jsp%EC%97%90-%EC%A0%84%EB%8B%AC%ED%95%98%EA%B3%A0-%EA%B2%B0%EA%B3%BC%EB%A5%BC-forward%ED%95%98%EC%97%AC-%ED%91%9C%EC%8B%9C/

 

JSP/Servlet | 서블릿과 JSP/HTML | JSP에 전달하고 결과를 forward하여 표시

또 다른 방법은 포워드로 결과를 표시하는 JSP에 표시를 전환하는 것이다. 서블릿에서 결과를 표시하는 JSP를 포워드(forward)로 표시 시키면 서블릿에서 화면의 표시 등을 할 필요는 없다. 단, 이

www.devkuma.com

 

Color Code :: 색상표 | 색상 :: SAEKSANG.COM

 

Color Code :: 색상표 | 색상 :: SAEKSANG.COM

색상닷컴 :: SAEKSAG.COM

saeksang.com