InetAddress 클래스
2022. 10. 7. 16:44ㆍDev.Program/Java & Spring
728x90
======== JAVA0706
======== Ex.java
< InetAddress 클래스 >
import java.net.InetAddress; import java.net.UnknownHostException; public class Ex { public static void main(String[] args) { /* * InetAddress 클래스 * - 자바에서 IP 주소 관련 기능을 제공하는 클래스 */ String url = "www.itwillbs.co.kr"; try { // InetAddress 의 static 메서드인 getByName() 메서드를 사용하면 // 특정 URL 에 대한 IP 주소를 관리하는 InetAddress 객체를 가져올 수 있다! InetAddress inetAddr = InetAddress.getByName(url); // InetAddress 객체의 getXXX() 메서드를 호출하여 다양한 정보 가져오기 String hostName = inetAddr.getHostName(); // 대상 URL 의 호스트명 String hostAddress = inetAddr.getHostAddress(); // 대상 URL 의 서버 IP 주소 System.out.println(hostName + ", " + hostAddress); } catch (UnknownHostException e) { // 파라미터로 전달된 호스트 주소(도메인 포함)가 잘못됐을 경우 예외 발생 e.printStackTrace(); } } } |
// 2. 자신의 로컬 호스트(localhost)에 대한 정보 가져오기 // => 로컬호스트 : 현재 어플리케이션이 동작 중인 호스트(=자기 자신) InetAddress localhost = InetAddress.getLocalHost(); String localhostName = localhost.getHostName(); String localhostAddress = localhost.getHostAddress(); System.out.println(localhostName + ", " + localhostAddress); |
- 우리는 지금 VirtualBox 를 사용중이라 이렇게 가져옴
// 리턴받은 IP 주소를 옥텟(.) 기준으로 분리하여 배열에 저장 // ex) 192.168.1.200 => 0번 : 192, 1번 : 168, 2번 : 1, 3번 : 200 저장 // => String 클래스의 split() 메서드 필요 // => 단, 구분자가 마침표(.)일 경우 반드시 "\\." 형식으로 지정해야함 // 만약, 마침표만 기정할 경우 모든 문자를 구분자로 각각 사용함 String[] strIp = localhostAddress.split("\\."); for(String IpArr : strIp) { System.out.println(IpArr); } |
int[] ipArr = new int[4]; for(int i = 0; i < strIp.length; i++) { ipArr[i] = Integer.parseInt(strIp[i]); System.out.println(ipArr[i]); } |
// getAddress() 메서드를 사용하면 주소를 정수형으로 변환 가능 // ⇒ 단, byte[] 배열 타입으로 리턴되므로 // IP 주소 옥텟 범위가 0 ~ 255 이지만, 일부가 음수값을 갖게 됨 // 즉, 실제 사용하는 IP 주소 숫자 범위와 다른 값을 갖는다! ⇒ 변환필요 byte[] b = localhost.getAddress(); for(byte bb : b) { System.out.println(bb); } |
// getAddress() 메서드를 사용하면 주소를 정수형으로 변환 가능 // => 단, byte[] 배열 타입으로 리턴되므로 // IP 주소 옥텟 범위가 0 ~ 255 이지만, 일부가 음수값을 갖게 됨 // 즉, 실제 사용하는 IP 주소 숫자 범위와 다른 값을 갖는다! => 변환 필요 byte[] b = localhost.getAddress(); for(byte bb : b) { // System.out.println(bb); // 저장된 byte[] 배열 내의 값은 -128 ~ +127 사이이므로 // IP 주소의 128 ~ 255 사이의 값이 음수로 저장되어 있음 // (0 ~ 127 까지의 값은 그대로 저장되어 있음) // => 128 ~ 255 사이의 값을 만들려면 0보다 작은 값 + 256 System.out.println(bb < 0 ? bb + 256 : bb); } |
======== Ex2.java
- 마우스 갖다대면 2번째 거 클릭해서 try~catch 추가
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; public class Ex2 { public static void main(String[] args) { /* * URL 클래스 * - URL : Uniform Resource Locator * - URL 정보를 객체로 관리하는 클래스 * => 파일, 디렉토리, DB의 Query 등 다양한 형식의 객체 관리 */ BufferedReader buffer = null; try { // 특정 URL 정보를 객체로 관리하기 위해 URL 인스턴스 생성 시 URL 주소 전달 URL url = new URL("http://www.itwillbs.co.kr"); // 대상 URL 로부터 전달되는 데이터를 byte 타입으로 관리하기 위해 // InputStream 타입 객체로 리턴받음(해당 주소의 웹페이지 정보 전달됨) // InputStream is = url.openStream(); // 정보에 대한 처리 방식을 byte -> char 단위로 변경하기 위해 // InputStream -> InputStreamReader 객체로 변환 // InputStreamReader reader = new InputStreamReader(is); // 전달된 모든 문자들을 문자열 단위로 처리하기 위해 // InputStreamReader -> BufferedReader 객체로 변환 // BufferedReader buffer = new BufferedReader(reader); // 위의 세 문장을 한 문장으로 결합할 경우 buffer = new BufferedReader(new InputStreamReader(url.openStream())); String str = buffer.readLine(); while(str != null) { // 읽어온 문자열이 null(Ctrl + Z) 인지 판별 System.out.println(str); str = buffer.readLine(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { buffer.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
- 자바코드로 간단하게 크롤링해봄!~ (무식하게 다 긁어오는거)
// URL 객체에 대한 메타 데이터 정보 가져오기 url = new URL("http://www.google.co.kr/index.html"); System.out.println("프로토콜 : " + url.getProtocol()); System.out.println("포트번호 : " + url.getDefaultPort()); System.out.println("호스트명 : " + url.getHost()); System.out.println("파일명 : " + url.getFile()); |
- getXXX() 메서드로 다양한 정보들을 가져올 수 있다
======== Ex3.java
import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class Ex3 { public static void main(String[] args) { /* * URLConnection 클래스 * - 대상 URL 객체와 어플리케이션에 대한 연결(통신)을 담당하는 클래스 * - 주로, 원격지 자원에 대한 속성 정보, 대상 파일에 대한 정보 읽기 등 지원 */ try { URL url = new URL("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"); // URLConnection 객체를 얻기 위해 URL 객체의 openConnection() 메서드 호출 URLConnection con = url.openConnection(); // URLConnection 객체의 connect() 메서드를 호출하여 해당 URL 에 접속 con.connect(); System.out.println("대상 자원의 타입 : " + con.getContentType()); System.out.println( "대상 자원(파일) 크기 : " + con.getContentLength() + " Byte"); System.out.println("대상 자원 최종 수정일 : " + con.getLastModified()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } |
System.out.println("대상 자원 최종 수정일 : " + new Date(con.getLastModified())); |
======== Ex4.java
import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; public class Ex4 { public static void main(String[] args) { /* * URLEncoder & URLDecoder 클래스 * - 문자열을 "x-www-urlencoded" 형식(MIME 형식)으로 변환하여 사용하는 클래스 * - URLEncoder 클래스는 기본 문자열 -> 인코딩 된 문자열로 변환 * => URLEncoder.encode() 메서드 사용 * - URLDecoder 클래스는 인코딩 된 문자열 -> 기본 문자열로 변환 * => URLDecoder.decode() 메서드 사용 * * < URL 에 사용되는 문자열 변환 규칙 > * 1. 아스키코드 문자(A ~ Z, a ~ z, 0 ~ 9) 는 그대로 변환됨 * 2. 공백 문자는 + 기호로 변환 * 3. 특수문자는 경우에 따라 변환되거나 변환되지 않음 * 4. 기타 문자(한글, 한자 등)는 % 기호 뒤에 16진수 2자리로 변환 * */ try { String originalStr = "[ITWILL Java : 자바 프로그래밍 1]"; // URLEncoder 클래스의 encode() 메서드를 사용하여 원본 문자열을 인코딩 // => URLEncoder.encode(원본문자열, "인코딩방식"); String encodingStr = URLEncoder.encode(originalStr, "UTF-8"); System.out.println(encodingStr); // %5BITWILL+Java+%3A+%EC%9E%90%EB%B0%94+%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D+1%5D // URLDecoder 클래스의 decode() 메서드를 사용하여 인코딩 된 문자열을 복구 // => URLDecoder.decode(인코딩 된 문자열, "인코딩방식"); String decodingStr = URLDecoder.decode(encodingStr, "UTF-8"); System.out.println(decodingStr); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } |
======== Server.java
import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) { /* * 소켓 프로그래밍(Socket Programming) * - 통신을 하기 위해 사용되는 포트를 소켓(Socket)이라고 함 * - 소켓을 사용하여 원격 호스트와의 I/O 통신 상태를 구축 * => Socket 클래스 활용 * - 서버측에서는 추가적으로 ServerSocket 클래스를 사용하여 * 클라이언트로부터의 요청을 받아들이는 작업 추가적으로 필요 */ // Socket socket = null; ServerSocket serverSocket = null; try { // ServerSocket 객체를 생성하면서, 포트번호를 파라미터로 전달하여 // 해당 포트를 소켓 통신용으로 오픈(클라이언트 접속을 위해 열어두기) int port = 9999; serverSocket = new ServerSocket(port); // => 지정된 포트가 사용중일 경우 IOException 발생할 수 있음 } catch (IOException e) { e.printStackTrace(); } try { while(true) { // 클라이언트로부터 서버 접속 요청이 발생할 때까지 대기하다가 // 클라이언트로부터 요청이 발생하면 해당 요청을 받아서 // 상대 클라이언트와 소켓 연결 후 Socket 객체 리턴 Socket socket = serverSocket.accept(); // 연결된 클라이언트에게 메세지 전송 // 1. 상대방과 연결된 Socket 객체로부터 출력스트림 가져오기 OutputStream os = socket.getOutputStream(); // 2. 상대방에게 전달할 데이터를 스트림 객체로 생성 // => Object 타입으로 전달하기 위해 ObjectOutputStream 객체 생성 ObjectOutputStream oos = new ObjectOutputStream(os); // 3. ObjectOutputStream 객체의 writeObject() 메서드를 호출하여 // 전달할 데이터(객체)를 생성하여 전달 String str = "Hello, World!"; oos.writeObject(str); socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } |
======== Client.java
import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] args) { try { // Socket 객체를 생성하여 접속할 서버 정보 입력 후 접속 수행 String host = "192.168.1.200"; // 접속할 서버의 IP 주소 int port = 9999; // 접속할 서버의 포트번호 Socket socket = new Socket(host, port); // 지정된 서버에 접속 // 서버로부터 수신된 데이터를 읽어오기 위해 InputStream 객체 가져오기 InputStream is = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(is); System.out.println("서버로부터 전달된 데이터 : " + ois.readObject()); ois.close(); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
- server.java 부터 실행하기
- Client.java 에서 실행하면 이렇게 뜸
======== SimpleChatServer.java (JFrame 상속)
import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class SimpleChatServer extends JFrame { JTextArea ta; JTextField tf; ServerSocket serverSocket; Socket socket; public SimpleChatServer() { showFrame(); // service(); // 이렇게 호출도 가능 } private void showFrame() { setTitle("채팅 서버"); setBounds(400, 300, 400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 채팅 메세지 출력을 위한 JTextArea 생성 및 부착 - CENTER 영역 부착 ta = new JTextArea(); ta.setBackground(Color.LIGHT_GRAY); // 배경색 변경 ta.setEditable(false); // 입력 잠금 설정 add(ta, BorderLayout.CENTER); // 채팅 메세지 입력을 위한 JTextField 생성 및 부착 - SOUTH 영역에 부착 tf = new JTextField(); add(tf, BorderLayout.SOUTH); // JTextField 에 메세지 입력 후 엔터키 눌렀을 때 이벤트 처리 // => ActionListener 연결 tf.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { sendMsg(); } }); setVisible(true); // 화면 표시 후 메세지 입력 창에 커서 요청 tf.requestFocus(); // 채팅 서비스 시작을 위해 service() 메서드 호출 service(); } // 채팅 서비스 동작을 위한 코드 기술 public void service() { try { ta.append("채팅 서비스 준비중...\n"); // 1. 채팅 서버를 열기 위한 ServerSocket 객체 생성 및 포트 번호 생성 int port = 9999; serverSocket = new ServerSocket(port); ta.append("클라이언트 접속 대기중...\n"); // 2. 클라이언트로부터 요청 대기 및 요청 시 소켓 연결 수행 socket = serverSocket.accept(); // 접속한 클라이언트 IP 주소 알아내기(Socket 객체의 getInetAddress()) ta.append("클라이언트가 접속했습니다. - " + socket.getInetAddress() + "\n"); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } // JTextField 에 메세지 입력 후 엔터키 입력 시 입력받은 메세지를 클라이언트에게 전송 public void sendMsg() { } public static void main(String[] args) { new SimpleChatServer(); } } |
======== SimpleChatClient.java (JFrame 상속)
import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class SimpleChatClient extends JFrame { JTextArea ta; JTextField tf; Socket socket; public SimpleChatClient() { showFrame(); } private void showFrame() { setTitle("채팅 클라이언트"); setBounds(400, 300, 400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 채팅 메세지 출력을 위한 JTextArea 생성 및 부착 - CENTER 영역 부착 ta = new JTextArea(); ta.setBackground(Color.LIGHT_GRAY); // 배경색 변경 ta.setEditable(false); // 입력 잠금 설정 add(ta, BorderLayout.CENTER); // 채팅 메세지 입력을 위한 JTextField 생성 및 부착 - SOUTH 영역에 부착 tf = new JTextField(); add(tf, BorderLayout.SOUTH); // JTextField 에 메세지 입력 후 엔터키 눌렀을 때 이벤트 처리 // => ActionListener 연결 tf.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { sendMsg(); } }); setVisible(true); // 접속할 서버의 IP 주소 입력을 위한 다이얼로그 생성 String ip = JOptionPane.showInputDialog(this, "접속할 서버 IP 주소 입력"); if(ip == null || ip.equals("")) { JOptionPane.showMessageDialog(this, "IP 주소 입력 필수!"); return; } // 화면 표시 후 메세지 입력 창에 커서 요청 tf.requestFocus(); service(ip); } public void service(String ip) { try { // 서버 접속을 위한 Socket 객체 생성 int port = 9999; socket = new Socket(ip, port); ta.append("서버 접속 완료. \n"); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // JTextField 에 메세지 입력 후 엔터키 입력 시 입력받은 메세지를 클라이언트에게 전송 public void sendMsg() { } public static void main(String[] args) { new SimpleChatClient(); } } |
- 서버부터 실행
- 클라이언트에서 자기 IP 주소 적어보기
- 서버 창에 자기 아이피주소 뜨면 성공!
< SimpleChatServer.java >
import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class SimpleChatServer extends JFrame { JTextArea ta; JTextField tf; ServerSocket serverSocket; Socket socket; // 문자열로 된 메세지 송수신을 위한 // DataOutputStream, DataInputStream 변수 선언 DataOutputStream dos; DataInputStream dis; public SimpleChatServer() { showFrame(); // service(); // 이렇게 호출도 가능 } private void showFrame() { setTitle("채팅 서버"); setBounds(400, 300, 400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 채팅 메세지 출력을 위한 JTextArea 생성 및 부착 - CENTER 영역 부착 ta = new JTextArea(); ta.setBackground(Color.LIGHT_GRAY); // 배경색 변경 ta.setEditable(false); // 입력 잠금 설정 add(ta, BorderLayout.CENTER); // 채팅 메세지 입력을 위한 JTextField 생성 및 부착 - SOUTH 영역에 부착 tf = new JTextField(); add(tf, BorderLayout.SOUTH); // JTextField 에 메세지 입력 후 엔터키 눌렀을 때 이벤트 처리 // => ActionListener 연결 tf.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { sendMsg(); } }); setVisible(true); // 화면 표시 후 메세지 입력 창에 커서 요청 tf.requestFocus(); // 채팅 서비스 시작을 위해 service() 메서드 호출 service(); } // 채팅 서비스 동작을 위한 코드 기술 public void service() { try { ta.append("채팅 서비스 준비중...\n"); // 1. 채팅 서버를 열기 위한 ServerSocket 객체 생성 및 포트 번호 생성 int port = 9999; serverSocket = new ServerSocket(port); ta.append("클라이언트 접속 대기중...\n"); // 2. 클라이언트로부터 요청 대기 및 요청 시 소켓 연결 수행 socket = serverSocket.accept(); // 접속한 클라이언트 IP 주소 알아내기(Socket 객체의 getInetAddress()) ta.append("클라이언트가 접속했습니다. - " + socket.getInetAddress() + "\n"); // --------------------------------------------------------- // 클라이언트에게 환영 메세지 전송 // 1. 출력스트림 가져와서 DataOutputStream 객체 생성 dos = new DataOutputStream(socket.getOutputStream()); // 2. DataOutputStream 객체의 writeUTF() 메서드 호출하여 문자열 데이터 전송 dos.writeUTF("서버 : 채팅 서버에 접속하신 것을 환영합니다!"); // --------------------------------------------------------- dos.close(); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } // JTextField 에 메세지 입력 후 엔터키 입력 시 입력받은 메세지를 클라이언트에게 전송 public void sendMsg() { } public static void main(String[] args) { new SimpleChatServer(); } } |
< SimpleChatClient.java >
import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class SimpleChatClient extends JFrame { JTextArea ta; JTextField tf; // 문자열로 된 메세지 송수신을 위한 // DataOutputStream, DataInputStream 변수 선언 DataOutputStream dos; DataInputStream dis; Socket socket; public SimpleChatClient() { showFrame(); } private void showFrame() { setTitle("채팅 클라이언트"); setBounds(400, 300, 400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 채팅 메세지 출력을 위한 JTextArea 생성 및 부착 - CENTER 영역 부착 ta = new JTextArea(); ta.setBackground(Color.LIGHT_GRAY); // 배경색 변경 ta.setEditable(false); // 입력 잠금 설정 add(ta, BorderLayout.CENTER); // 채팅 메세지 입력을 위한 JTextField 생성 및 부착 - SOUTH 영역에 부착 tf = new JTextField(); add(tf, BorderLayout.SOUTH); // JTextField 에 메세지 입력 후 엔터키 눌렀을 때 이벤트 처리 // => ActionListener 연결 tf.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { sendMsg(); } }); setVisible(true); // 접속할 서버의 IP 주소 입력을 위한 다이얼로그 생성 String ip = JOptionPane.showInputDialog(this, "접속할 서버 IP 주소 입력"); if(ip == null || ip.equals("")) { JOptionPane.showMessageDialog(this, "IP 주소 입력 필수!"); return; } // 화면 표시 후 메세지 입력 창에 커서 요청 tf.requestFocus(); service(ip); } public void service(String ip) { try { // 서버 접속을 위한 Socket 객체 생성 int port = 9999; socket = new Socket(ip, port); ta.append("서버 접속 완료. \n"); // --------------------------------------------------------- // 1. 입력스트림 가져와서 DataInputStream 객체 생성 dis = new DataInputStream(socket.getInputStream()); // 2. DataInputStream 객체의 readUTF() 메서드 호출하여 문자열 데이터 전송 String str = dis.readUTF(); // 3. JTextField 에 수신된 문자열 출력 ta.append(str + "\n"); // --------------------------------------------------------- dis.close(); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // JTextField 에 메세지 입력 후 엔터키 입력 시 입력받은 메세지를 클라이언트에게 전송 public void sendMsg() { } public static void main(String[] args) { new SimpleChatClient(); } } |
- 똑같이 실행해보기
>>>>> + 멀티스레드(최종 코드)
< SimpleChatServer.java >
import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class SimpleChatServer extends JFrame { JTextArea ta; JTextField tf; ServerSocket serverSocket; Socket socket; // 문자열로 된 메세지 송수신을 위한 // DataOutputStream, DataInputStream 변수 선언 DataOutputStream dos; DataInputStream dis; boolean stopSignal; public SimpleChatServer() { showFrame(); // service(); // 이렇게 호출도 가능 } private void showFrame() { setTitle("채팅 서버"); setBounds(400, 300, 400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 채팅 메세지 출력을 위한 JTextArea 생성 및 부착 - CENTER 영역 부착 ta = new JTextArea(); ta.setBackground(Color.LIGHT_GRAY); // 배경색 변경 ta.setEditable(false); // 입력 잠금 설정 add(ta, BorderLayout.CENTER); // 채팅 메세지 입력을 위한 JTextField 생성 및 부착 - SOUTH 영역에 부착 tf = new JTextField(); add(tf, BorderLayout.SOUTH); // JTextField 에 메세지 입력 후 엔터키 눌렀을 때 이벤트 처리 // => ActionListener 연결 tf.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { sendMsg(); } }); setVisible(true); // 화면 표시 후 메세지 입력 창에 커서 요청 tf.requestFocus(); // 채팅 서비스 시작을 위해 service() 메서드 호출 service(); } // 채팅 서비스 동작을 위한 코드 기술 public void service() { try { ta.append("채팅 서비스 준비중...\n"); // 1. 채팅 서버를 열기 위한 ServerSocket 객체 생성 및 포트 번호 생성 int port = 9999; serverSocket = new ServerSocket(port); ta.append("클라이언트 접속 대기중...\n"); // 2. 클라이언트로부터 요청 대기 및 요청 시 소켓 연결 수행 socket = serverSocket.accept(); // 접속한 클라이언트 IP 주소 알아내기(Socket 객체의 getInetAddress()) ta.append("클라이언트가 접속했습니다. - " + socket.getInetAddress() + "\n"); // --------------------------------------------------------- // 1. 입력스트림, 출력스트림 가져와서 DataXXXStream 객체 생성 dis = new DataInputStream(socket.getInputStream()); dos = new DataOutputStream(socket.getOutputStream()); // 클라이언트에게 환영 메세지 전송 dos.writeUTF("서버 : 채팅 서버에 접속하신 것을 환영합니다!"); Thread t = new Thread(new Runnable() { @Override public void run() { try { while(!stopSignal) { // 중지 신호가 올때까지 반복 // 2. DataInputStream 객체의 readUTF() 메서드 호출하여 문자열 데이터 전송 String str = dis.readUTF(); // 3. JTextField 에 수신된 문자열 출력 ta.append(str + "\n"); } } catch (EOFException e) { // 접속이 끊어질 경우 발생하는 예외 처리 // e.printStackTrace(); System.out.println("클라이언트로부터 접속 끊어짐!"); } catch (IOException e) { e.printStackTrace(); } finally { try { dis.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }); // 멀티쓰레딩 실행을 위해 start() 메서드 호출 t.start(); } catch (IOException e) { e.printStackTrace(); } } // JTextField 에 메세지 입력 후 엔터키 입력 시 입력받은 메세지를 클라이언트에게 전송 public void sendMsg() { try { // JTextField 에 입력된 메세지를 가져오기 String msg = tf.getText(); // 입력된 메세지를 JTextArea 에 출력(내 채팅창에 표시) ta.append(msg + "\n"); // 만약, 입력된 메세지(문자열)가 "/exit" 이면, "bye" 메세지 출력 후 종료 if(msg.equals("/exit")) { ta.append("bye"); // 메세지 출력 // 현재 반복중인 수신 쓰레드에 종료 신호 전달 stopSignal = true; // 출력스트림, 소켓 자원 반환 dos.close(); socket.close(); serverSocket.close(); // 현재 어플리케이션 종료 System.exit(0);; } else { // 입력된 문자열이 "/exit" 가 아니면 클라이언트에게 메세지 전송 dos.writeUTF("서버 : " + msg); // JTextField 입력창 초기화 및 커서 요청 tf.setText(""); tf.requestFocus(); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new SimpleChatServer(); } } |
< SimpleChatClient.java >
import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class SimpleChatClient extends JFrame { JTextArea ta; JTextField tf; // 문자열로 된 메세지 송수신을 위한 // DataOutputStream, DataInputStream 변수 선언 DataOutputStream dos; DataInputStream dis; boolean stopSignal; // 멀티쓰레딩 중지 신호를 저장할 변수 Socket socket; public SimpleChatClient() { showFrame(); } private void showFrame() { setTitle("채팅 클라이언트"); setBounds(400, 300, 400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 채팅 메세지 출력을 위한 JTextArea 생성 및 부착 - CENTER 영역 부착 ta = new JTextArea(); ta.setBackground(Color.LIGHT_GRAY); // 배경색 변경 ta.setEditable(false); // 입력 잠금 설정 add(ta, BorderLayout.CENTER); // 채팅 메세지 입력을 위한 JTextField 생성 및 부착 - SOUTH 영역에 부착 tf = new JTextField(); add(tf, BorderLayout.SOUTH); // JTextField 에 메세지 입력 후 엔터키 눌렀을 때 이벤트 처리 // => ActionListener 연결 tf.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { sendMsg(); } }); setVisible(true); // 접속할 서버의 IP 주소 입력을 위한 다이얼로그 생성 String ip = JOptionPane.showInputDialog(this, "접속할 서버 IP 주소 입력"); if(ip == null || ip.equals("")) { JOptionPane.showMessageDialog(this, "IP 주소 입력 필수!"); return; } // 화면 표시 후 메세지 입력 창에 커서 요청 tf.requestFocus(); service(ip); } public void service(String ip) { try { // 서버 접속을 위한 Socket 객체 생성 int port = 9999; socket = new Socket(ip, port); ta.append("서버 접속 완료. \n"); // --------------------------------------------------------- // 1. 입력스트림, 출력스트림 가져와서 DataXXXStream 객체 생성 dis = new DataInputStream(socket.getInputStream()); dos = new DataOutputStream(socket.getOutputStream()); // --------------------------------------------------- // 서버로부터 전달받는 메세제 출력을 위한 멀티쓰레딩 구현 Thread t = new Thread(new Runnable() { @Override public void run() { try { while(!stopSignal) { // 중지 신호가 올때까지 반복 // 2. DataInputStream 객체의 readUTF() 메서드 호출하여 문자열 데이터 전송 String str = dis.readUTF(); // 3. JTextField 에 수신된 문자열 출력 ta.append(str + "\n"); } } catch (EOFException e) { // 접속이 끊어질 경우 발생하는 예외 처리 // e.printStackTrace(); System.out.println("서버로부터 접속 끊어짐!"); } catch (IOException e) { e.printStackTrace(); } finally { try { dis.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }); // 멀티쓰레딩 실행을 위해 start() 메서드 호출 t.start(); // --------------------------------------------------------- // dis.close(); // socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // JTextField 에 메세지 입력 후 엔터키 입력 시 입력받은 메세지를 서버에게 전송 public void sendMsg() { try { // JTextField 에 입력된 메세지를 가져오기 String msg = tf.getText(); // 입력된 메세지를 JTextArea 에 출력(내 채팅창에 표시) ta.append(msg + "\n"); // 만약, 입력된 메세지(문자열)가 "/exit" 이면, "bye" 메세지 출력 후 종료 if(msg.equals("/exit")) { ta.append("bye"); // 메세지 출력 // 현재 반복중인 수신 쓰레드에 종료 신호 전달 stopSignal = true; // 출력스트림, 소켓 자원 반환 dos.close(); socket.close(); // 현재 어플리케이션 종료 System.exit(0);; } else { // 입력된 문자열이 "/exit" 가 아니면 서버에게 메세지 전송 dos.writeUTF("클라이언트 : " + msg); // JTextField 입력창 초기화 및 커서 요청 tf.setText(""); tf.requestFocus(); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new SimpleChatClient(); } } |
- 채팅창 쳐보면 서로 주고받는 거 확인할 수 있다!
- 메세지 창에 쳐보면
- 콘솔창에서 확인가능
728x90
'Dev.Program > Java & Spring' 카테고리의 다른 글
[Spring] - (2) (0) | 2022.10.09 |
---|---|
[Spring] - (1)설치 및 설정하기 (0) | 2022.10.09 |
데이터 입출력 : IO(Input/Output) (0) | 2022.10.07 |
MVC2 - (5) (0) | 2022.10.07 |
MVC2 - (4) (0) | 2022.10.07 |