자바 Gui 메신저 | Javafx Gui 채팅 프로그램 개발하기 ① 프로젝트 개요 (Javafx Multi-Chatting Project #1) 17634 좋은 평가 이 답변

당신은 주제를 찾고 있습니까 “자바 gui 메신저 – JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1)“? 다음 카테고리의 웹사이트 https://you.experience-porthcawl.com 에서 귀하의 모든 질문에 답변해 드립니다: you.experience-porthcawl.com/blog. 바로 아래에서 답을 찾을 수 있습니다. 작성자 동빈나 이(가) 작성한 기사에는 조회수 19,543회 및 좋아요 126개 개의 좋아요가 있습니다.

Table of Contents

자바 gui 메신저 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1) – 자바 gui 메신저 주제에 대한 세부정보를 참조하세요

JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1) 강의 동영상입니다. 이번 시간에는 프로젝트에 대해 간략히 소개하고 프로젝트 개발 환경을 구축하는 시간을 가집니다.

자바 gui 메신저 주제에 대한 자세한 내용은 여기를 참조하세요.

자바 GUI 네트워크 채팅프로그램 멀티쓰레드 구현코드

자바 Socket 통신을 기반으로 멀티쓰레드와, Swing GUI를 활용해 네트워크 채팅 프로그램을 구현해보았다. 기본적인 Socket 통신이 어떻게 이루어지는 …

+ 여기에 표시

Source: ssons.tistory.com

Date Published: 11/21/2021

View: 1402

자바 네트워킹 – GUI 채팅 프로그램 클라이언트 : 네이버 블로그

프로그램을 실행하면서 넘기는 아규먼트를 사용하지 않을 경우. 접속후 처음으로 넘어가는 메시지가 닉네임으로 사용됨.

+ 자세한 내용은 여기를 클릭하십시오

Source: blog.naver.com

Date Published: 12/24/2021

View: 4290

활용) GUI 채팅프로그램 – JAVA – invertKO

활용) GUI 채팅프로그램. invertKO 2019. 1. 30. 23:03. #Step1 폴더 구성. #Step2 서버 자바 프로젝트. -> Main.java와 client.java로 나뉜다. ① Main.java …

+ 여기에 표시

Source: invertko.tistory.com

Date Published: 12/17/2022

View: 804

GUI 채팅 프로그램 – JAVA

-누군가 로그인하면 상대방의 IP와 ID를 뿌려준다. -> 채팅을 즐긴다. . import java …

+ 여기에 보기

Source: invincure.tistory.com

Date Published: 1/17/2021

View: 86

[Java] 멀티채팅 프로그램 (GUI) – swk의 지식저장소

자바 멀티채팅 프로그램을 통하여 네트워크 소켓 통신의 기본을 알아봅시다. 한 서버에 여러 클라이언트 접속이 가능합니다.

+ 여기에 표시

Source: swk3169.tistory.com

Date Published: 1/9/2021

View: 6240

Java : GUI, 네트워크(1:1 채팅 프로그램 만들기) – 황금레시피

MainFrame import java.awt.BorderLayout; import java.awt.GrLayout; import java.awt.event.ActionEvent; import java.awt.event.

+ 여기에 자세히 보기

Source: programmingworld1.tistory.com

Date Published: 8/15/2021

View: 6342

Gui 멀티 채팅 프로그램 예제 – Code

자유코딩 님의 블로그입니다. 구독하기. 프로필 사진. Java 프로그래밍 예제의 다른 글. 자바 TCP 채팅 …

+ 여기에 보기

Source: fors.tistory.com

Date Published: 9/2/2021

View: 9910

[ JAVA/ GUI ] 네트워킹2/ 채팅창만들기3 – 별님 블로그

[ JAVA/ GUI ] 네트워킹2/ 채팅창만들기3/ 통신/ 자바네트워킹/ 자바채팅창만들기/ 자바통신/ 자바GUI네트워킹/ 자바GUI채팅창만들기/ 자바GUI통신/ …

+ 여기에 표시

Source: asterisco.tistory.com

Date Published: 8/18/2022

View: 7610

주제와 관련된 이미지 자바 gui 메신저

주제와 관련된 더 많은 사진을 참조하십시오 JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1). 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1)
JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1)

주제에 대한 기사 평가 자바 gui 메신저

  • Author: 동빈나
  • Views: 조회수 19,543회
  • Likes: 좋아요 126개
  • Date Published: 2018. 7. 21.
  • Video Url link: https://www.youtube.com/watch?v=0gMYlUppe-c

자바 GUI 네트워크 채팅프로그램 멀티쓰레드 구현코드

자바 Socket 통신을 기반으로 멀티쓰레드와, Swing GUI를 활용해 네트워크 채팅 프로그램을 구현해보았다.

기본적인 Socket 통신이 어떻게 이루어지는지 개념정리는 아래 링크를 참고하자.

위의 페이지에서 설명하는 것에서 추가된 것은 쓰레드이다.

서버

서버는 클라이언트 상대용 Socket을 자바 ArrayList에 저장하고 현재 상대하고 있는 하나의 클라이언트에만

국한되는 것이 아니라 ArrayList에 보관 중인 모든 Socket을 꺼내서 글을 쓴다.

클라이언트

수시로 날아오는 메시지 처리를 위해 글을 읽는 부분을 쓰레드로 빼서 처리한다.

쓰레드를 활용하지 않으면 글을 쓰고 있을 때 상대방이 주는 메시지를 리얼타임으로 받지 못한다.

총 코드

다섯 가지 클래스로 서버, 클라이언트, 쓰레드를 나누어서 작성한 코드를 예로 든다.

ChatServer 클래스와 Thread를 상속받은 ServerSocketThread를 살펴보자.

package chatting; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class ChatServer { ServerSocket serverSocket; Socket socket; List list; // ServerSocketThread 객체 저장 public ChatServer() { list = new ArrayList(); System.out.println(“서버가 시작되었습니다.”); } public void giveAndTake() { try { serverSocket = new ServerSocket(5420); // 소켓 접속 대기 serverSocket.setReuseAddress(true); // ServerSocket이 port를 바로 다시 사용한다 설정(port를 잡고있음) while(true) { socket = serverSocket.accept(); // accept -> 1. 소켓 접속 대기 2. 소켓 접속 허락 ServerSocketThread thread = new ServerSocketThread(this, socket); // this -> ChatServer 자신 addClient(thread); // 리스트에 쓰레드 객체 저장 thread.start(); } } catch (IOException e) { e.printStackTrace(); } } // synchronized : 쓰레드들이 공유데이터를 함께 사용하지 못하도록 하는 것 // 클라이언트가 입장 시 호출되며, 리스트에 클라이언트 담당 쓰레드 저장 private synchronized void addClient(ServerSocketThread thread) { // 리스트에 ServerSocketThread 객체 저장 list.add(thread); System.out.println(“Client 1명 입장. 총 ” + list.size() + “명”); } // 클라이언트가 퇴장 시 호출되며, 리스트에 클라이언트 담당 쓰레드 제거 public synchronized void removeClient(Thread thread) { list.remove(thread); System.out.println(“Client 1명 퇴장. 총 ” + list.size() + “명”); } // 모든 클라이언트에게 채팅 내용 전달 public synchronized void broadCasting(String str) { for(int i = 0; i < list.size(); i++) { ServerSocketThread thread = (ServerSocketThread)list.get(i); thread.sendMessage(str); } } } ChatServer 생성자에 제네릭 타입은 Thread로써 list배열을 선언해준다. arrayList에 접속한 thread객체를 저장하며 thread를 실행한다. thread가 실행하는 run 함수는 아래 클래스인 ServerSocketThread에서 실행한다. 아래 코드를 살펴보자. package chatting; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; public class ServerSocketThread extends Thread { Socket socket; ChatServer server; BufferedReader in; // 입력 담당 클래스 PrintWriter out; // 출력 담당 클래스 String name; String threadName; public ServerSocketThread(ChatServer server, Socket socket) { this.server = server; this.socket = socket; threadName = super.getName(); // Thread 이름을 얻어옴 System.out.println(socket.getInetAddress() + "님이 입장하였습니다."); // IP주소 얻어옴 System.out.println("Thread Name : " + threadName); } // 클라이언트로 메시지 출력 public void sendMessage(String str) { out.println(str); } // 쓰레드 @Override public void run() { try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // true : autoFlush 설정 out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); sendMessage("대화자 이름을 넣으세요"); name = in.readLine(); server.broadCasting("[" + name + "]님이 입장하셨습니다."); while(true) { String str_in = in.readLine(); server.broadCasting("[" + name + "] " + str_in); } } catch (IOException e) { System.out.println(threadName + " 퇴장했습니다."); server.removeClient(this); //e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } Client와 데이터를 주고받기 위해서 InputStream, OutputStream 생성 boradCasting 함수를 사용함으로써 모든 클라이언트에게 채팅 내용을 전달 무한 반복문에서 채팅 내용을 반복 클라이언트가 퇴장하는 경우 removeClient 함수 호출 package chatting; import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class ClientGui extends JFrame implements ActionListener, Runnable{ // 클라이언트 화면용 Container container = getContentPane(); JTextArea textArea = new JTextArea(); JScrollPane scrollPane = new JScrollPane(textArea); JTextField textField = new JTextField(); // 통신용 Socket socket; PrintWriter out; BufferedReader in; String str; // 채팅 문자열 저장 public ClientGui(String ip, int port) { // frame 기본 설정 setTitle("챗팅"); setSize(550, 400); setLocation(400, 400); init(); start(); setVisible(true); // 통신 초기화 initNet(ip, port); System.out.println("ip = " + ip); } // 통신 초기화 private void initNet(String ip, int port) { try { // 서버에 접속 시도 socket = new Socket(ip, port); // 통신용 input, output 클래스 설정 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // ture : auto flush 설정 out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); } catch (UnknownHostException e) { System.out.println("IP 주소가 다릅니다."); //e.printStackTrace(); } catch (IOException e) { System.out.println("접속 실패"); //e.printStackTrace(); } // 쓰레드 구동 Thread thread = new Thread(this); // run 함수 -> this thread.start(); } private void init() { container.setLayout(new BorderLayout()); container.add(“Center”, scrollPane); container.add(“South”, textField); } private void start() { setDefaultCloseOperation(EXIT_ON_CLOSE); textField.addActionListener(this); } // 응답 대기 // -> 서버로부터 응답으로 전달된 문자열을 읽어서, textArea에 출력하기 @Override public void run() { while(true) { try { str = in.readLine(); textArea.append(str + ”

“); } catch (IOException e) { e.printStackTrace(); } } } @Override public void actionPerformed(ActionEvent e) { // textField의 문자열을 읽어와서 서버로 전송함 str = textField.getText(); out.println(str); // textField 초기화 textField.setText(“”); } }

클라이언트 화면은 구성하고 initNet 함수를 통해

socket이 port를 통해서 서버에 접속을 시도함

글을 쓰기 위한 InputStream, 받기 위한 OutputStream 설정

쓰레드를 구동시킴으로써 채팅 기능을 활성화.

서버 메인, 클라이언트 메인에서 설정해놓은 클래스를 호출

package chatting; import java.net.InetAddress; import java.net.UnknownHostException; public class ClientGuiMain { public static void main(String[] args) { try { InetAddress ia = InetAddress.getLocalHost(); String ip_str = ia.toString(); String ip = ip_str.substring(ip_str.indexOf(“/”) + 1); new ClientGui(ip, 5420); } catch (UnknownHostException e) { e.printStackTrace(); } } } package chatting; public class ChatServerMain { public static void main(String[] args) { ChatServer server = new ChatServer(); server.giveAndTake(); } }

네트워크 환경을 쓰레드로써 구동시키는 방법의 흐름은 이해되나,

직접 코드를 작성하며 작동이 안 되는 어려움이 있었다.

java network Gui 채팅프로그램

자바 네트워킹 – GUI 채팅 프로그램 클라이언트

자바 네트워킹 – GUI 채팅 프로그램 클라이언트 지식 저장소 https://blog.naver.com/blackpencil/100189385478 클라이언트 메인 클래스 import java.awt.* ; import java.io.* ; import java.net.Socket ; import javax.swing.* ; public class Client extends Frame implements ActionListener { Client static = new JTextArea ( 20 , 40 ) ; JTextArea ta static = new JScrollPane ( ta ) ; JScrollPane scrollta = new JButton ( “전송” ) , btn_ip = new JButton ( “접속” ) ; JButton btn_msg, btn_ip = new JTextField ( 20 ) , t_ip = new JTextField ( 7 ) ; JTextField t_msg, t_ip = new JPanel ( ) , panel2 = new JPanel ( ) ; JPanel panel, panel2 ; Socket socket Sender sender ; // 소켓 생성 및 메시지 전송 클래스 ; // 텍스트필드에서 메세지와 _ip를 저장할 변수 String msg, ip boolean connect = false ; // 접속 여부 판단 카운터> f:비접속, t:접속중 static = null ; // _args[] 사용시 값을 저장할 변수 String arg_name Client ( ) { // 생성자 // 프레임 셋팅 setTitle ( “GUI Multi Chat” ) ; setLocation ( 200 , 200 ) ; setSize ( 500 , 450 ) ; // JTextArea add ( scroll, CENTER ) ; panel.scroll, BorderLayout // 수평 스크롤바 제거 scroll. setHorizontalScrollBarPolicy ( ScrollPaneConstants . HORIZONTAL_SCROLLBAR_NEVER ) ; // TextArea 배경색 설정 setBackground ( new Color ( 250 , 244 , 192 ) ) ; ta. // 입력 컴포넌트 패널 panel2. add ( t_msg ) ; panel2. add ( btn_msg ) ; panel2. add ( t_ip ) ; panel2. add ( btn_ip ) ; // 텍스트 필드 초기 텍스트 설정 t_msg. setText ( “닉네임을 입력하세요.” ) ; t_ip. setText ( “ip 주소 입력” ) ; // 프레임에 패널 추가 add ( panel2, SOUTH ) ; panel.panel2, BorderLayout ( panel, CENTER ) ; addpanel, BorderLayout // TextArea에 실행 방법을 추가 ta. append ( “접속 방법 : ip입력 -> 접속 버튼-> ” + “닉네임 입력 -> 전송버튼 -> 채팅시작 *^^*

” ) ; /* append() 는 텍스트 말미에 이어서 추가하므로 *

으로 개행시켜줘야함*/ // 윈도우 종료 이벤트 ( new WindowAdapter ( ) { addWindowListener public void windowClosing ( WindowEvent e ) { windowClosing System . exit ( 0 ) ; } } ) ; // 텍스트 필드 키보드 이벤트 addKeyListener ( new KeyAdapter ( ) { t_msg. public void keyPressed ( KeyEvent e ) { keyPressed // 엔터키 입력시 메시지를 보냄 if ( e. getKeyCode ( ) == KeyEvent . VK_ENTER ) { e. msg = t_msg. getText ( ) ; sender. sendMsg ( msg ) ; t_msg. setText ( “” ) ; } } } ) ; // 텍스트 필드 포커스 이벤트 addFocusListener ( new FocusAdapter ( ) { t_msg. // 텍스트 필드에 포커스가 왔을 때 필드를 공백으로 public void focusGained ( FocusEvent e ) { focusGained t_msg. setText ( “” ) ; } } ) ; addFocusListener ( new FocusAdapter ( ) { t_ip. // 텍스트 필드에 포커스가 왔을 때 필드를 공백으로 public void focusGained ( FocusEvent e ) { focusGained t_ip. setText ( “” ) ; } } ) ; // 버튼 이벤트 btn_msg. addActionListener ( this ) ; btn_ip. addActionListener ( this ) ; setVisible ( true ) ; } @Override public void actionPerformed ( ActionEvent e ) { actionPerformed // TODO Auto-generated method stub // 전송 버튼을 클릭 했을 때 if ( e. getSource ( ) == btn_msg ) { //System.out.println(“>>>click trans_btn”); if ( connect ) { try { // 접속중이라면 메시지를 넘김 msg = t_msg. getText ( ) ; sender. sendMsg ( msg ) ; t_msg. setText ( “” ) ; // 전송버튼 클릭후 포커스를 텍스트 필드로 돌림 t_msg. requestFocus ( ) ; } catch ( ex ) { Exception ex System . out . println ( “서버에 접속되지 않았습니다.” ) ; JOptionPane . showMessageDialog ( this , “서버에 접속되지 않았습니다.” , “알림” , JOptionPane . ERROR_MESSAGE ) ; t_msg. setText ( “닉네임을 입력하세요.” ) ; } } else { // 접속중이 아닐때 메시지를 넘긴다면 에러메시지 출력 System . out . println ( “서버에 접속되지 않았습니다.” ) ; JOptionPane . showMessageDialog ( this , “서버에 접속되지 않았습니다.” , “알림” , JOptionPane . ERROR_MESSAGE ) ; t_msg. setText ( “닉네임을 입력하세요.” ) ; } } // 접속 버튼을 클릭 했을 때 if ( e. getSource ( ) == btn_ip ) { //System.out.println(“>>>click ip_btn”); // 접속중이 아니라면 소캣을 생성해 서버에 연결 if ( ! connect ) { ip = t_ip. getText ( ) ; try { = new Socket ( ip, 9002 ) ; socketip, System . out . println ( “서버에 연결되었습니다.” ) ; ta. append ( “서버에 연결되었습니다.

” ) ; sender = new Sender ( socket, arg_name ) ; = new ReceiverThread ( socket ) ; Thread t2ReceiverThreadsocket t2. start ( ) ; setBackground ( Color . RED ) ; btn_ip. btn_ip. setText ( “접속중” ) ; connect = true ; // 접속중인지 아닌지를 판별할 카운터 } catch ( ex ) { Exception ex System . out . println ( ex. getMessage ( ) ) ; ex. JOptionPane . showMessageDialog ( this , “접속에 실패했습니다.” , “알림” , JOptionPane . ERROR_MESSAGE ) ; } } // 접속중이 이라면 소켓을 닫음 else if ( connect ) { try { socket. close ( ) ; System . out . println ( “서버와 연결이 끊어졌습니다.” ) ; ta. append ( “서버와 연결이 끊어졌습니다.

” ) ; setBackground ( Color . GREEN ) ; btn_ip. btn_ip. setText ( “접속” ) ; t_msg. setText ( “닉네임을 입력하세요.” ) ; connect = false ; // 접속중인지 아닌지를 판별할 카운터 } catch ( ioe ) { IOException ioe ioe. printStackTrace ( ) ; } } } } public static void main ( args [ ] ) { main String args /* // args[] 사용시 사용하는 코드 if(args.length != 1) { System.out.println( “Usage: java ClientExample4 “); return; } // 버튼 이벤트에서 사용하기 위해서 _args[] 값을 저장 arg_name = args[0]; */ new Client ( ) ; } // 내부 클래스 public class Sender { ; PrintWriter writer ; Socket socket ; String name // 소캣 생성 ( socket, ) { Sender Socket socket, String name this . socket = socket ; this . name = name ; try { = new PrintWriter ( writer socket. getOutputStream ( ) ) ; // 이부분을 지우면 처음 메시지 입력시 닉네임 입력 //writer.println(name); //writer.flush(); } catch ( Exception e ) { } } // 서버로 메시지를 넘김 public void sendMsg ( msg ) { sendMsg String msg if ( writer != null ) { try { writer. println ( msg ) ; writer. flush ( ) ; } catch ( Exception e ) { } } } } } 서버로 부터 메시지를 수신받는 쓰레드 package com.multichat ; import java.io.BufferedReader ; import java.io.InputStreamReader ; import java.net.Socket ; public class ReceiverThread extends Thread { ReceiverThread ; Socket socket public ReceiverThread ( socket ) { ReceiverThread Socket socket // TODO Auto-generated constructor stub this . socket = socket ; } public void run ( ) { try { // 서버에서 받는 부분 = new BufferedReader ( BufferedReader reader new InputStreamReader ( socket. getInputStream ( ) ) ) ; socket. while ( true ) { = reader. readLine ( ) ; String strreader. if ( str == null ) break ; System . out . println ( str ) ; str Client. ta . append ( str + ”

” ) ; /* 쓰레드시에 스크롤바가 자동으로 내려가질 않으므로 * 수평 스크롤바 위치를 따로 잡아줘야함 * append() 뒤에 붙여줘야함 */ Client. scroll . getVerticalScrollBar ( ) . setValue ( Client. scroll . getVerticalScrollBar ( ) . getMaximum ( ) ) ; } } catch ( Exception e ) { System . out . println ( e. getMessage ( ) ) ; e. } } } 프로그램을 실행하면서 넘기는 아규먼트를 사용하지 않을 경우 접속후 처음으로 넘어가는 메시지가 닉네임으로 사용됨 키보드 이벤트로 엔터키 입력시 메시지 전송 포커스 이벤트로 텍스트 필드 클릭시 텍스트 초기화 실행화면

인쇄

활용) GUI 채팅프로그램

package com.chat;

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Iterator;

import java.util.Vector;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import javafx.application.Application;

import javafx.application.Platform;

import javafx.geometry.Insets;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.control.TextArea;

import javafx.scene.layout.BorderPane;

import javafx.scene.text.Font;

import javafx.stage.Stage;

public class Main extends Application {

/*

* 여러 개의 Thread를 효율적으로 관리하는 대표적인 라이브러리 -> ThreadPool로 처리하게 되면 Thread숫자를 제한하기 떄문에

* 서버폭증에 대비할 수 있다.

*/

public static ExecutorService threadPool;

/* 접속한 클라이언트들을 관리한다 -> 일종의 배열 */

public static Vector < client > clients = new Vector < client > ();

ServerSocket serverSocket;

/* 서버를 구동시켜서 클라이언트의 연결을 기다리는 메소드 */

public void startServer( String IP, int port) {

try {

serverSocket = new ServerSocket();

/* 특정 클라이언트의 접속을 기다린다 */

serverSocket.bind( new InetSocketAddress(IP, port));

} catch (Exception e) { // 오류 발생

if ( ! serverSocket.isClosed()) { // serverSocket이 닫혀 있는 상황이 아니라면

stopServer();

}

return ;

}

// 클라이언트가 접속할때 까지 기다린다.

Runnable thread = new Runnable() {

@Override

public void run() {

while ( true ) {

try {

Socket socket = serverSocket.accept(); // 클라이언트의 접속을 기다린다.

clients. add ( new client(socket));

System . out . println ( “[클라이언트 접속]” + socket.getRemoteSocketAddress() + “:”

+ Thread.currentThread().getName());

} catch (Exception e) {

if ( ! serverSocket.isClosed()) {

stopServer();

}

break ;

}

}

}

};

/* threadpool을 초기화 한 다음, 첫 번째 thread를 넣어준다. */

threadPool = Executors.newCachedThreadPool();

threadPool.submit(thread);

} // startServer()

/* 서버의 동작을 중지시키는 메소드 */

public void stopServer() {

try {

// 현재 작동 중인 모든 소켓 닫기

/* Iterator통해서 모든 클라이언트에 개별적으로 접근할 수 있도록 할 수 있다 */

Iterator < client > iterator = clients.iterator();

while (iterator.hasNext()) {

client client = iterator.next();

client.socket.close();

iterator.remove();

}

// serversocket 객체 닫기

if (serverSocket ! = null & & ! serverSocket.isClosed()) {

serverSocket.close();

}

// threadPool 종료하기

if (threadPool ! = null & & threadPool.isShutdown()) {

threadPool.isShutdown();

}

} catch (Exception e) {

e.printStackTrace();

}

} // stopServer()

/* 화면설정 */

@Override

public void start(Stage primaryStage){

BorderPane root = new BorderPane();

root.setPadding( new Insets( 5 ));

TextArea textArea = new TextArea();

textArea.setEditable( false );

textArea.setFont( new Font( “나눔고딕” , 15 ));

root.setCenter(textArea);

Button toggleButton = new Button( “시작하기” );

toggleButton.setMaxWidth(Double.MAX_VALUE);

BorderPane.setMargin(toggleButton, new Insets( 1 , 0 , 0 , 0 ));

root.setBottom(toggleButton);

String IP = “127.0.0.1” ;

int port = 2980 ;

toggleButton.setOnAction(event – > {

if (toggleButton.getText(). equals ( “시작하기” )) {

startServer(IP, port);

Platform.runLater(() – > {

String message = String . format ( “[서버 시작]

” ,IP,port);

textArea.appendText(message);

toggleButton.setText( “종료하기” );

});

} else {

stopServer();

Platform.runLater(() – > {

String message = String . format ( “[서버 종료]

” ,IP,port);

textArea.appendText(message);

toggleButton.setText( “시작하기” );

});

}

});

Scene scene = new Scene(root, 400 , 400 );

primaryStage.setTitle( “Chat Server” );

primaryStage.setOnCloseRequest(event – > stopServer());

primaryStage.setScene(scene);

primaryStage.show();

} // start()

public static void main( String [] args) {

launch(args);

} // main()

}

GUI 채팅 프로그램

GUI 채팅 프로그램

GUI 채팅 프로그램.docx 2.GUIChat 완성.zip MultiChatServer.java MultiChatClient.java ClientFrame.java

실행화면(당근 MultiChatServer.java먼저 실행 -> MultiChatClient.java 실행)

– 채팅상에서 나의 ID 입력

-누군가 로그인하면 상대방의 IP와 ID를 뿌려준다. -> 채팅을 즐긴다.

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.IOException ;

import java.net.Socket;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

class Id extends JFrame implements ActionListener{

static JTextField tf=new JTextField(8);

JButton btn = new JButton(” 입력 “);

WriteThread wt;

ClientFrame cf;

public Id(){}

public Id(WriteThread wt, ClientFrame cf) {

super(” 아이디 “);

this.wt = wt;

this.cf = cf;

setLayout(new FlowLayout());

add(new JLabel(” 아이디 “));

add(tf);

add(btn);

btn.addActionListener(this);

setBounds(300, 300, 250, 100);

setVisible(true);

}

public void actionPerformed(ActionEvent e) {

wt.sendMsg();

cf.isFirst = false;

cf.setVisible(true);

this.dispose();

}

static public String getId(){

return tf.getText();

}

}

public class ClientFrame extends JFrame implements ActionListener{

JTextArea txtA = new JTextArea();

JTextField txtF = new JTextField(15);

JButton btnTransfer = new JButton(” 전송 “);

JButton btnExit = new JButton(” 닫기 “);

boolean isFirst=true;

JPanel p1 = new JPanel();

Socket socket;

WriteThread wt;

public ClientFrame(Socket socket) {

super(” 채팅이나 해볼까 “);

this.socket = socket;

wt = new WriteThread(this);

new Id(wt, this);

add(“Center”, txtA);

p1.add(txtF);

p1.add(btnTransfer);

p1.add(btnExit);

add(“South”, p1);

// 메세지를 전송하는 클래스 생성 .

btnTransfer.addActionListener(this);

btnExit.addActionListener(this);

setDefaultCloseOperation(EXIT_ON_CLOSE);

setBounds(300, 300, 350, 300);

setVisible(false);

}

public void actionPerformed(ActionEvent e){

String id = Id.getId();

if(e.getSource()==btnTransfer){// 전송버튼 눌렀을 경우

// 메세지 입력없이 전송버튼만 눌렀을 경우

if(txtF.getText().equals(“”)){

return;

}

txtA.append(“[“+id+”] “+ txtF.getText()+”

“);

wt.sendMsg();

txtF.setText(“”);

}else{

this.dispose();

}

}

}

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.Socket;

// 키보드로 전송문자열 입력받아 서버로 전송하는 스레드

class WriteThread{

Socket socket;

ClientFrame cf;

String str;

String id;

public WriteThread(ClientFrame cf) {

this.cf = cf;

this.socket= cf.socket;

}

public void sendMsg() {

// 키보드로부터 읽어오기 위한 스트림객체 생성

BufferedReader br=

new BufferedReader(new InputStreamReader(System.in));

PrintWriter pw=null;

try{

// 서버로 문자열 전송하기 위한 스트림객체 생성

pw=new PrintWriter(socket.getOutputStream(),true);

// 첫번째 데이터는 id 이다 . 상대방에게 id 와 함께 내 IP 를 전송한다 .

if(cf.isFirst==true){

InetAddress iaddr=socket.getLocalAddress();

String ip = iaddr.getHostAddress();

getId();

System.out.println(“ip:”+ip+”id:”+id);

str = “[“+id+”] 님 로그인 (“+ip+”)”;

}else{

str= “[“+id+”] “+cf.txtF.getText();

}

// 입력받은 문자열 서버로 보내기

pw.println(str);

}catch(IOException ie){

System.out.println(ie.getMessage());

}finally{

try{

if(br!=null) br.close();

//if( pw !=null) pw.close();

//if(socket!=null) socket.close();

}catch(IOException ie){

System.out.println(ie.getMessage());

}

}

}

public void getId(){

id = Id.getId();

}

}

// 서버가 보내온 문자열을 전송받는 스레드

class ReadThread extends Thread{

Socket socket;

ClientFrame cf;

public ReadThread(Socket socket, ClientFrame cf) {

this.cf = cf;

this.socket=socket;

}

public void run() {

BufferedReader br=null;

try{

// 서버로부터 전송된 문자열 읽어오기 위한 스트림객체 생성

br=new BufferedReader(

new InputStreamReader(socket.getInputStream()));

while(true){

// 소켓으로부터 문자열 읽어옴

String str=br.readLine();

if(str==null){

System.out.println(” 접속이 끊겼음 “);

break;

}

// 전송받은 문자열 화면에 출력

//System.out.println(“[server] ” + str );

cf.txtA.append(str+”

“);

}

}catch(IOException ie){

System.out.println(ie.getMessage());

}finally{

try{

if(br!=null) br.close();

if(socket!=null) socket.close();

}catch(IOException ie){}

}

}

}

public class MultiChatClient {

public static void main(String[] args) {

Socket socket=null;

ClientFrame cf;

try{

socket=new Socket(“127.0.0.1″,3000);

System.out.println(” 연결성공 !”);

cf = new ClientFrame(socket);

new ReadThread(socket, cf).start();

}catch(IOException ie){

System.out.println(ie.getMessage());

}

}

}

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Vector;

// 클라이언트로 부터 전송된 문자열을 받아서 다른 클라이언트에게 문자열을

// 보내주는 스레드

class EchoThread extends Thread{

Socket socket;

Vector vec;

public EchoThread(Socket socket, Vector vec){

this.socket = socket;

this.vec = vec;

}

public void run(){

BufferedReader br = null;

try{

br = new BufferedReader(

new InputStreamReader(socket.getInputStream()));

String str =null;

while(true){

// 클라이언트로 부터 문자열 받기

str=br.readLine();

// 상대가 접속을 끊으면 break;

if(str==null){

// 벡터에서 없애기

vec.remove(socket);

break;

}

// 연결된 소켓들을 통해서 다른 클라이언트에게 문자열 보내주기

sendMsg(str);

}

}catch(IOException ie){

System.out.println(ie.getMessage());

}finally{

try{

if(br != null) br.close();

if(socket != null) socket.close();

}catch(IOException ie){

System.out.println(ie.getMessage());

}

}

}

// 전송받은 문자열 다른 클라이언트들에게 보내주는 메서드

public void sendMsg(String str){

try{

for(Socket socket:vec){

// for 를 돌되 현재의 socket 이 데이터를 보낸 클라이언트인 경우를 제외하고

// 나머지 socket 들에게만 데이터를 보낸다 .

if(socket != this.socket){

PrintWriter pw =

new PrintWriter(socket.getOutputStream(), true);

pw.println(str);

pw.flush();

// 단 , 여기서 얻어온 소켓들은 남의것들이기 때문에 여기서 닫으면 안된다 .

}

}

}catch(IOException ie){

System.out.println(ie.getMessage());

}

}

}

public class MultiChatServer {

public static void main(String[] args) {

ServerSocket server = null;

Socket socket =null;

// 클라이언트와 연결된 소켓들을 배열처럼 저장할 벡터객체 생성

Vector vec = new Vector();

try{

server= new ServerSocket(3000);

while(true){

System.out.println(” 접속대기중 ..”);

socket = server.accept();

// 클라이언트와 연결된 소켓을 벡터에 담기

vec.add(socket);

// 스레드 구동

new EchoThread(socket, vec).start();

}

}catch(IOException ie){

System.out.println(ie.getMessage());

}

}

}

[Java] 멀티채팅 프로그램 (GUI)

자바 멀티채팅 프로그램을 통하여 네트워크 소켓 통신의 기본을 알아봅시다.

한 서버에 여러 클라이언트 접속이 가능합니다.

개발 환경은 eclipse이니 참고바랍니다.

실행화면

1. API

먼저 소켓 프로그래밍에서 사용되는 API들을 정리해보겠습니다.

1) ServerSocket

서버 역할을 하는 소켓 객체입니다.

클라이언트의 연결 요청을 기다리면서 연결 요청에 대한 수락을 담당합니다.

2) Socket

클라이언트와 서버 간의 통신을 직접 담당합니다.

3) DataInputStream과 DataOutputStream

자바의 기본 자료형 데이터를 바이트 스트림으로 입출력하는 기능을 제공하는 ByteStream 클래스입니다.

2. 자바 채팅 처리

3. 자바 채팅의 내용

4. 1:1 채팅

5. 다중채팅(소스코드)

서버는 클라이언트가 접속을 할 때마다 새로운 리시버클래스-쓰레드를 하나씩 start 시킨다.

클라이언트의 정보를 synchronizedMap에 저장해놓는다.

패키지를 client와 server로 나누었습니다.

1) ServerBackground.java

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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 package kr.co.swk.multichat.server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class ServerBackground { // 지금까지 한일. GUi연동시키면서 서버Gui에 메시지띄움. // 다음 이슈. Gui 상에서 일단 1:1 채팅을 하고 싶다. private ServerSocket serverSocket; private Socket socket; private ServerGui gui; private String msg; /** XXX 03. 세번째 중요한것. 사용자들의 정보를 저장하는 맵입니다. */ private Map < String , DataOutputStream > clientsMap = new HashMap < String , DataOutputStream > (); public final void setGui(ServerGui gui) { this .gui = gui; } public void setting() throws IOException { Collections.synchronizedMap(clientsMap); // 이걸 교통정리 해줍니다^^ serverSocket = new ServerSocket( 7777 ); while ( true ) { /** XXX 01. 첫번째. 서버가 할일 분담. 계속 접속받는것. */ System . out . println ( “서버 대기중…” ); = serverSocket.accept(); // 먼저 서버가 할일은 계속 반복해서 사용자를 받는다. socket System . out . println (socket.getInetAddress() + “에서 접속했습니다.” ); // 여기서 새로운 사용자 쓰레드 클래스 생성해서 소켓정보를 넣어줘야겠죠?! Receiver receiver = new Receiver(socket); receiver.start(); } } public static void main( String [] args) throws IOException { ServerBackground serverBackground = new ServerBackground(); serverBackground.setting(); } // 맵의내용(클라이언트) 저장과 삭제 public void addClient( String nick, DataOutputStream out ) throws IOException { sendMessage(nick + “님이 접속하셨습니다.” ); clientsMap.put(nick, out ); ); } public void removeClient( String nick) { sendMessage(nick + “님이 나가셨습니다.” ); clientsMap.remove(nick); } // 메시지 내용 전파 public void sendMessage( String msg) { < String > it = clientsMap.keySet().iterator(); Iteratorit String key = “” ; while (it.hasNext()) { = it.next(); key try { clientsMap.get(key).writeUTF(msg); } catch (IOException e) { e.printStackTrace(); } } } // —————————————————————————– class Receiver extends Thread { private DataInputStream in ; private DataOutputStream out ; private String nick; /** XXX 2. 리시버가 한일은 자기 혼자서 네트워크 처리 계속..듣기.. 처리해주는 것. */ public Receiver(Socket socket) throws IOException { out = new DataOutputStream(socket.getOutputStream()); in = new DataInputStream(socket.getInputStream()); nick = in .readUTF(); addClient(nick, out ); } public void run() { try { // 계속 듣기만!! while ( in ! = null ) { msg = in .readUTF(); sendMessage(msg); gui.appendMsg(msg); } } catch (IOException e) { // 사용접속종료시 여기서 에러 발생. 그럼나간거에요.. 여기서 리무브 클라이언트 처리 해줍니다. removeClient(nick); } } } } http://colorscripter.com/info#e ” target=”_blank” style=”color:#4f4f4ftext-decoration:none”>Colored by Color Scripter http://colorscripter.com/info#e” target=”_blank” style=”text-decoration:none;color:white”> cs

2) ServerGui.java

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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 package kr.co.swk.multichat.server; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event. ActionListener ; import java.io.IOException; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class ServerGui extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private JTextArea jta = new JTextArea( 40 , 25 ); private JTextField jtf = new JTextField( 25 ); private ServerBackground server = new ServerBackground(); public ServerGui() throws IOException { add (jta, (jta, BorderLayout.CENTER); add (jtf, (jtf, BorderLayout.SOUTH); jtf.addActionListener( this ); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible( true ); setBounds( 200 , 100 , 400 , 600 ); setTitle( “서버부분” ); server.setGui( this ); ); server.setting(); } public static void main( String [] args) throws IOException { new ServerGui(); } @Override public void actionPerformed(ActionEvent e) { String msg = “서버 : ” + jtf.getText() + ”

” ; System . out . print (msg); server.sendMessage(msg); jtf.setText( “” ); } public void appendMsg( String msg) { jta.append(msg); } } http://colorscripter.com/info#e ” target=”_blank” style=”color:#4f4f4ftext-decoration:none”>Colored by Color Scripter http://colorscripter.com/info#e” target=”_blank” style=”text-decoration:none;color:white”> cs

3) ClientBackground.java

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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package kr.co.swk.multichat.client; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; public class ClientBackground { private Socket socket; private DataInputStream in ; private DataOutputStream out ; private ClientGui gui; private String msg; private String nickName; public final void setGui(ClientGui gui) { this .gui = gui; } public void connet() { try { socket = new Socket( “127.0.0.1” , 7777 ); System . out . println ( “서버 연결됨.” ); out = new DataOutputStream(socket.getOutputStream()); in = new DataInputStream(socket.getInputStream()); // 접속하자마자 닉네임 전송하면. 서버가 이걸 닉네임으로 인식을 하고서 맵에 집어넣겠지요? out .writeUTF(nickName); System . out . println ( “클라이언트 : 메시지 전송완료” ); while ( in ! = null ) { msg = in .readUTF(); gui.appendMsg(msg); } } catch (IOException e) { e.printStackTrace(); } } public static void main( String [] args) { ClientBackground clientBackground = new ClientBackground(); clientBackground.connet(); } public void sendMessage( String msg2) { try { out .writeUTF(msg2); } catch (IOException e) { e.printStackTrace(); } } public void setNickname( String nickName) { this .nickName = nickName; } } http://colorscripter.com/info#e ” target=”_blank” style=”color:#4f4f4ftext-decoration:none”>Colored by Color Scripter http://colorscripter.com/info#e” target=”_blank” style=”text-decoration:none;color:white”> cs

4) ClientGui.java

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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package kr.co.swk.multichat.client; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event. ActionListener ; import java.util.ArrayList; import java.util. Scanner ; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class ClientGui extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private JTextArea jta = new JTextArea( 40 , 25 ); private JTextField jtf = new JTextField( 25 ); private ClientBackground client = new ClientBackground(); private static String nickName; public ClientGui() { add (jta, (jta, BorderLayout.CENTER); add (jtf, (jtf, BorderLayout.SOUTH); jtf.addActionListener( this ); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible( true ); setBounds( 800 , 100 , 400 , 600 ); setTitle( “클라이언트” ); client.setGui( this ); ); client.setNickname(nickName); client.connet(); } public static void main( String [] args) { Scanner scanner = new Scanner ( System . in ); System . out . print ( “당신의 닉네임부터 설정하세요 : ” ); nickName = scanner.nextLine(); scanner.close(); new ClientGui(); } @Override // 말치면 보내는 부분 public void actionPerformed(ActionEvent e) { String msg = nickName + “:” + jtf.getText() + ”

” ; client.sendMessage(msg); jtf.setText( “” ); } public void appendMsg( String msg) { jta.append(msg); } } http://colorscripter.com/info#e ” target=”_blank” style=”color:#4f4f4ftext-decoration:none”>Colored by Color Scripter http://colorscripter.com/info#e” target=”_blank” style=”text-decoration:none;color:white”> cs

6. 실행결과

ServerGui 실행 및 접속성공

ClientGui 실행

Client 접속 성공

Client에서 송신된 채팅화면

Server에서

송신된 채팅화면

Client와 Server가 내용을 주고받는 화면

다수의 Client가 접속

멀티채팅으로 대화를 주고 받는 모습

Gui 멀티 채팅 프로그램 예제

안녕하세요 이번 글에서는 GUI 멀티 채팅 프로그램 예제에 대해서 알아보도록 하겠습니다.

2개의 java파일로 구성되어 있습니다.

ClientFrame

import java.awt.BorderLayout; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class ClientFrame extends JFrame{ //자유롭게 사용하려면 여기에 필드로 선언해야 한다 //채팅창 프레임을 구성하는 컴포넌트 //textarea 한줄 이상의 문자 입력 보여주기 private JTextArea textarea; private JTextField sendMsgTf; private JScrollPane scrollPane; //서버와의 통신을 위한 소켓 private Socket socket; private BufferedWriter bw; public ClientFrame() { textarea = new JTextArea(); sendMsgTf = new JTextField(); textarea.setEditable(false);//쓰기를 금지함 edit 할 수 없는 상태 scrollPane = new JScrollPane(textarea); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); //As needed 즉 필요에의해서 내용이 많아지면 스크롤 바가 생긴다 scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); //가로 스크롤은 안만든다 setSize(500, 700); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); setTitle(“chatting”); sendMsgTf.addKeyListener(new MsgSendListener()); //텍스트 필드에 키 리스너를 등록 //텍스트 필드를 지켜보고 있다가 특정 상황이 오면 //이벤트 리스너에 정의된 내용 실행 add(scrollPane,BorderLayout.CENTER);//프레임에 붙이기 //add(textarea,BorderLayout.CENTER);//프레임에 붙이기 add(sendMsgTf,BorderLayout.SOUTH);//프레임에 붙이기 } //소켓 설정을 위한 세터 //이제 프레임도 소켓의 정보를 가지게 되었다 public void setSocket(Socket socket) { this.socket = socket; try { OutputStream out = socket.getOutputStream(); bw = new BufferedWriter(new OutputStreamWriter(out)); } catch (Exception e) { e.printStackTrace(); } } //내부 클래스로 이벤트 리스너 만들기 class MsgSendListener implements KeyListener { @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) {//키가 눌렸다가 떼어졌을때 //엔터키가 눌렸다가 떼어지면 텍스트 필드에 있는 내용이 텍스트 에어리어에 나타나게 if (e.getKeyCode()==KeyEvent.VK_ENTER) {//각각의 키들이 가지고 있는 코드 값이 나타난다 //VK_ENTER = 상수 , 엔터 키에 대한 키값을 의미한다 String msg = sendMsgTf.getText(); System.out.println(msg); textarea.append(“[ 나 ]: “+msg+”

“); sendMsgTf.setText(“”); try { bw.write(msg+”

“); bw.flush(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }//한문장이 끝났다는 것을 알리기 위해서 bufferedWriter에 ”

“을 붙인다 } } } //내부 클래스로 수신 스레드 작성 class TcpClientReceiveThread implements Runnable { private Socket socket; public TcpClientReceiveThread(Socket socket) { this.socket = socket; } @Override public void run() { //서버로부터 오는 메세지를 읽어서 //텍스트 에어리어에 추가하기 try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); while (true) { String msg = br.readLine();//메세지 한줄 읽어오기 textarea.append(“[상대방]” + msg + ”

“); } } catch (Exception e) { textarea.append(“연결이 종료되었습니다.”); //System.out.println(“연결이 종료되었습니다.”); } finally { try { if (socket!=null&&!socket.isClosed()) { socket.close();//다 쓴 소켓 닫기 } } catch (Exception e2) { } } } } public static void main(String[] args) { try { //서버 아이피 , 포트번호 -> 소켓 생성 -> 연결 요청 Socket socket = new Socket(“10.10.10.134”, 5000); //소켓 객체 생성 ClientFrame cf = new ClientFrame(); cf.setSocket(socket);//메인에서 프레임 생성 TcpClientReceiveThread th1 = cf.new TcpClientReceiveThread(socket); //TcpClientReceiveThread가 내부 클래스로 선언되어 있기 때문에 //cf로 접근해서 socket을 전달한다 new Thread(th1).start(); } catch (Exception e) { e.printStackTrace(); } } }

TcpChatServer

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; class TcpChatServerManager { private List socketList; // 생성자 : TCSM 객체를 생성하면 소켓리스트 하나 만듬 public TcpChatServerManager() { socketList = new ArrayList(); } // 소켓 추가 메소드 public void addSocket(Socket socket) { this.socketList.add(socket); new Thread(new ReceiverThread(socket)).start(); } // 멀티클라이언트와 연결을 동시에 유지하기 위한 스레드 구성 // 각각의 소켓정보를 가지고 있어야함. class ReceiverThread implements Runnable { private Socket socket; // 소켓 public ReceiverThread(Socket socket) { this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub try { // 클라이언트가 보낸 메시지 읽기 위한 작업 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); while (true) { String msg = br.readLine(); // 클라이언트가 보낸 메시지 읽기 System.out.println(msg); // 받은 메시지를 메시지 보낸 클라이언트 제외하고 // 모든 클라이언트한테 보내기 Socket tmpSocket = null; try { for (int i = 0; i < socketList.size(); i++) { // 소켓리스트를 순회하면서 tmpSocket = socketList.get(i); // socketList.get(0) -> 소켓 객체 if (socket.equals(tmpSocket)) continue; // 메시지를 보낸 클라이언트라면 반복을 한번 건너뛰기 // 서버가 받은 메시지를 클라이언트에 송신하기 BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(tmpSocket.getOutputStream())); bw.write(msg + ”

“); bw.flush(); } }catch(Exception e) { System.out.println(tmpSocket.getRemoteSocketAddress() + “연결 종료”); socketList.remove(tmpSocket); //연결을 끊은 클라이언트를 위한 소켓 제거 System.out.println(“===============현재참여자=================”); for(Socket s : socketList) { System.out.println(s.getRemoteSocketAddress()); } System.out.println(“==========================================”); } } } catch (IOException e) { // TODO Auto-generated catch block // e.printStackTrace(); } finally { if(socket != null) { System.out.println(socket.getRemoteSocketAddress() + “연결 종료”); socketList.remove(socket); //연결을 끊은 클라이언트를 위한 소켓 제거 System.out.println(“===============현재참여자=================”); for(Socket s : socketList) { System.out.println(s.getRemoteSocketAddress()); } System.out.println(“==========================================”); } } } } } public class TcpChatServer { public static void main(String[] args) { // 서버소켓 TcpChatServerManager tcsm = new TcpChatServerManager(); try { ServerSocket serverSocket = new ServerSocket(5000); while (true) { Socket socket = serverSocket.accept(); // 클라이언트 연결요청 대기(연결요청 오기전엔 멈춤) // -> 연결요청오면? 소켓을 반환 // 멀티 클라이언트 -> 소켓이 여러개 -> 리스트로 관리 // -> 서버 매니져 클래스로 관리 System.out.println(socket.getRemoteSocketAddress() + ” : 연결”); tcsm.addSocket(socket); // 얻은 소켓 서버매니져의 소켓목록에 추가 } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

실행 화면

[ JAVA/ GUI ] 네트워킹2/ 채팅창만들기3/ 통신/ 자바네트워킹/ 자바채팅창만들기/ 자바통신/ 자바GUI네트워킹/ 자바GUI채팅창만들기/ 자바GUI통신/ 자바GUI/ javaGUI/ JavaGUI/ JAVA/ java/ 자바/ 이클립스/ 자..

GUI창에서 네트워킹(통신)을 이용 하여 조금더 개선된 채팅창 을 만들어 보겠다.

먼저, 네트워크에 대해 조금 보겠다.

ㅁ. Internet ?? internet??

; Internet= web browser // internet = inter networking

ㅁ. 네트워크는 쌍방작동되야함. 만약 그렇지않으면 싱크 싱크아크 아크를 확인해야한다.

ㅁ. 한 PC에서 개발해서 디버깅 할때에는 포트번호를 다르게주고,

실질적으로 사용할때는 같은 번호로 할당하고 아이피주소를 상대방주소로 바꾼다.

ㅁ. IP 기초

형태 : 0000.0000.0000.0000

1. 0~127 까지가 앞이 0번임 -> 0xxx.255.255.255 -> A클래스 (우리나라에 없다)

// 127.0.0.0 => loopback IP 랜카드까지 나가지 않고 내부적으로 작동. 따라서 잠시 확인할때 사용가능

// C:\Windows\System32\drivers\etc

2. 127~191 1로시작 -> 1xxx.xxxx.255.255 -> B클래스

( 돈주고 사오는것임. 우리나라에 몇군대없다. 전자통신연구원, 서울대,연세대, 카이스트, 충남대 등 )

// 예, 172.16.X.X B클래스 사설IP

3. 192~223 세번째 자리까지 할당해줌. 예, 200.100. 1~10 .255-> C클래스

// 공유기를 써서 확장시킴. 10.x.x.x 는 사설아이피. 라우터밖으로 나오면 죽기때문에 내부적으로 사용

// ex, 192.168.x.x 는 사설IP

00. 자세한 설명은 각 주석 참고.

01. 포트값을 다음과 같이 입력하고 실행시켜서 나온 GUI창을 a 라고 생각하자.

02. 통신하기위해 포트값을 서로 바꿔서 실행시킨다음 내이름과 님이름을 수기로 바꾸고 그것을 b 라고 생각하자.

03. a 창에서 먼저 hi 라고 적어보자

04. 내창과 님창에 둘다 뜨는 것을 확인할 수 있다. b 창에서도 똑같이 시도해본다.

05. 정상작동함을 볼 수 있다.

※. 코드

import java.awt.BorderLayout;

import java.awt.FlowLayout;

import java.awt.Font;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;

class Chatting {

/* 화면구성을 위한 변수들 */

private JPanel displayPanel;

private JPanel inputPanel;

private JPanel setupPanel;

private JTextArea display;

private JTextField input;

/* setupPanel의 components*/

private JTextField myName;

private JTextField yourName;

private JTextField yourIP;

/* 통신을 위한 변수들 */

private DatagramSocket socket; // User Datagram Protocol

// <-> ServerSocket serverSocket ; TCP 통신

private DatagramPacket packet; // 수신할 데이터 패킷을 위함

private InetAddress address; // 상대방주소

private int myPort = 10002;

private int yourPort = 10001;

public Chatting() {

new MyFrame();

/* socket 설정 */

try {

address = InetAddress.getByName( yourIP.getText() );

// ; loopback address ; Testing in local // 상대방의 IP

socket = new DatagramSocket(myPort); // 수신할 포트설정

} catch (Exception e) {

display.append(“ERROR : ” + e.getMessage() + ”

“);

}

}// Chatting Constructor

public void receive()

{

while(true) // 무한정 돌면서 수신대기

{

try { // 수신하다보면 에러가 생길 수 있기 때문에 예외처리로

byte[] rcvBuffer = new byte[1024]; // 2승수로 바이트단위 잡아줘야함.

packet = new DatagramPacket(rcvBuffer, rcvBuffer.length);

socket.receive(packet); // 소켓에서 수신하면

display.append(yourName.getText() + “<< " + new String(rcvBuffer) + " "); // ; 수신데이터는 byte[] 이므로 String으로 변환 } catch (Exception e) { display.append("ERROR (receive) : " + e.getMessage()); } }// while }// receive Method class MyFrame extends JFrame implements ActionListener{ public MyFrame() { this.setTitle("My GUI"); this.setSize(500, 400); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); /* displayPanel 처리 */ displayPanel = new JPanel(); displayPanel.setLayout(new FlowLayout()); display = new JTextArea(11, 30); Font displayFont = new Font("Serif", Font.BOLD, 20); display.setFont(displayFont); display.setEditable(false); // textarea를 스크롤이 되도록 변경 JScrollPane scroll = new JScrollPane(display); displayPanel.add(scroll); /* input 처리 */ inputPanel = new JPanel(); inputPanel.setLayout(new FlowLayout()); input = new JTextField(30); Font inputFont = new Font("Serif", Font.BOLD, 20); input.setFont(inputFont); input.addActionListener(this); inputPanel.add(input); /* setupPanel 처리 */ setupPanel = new JPanel(); setupPanel.setLayout( new FlowLayout() ); setupPanel.add( new JLabel("MyName") ); myName = new JTextField(5); //5 칸 setupPanel.add(myName); myName.setText("홍길동"); setupPanel.add( new JLabel("YourName") ); yourName = new JTextField(5); //5 칸 setupPanel.add(yourName); yourName.setText("이순신"); setupPanel.add( new JLabel("YourIP") ); yourIP = new JTextField(6); //6 칸 setupPanel.add(yourIP); yourIP.setText("127.0.0.1"); /* Frame에 두개의 panel을 붙이기 */ this.setLayout(new BorderLayout()); this.add(setupPanel, BorderLayout.NORTH); this.add(displayPanel, BorderLayout.CENTER); this.add(inputPanel, BorderLayout.SOUTH); this.setVisible(true); }// myFrame Method @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == input) { display.append(myName.getText() + " >> “+ input.getText() + ”

“); // 나가는 데이터를 나타내기 위해 >>

/* network로 데이터 전송 */

// 데이터 전송시 바이트 단위로 전송

//

byte [] sendBuffer = input.getText().getBytes(); // input에서 getText를 바이트 단위로 변환해서 배열

// 전송할 데이터 패킷을 만듬

DatagramPacket sendPacket = new DatagramPacket(sendBuffer,sendBuffer.length, address, yourPort);

// ; sendBuffer를 보낼거고, sendBuffer길이만큼 보내줄거고, 상대방주소에, 상대방포트 로 보내줄거임.

try {

socket.send(sendPacket); // send 시 에러가 생길수 있기 때문에 예외처리해줘야 함.

} catch (Exception e2) {

display.append(“ERROR (send) : ” + e2.getMessage() + ”

” );

}// tryCatch

//input.selectAll();

input.setText(“”);

}// if

}// actionPerformed

}// MyFrame Class

}// Chatting Class

public class Test {

public static void main(String[] args) {

Chatting chat = new Chatting(); // MyFrame Class 가 Chatting 클래스 안으로 들어갔기 때문에

chat.receive();

}// main

}// Main Class

키워드에 대한 정보 자바 gui 메신저

다음은 Bing에서 자바 gui 메신저 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1)

  • JavaFX
  • 자바FX
  • 채팅프로그램
  • 자바GUI
  • JavaGUI
  • 자바GUI채팅프로그램

JavaFX #GUI #채팅 #프로그램 #개발하기 #① #프로젝트 #개요 #(JavaFX #Multi-Chatting #Project ##1)


YouTube에서 자바 gui 메신저 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 JavaFX GUI 채팅 프로그램 개발하기 ① 프로젝트 개요 (JavaFX Multi-Chatting Project #1) | 자바 gui 메신저, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

Leave a Comment