ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (국비교육) 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

     

Designed by Tistory.