본문 바로가기

UDP 를 이용한 다중 채팅 프로그램 만들기



최종적으로 만들 채팅 프로그램은


와 같은 구조를 가집니다.



우선 UDP를 이용하여 만들기 위해서는 TCP와 UDP를 알아야합니다.



TCP(Transmission Control Protocol)

연결형 서비스를 지원하는 전송계층 프로토콜

인터넷 환경에서 기본으로 사용한다.

호스트간 신뢰성 있는 데이터 전달과 흐름제어 및 혼잡제어 등을 제공하는 전송계층



UDP(User Datagram Protocol)

비연결형 서비스를 지원하는 전송계층 프로토콜

사용자 데이터그램형 프로토콜

인터넷상에서 서로 정보를 주고받을 때 정보를 보낸다는 신호나 받는다는 신호 절차를 거치지 않고,

보내는 쪽에서 일방적으로 데이터를 전달하는 통신 프로토콜

보내는 쪽에서는 받는 쪽이 데이터를 받았는지 받지 않았는지 확인할 수 없고, 또 확인할 필요도 없도록 만들어진 프로토콜




이사에 비유하자면 

TCP포장이사, UDP용달이사라고 생각하시면 됩니다.

포장이사는 비싼가격으로 이사를 하게 되지만 높은 신뢰성을 가지고 있습니다.

또한 처음부터 끝까지 흐름을 업체에서 제어합니다.


TCP는 데이터 흐름 제어, 연결의 설정과 해제 등의 특징이 있습니다.


반대로 비포장이사라면 상대적으로 덜 비싸고 신뢰성이 떨어지겠죠

하지만 속도는 처음부터 포장하는 포장이사보다는 빠르겠죠?


UDP는 TCP의 handshaking 같은 연결 설정도 없습니다.


따라서 UDP는 TCP와 달리 데이터의 수신에 대한 책임을 지지 않습니다.


Java 관련 클래스로는 TCP 는 Socket, ServerSocket 이 있고

UDP 는 DatagramSocket, DatagramPacket, MuliticastSocket 이 있습니다.



그 중 MulticastSocket 의 설명으로는 IP 멀티캐스트 패킷의 송수신에 유용하다


추가로 인터넷에 있는 다른 멀티캐스트 호스트의 그룹들을 결합하는 

기능을 갖춘 DatagramSocket 이다

멀티캐스트 그룹은 클래스 D IP 주소(224.0.0.1 ~ 239.255.255.255) 및 표준 UDP 포트 번호로 지정된다


먼저 사용하려는 포트로 MulticastSocket 을 작성한 다음 

joinGroup(InetAddress, groupAddr) 메서드를 호출하여 멀티캐스트 그룹을 결합한다.


메시지를 멀티 캐스트 그룹으로 전송할 때해당 호스트와 포트에 가입한 모든 수신자가 메시지를 수신한다.



라고 합니다......




이제는 뭐 대충 알겠으니 만들어 봅시다.


우선 만들 기능이 채팅뿐이니...

조금 더 고오급스러운 프로그램이 되도록 회원가입을 한번 만들어 볼까합니다.


거창하게 오라클DB를 사용하여 테이블을 만들어 줍니다.

구조는 아래와 같습니다.




또한 완성된 모습은 아래와 같습니다.




채팅 로그인과 회원가입 기능




채팅 기능과 별 쓰잘때기 없는 회원탈퇴기능




잘 보셨죠??


소스를 우선적으로 보면서 설명을 추가적으로 하겠습니다.




구조입니다.


먼저 보셔야 할것은 바로 Messenger.java !!!!!! 

하지만 귀찮으니 사용하는 유저의 마음으로 회원가입부터 보도록하겠습니다.


구조는 JFrame 을 쉽게 만들기위한 라이브러리를 사용합시다

이름이 기억이 안나........


Join.java

package com.lg.messenger;


import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;


import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JPasswordField;

import javax.swing.JTextField;

import javax.swing.border.EmptyBorder;


// 우선 JFrame을 이용하는 것을 볼 수 있습니다.

public class Join extends JFrame {


private JPanel contentPane; // 내용

private JTextField tf_JoinId; // 아이디

private JTextField tf_JoinName; // 이름

private JPasswordField pf_JoinPw; // 패스워드


/**

* Create the frame.

         * 프레임을 만들어줍니다.

         * 손까락만 까딱하면 만들어주는 프로그램이 있습니다.

         * 이클립스 마켓에 있는것 같아요오...

*/

public Join() {

setTitle("\uD68C\uC6D0\uAC00\uC785");

setBounds(100, 100, 300, 205); // 네 창사이즈 설정 입니다.

contentPane = new JPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

setContentPane(contentPane);

contentPane.setLayout(new BorderLayout(0, 0));


JPanel panel = new JPanel();

contentPane.add(panel, BorderLayout.CENTER);

panel.setLayout(null);


JLabel lblID = new JLabel(" I D :");

lblID.setBounds(39, 28, 27, 15);

panel.add(lblID);


tf_JoinId = new JTextField();

tf_JoinId.setBounds(96, 25, 116, 21);

panel.add(tf_JoinId);

tf_JoinId.setColumns(10);


JLabel lblNewLabel = new JLabel("PW :");

lblNewLabel.setBounds(39, 59, 26, 15);

panel.add(lblNewLabel);


JLabel lblNewLabel_1 = new JLabel("NAME :");

lblNewLabel_1.setBounds(39, 90, 45, 15);

panel.add(lblNewLabel_1);


tf_JoinName = new JTextField();

tf_JoinName.setBounds(96, 87, 116, 21);

panel.add(tf_JoinName);

tf_JoinName.setColumns(10);


// 여기 위에는 다 사진에 보이는 텍스트 필드를 만들어 준겁니다.



// 아래는 버튼을 만들어주고요


JButton btnJoinOk = new JButton("\uC644\uB8CC");

btnJoinOk.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int loginOk;

loginOk = UserDao.getInstance().insert(tf_JoinId.getText(), new String(pf_JoinPw.getPassword()),

tf_JoinName.getText());

if (loginOk != 0) {

JOptionPane.showMessageDialog(null, "회원가입성공");

dispose();

}else{

JOptionPane.showMessageDialog(null, "이미있는 아이디 입니다.");

}

}

});

btnJoinOk.setBounds(42, 118, 97, 23);

panel.add(btnJoinOk);


// UserDao 는 이따가 만들어 줄겁니다 걱정마세요!

// 섬세하게 뒤로가기 버튼도 만들어 줍니다.

JButton btnJoinBack = new JButton("\uCDE8\uC18C");

btnJoinBack.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

dispose();

}

});


btnJoinBack.setBounds(148, 118, 97, 23);

panel.add(btnJoinBack);


pf_JoinPw = new JPasswordField();

pf_JoinPw.setBounds(96, 56, 116, 21);

panel.add(pf_JoinPw);

}

}



회원가입을 했으니

이제는 로그인을 해야겠죠???


Login.java

package com.lg.messenger;


import java.awt.BorderLayout;

import java.awt.EventQueue;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;


import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JPasswordField;

import javax.swing.JTextField;


// 마찬가지로 JFrame을 이용하여 만들고 있습니다.

public class Login extends JFrame {

private JTextField tf_Id;

private JPasswordField pf_Pw;


public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {

public void run() {

try {

Login frame = new Login();

frame.setVisible(true);

} catch (Exception e) {

e.printStackTrace();

}

}

});

}


/**

* Create the frame.

*/


            

// 이걸 만들려고 하는 겁니다.


public Login() {

setTitle("\uCC44\uD305");

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 240, 160);


JPanel panel = new JPanel();

getContentPane().add(panel, BorderLayout.CENTER);

panel.setLayout(null);


JLabel lblNewLabel = new JLabel(" I D :");

lblNewLabel.setBounds(24, 29, 27, 15);

panel.add(lblNewLabel);


tf_Id = new JTextField();

tf_Id.setBounds(71, 26, 116, 21);

panel.add(tf_Id);

tf_Id.setColumns(10);


JLabel lblNewLabel_1 = new JLabel("PW :");

lblNewLabel_1.setBounds(25, 60, 26, 15);

panel.add(lblNewLabel_1);


// 로그인 기능 DB와 연결하여 성공여부를 알아옵니다.

JButton login = new JButton("\uB85C\uADF8\uC778");

login.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

try {

boolean loginOk;

loginOk = UserDao.getInstance().loginCheck(tf_Id.getText(), new String(pf_Pw.getPassword()));

if (loginOk) {

UserDao.getInstance().loginSuccess(tf_Id.getText());

dispose();

} else {

JOptionPane.showMessageDialog(null, "로그인실패");

}

} catch (Exception e1) {

e1.printStackTrace();

}

}

});

login.setBounds(12, 88, 96, 23);

panel.add(login);


JButton join = new JButton("\uD68C\uC6D0\uAC00\uC785");

join.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

Join frame = new Join();

frame.setVisible(true);

}

});

join.setBounds(120, 88, 96, 23);

panel.add(join);


pf_Pw = new JPasswordField();

pf_Pw.setBounds(71, 57, 116, 21);

panel.add(pf_Pw);

}


}



로그인이 되었다면 채팅을 해야합니다만

서버에서는 회원가입한 정보를 확인하여 로그인을 시켜줍니다.

Oracle DB 를 접속하는 방법을 알아봅시다.


OracleDBConnector.java

package com.lg.messenger;


import java.sql.Connection;

import java.sql.DriverManager;


// 멋있어 보이기 위해서 싱글톤 패턴을 이용하여 접속합니다.

// 고정된 메모리 영역을 얻으면서 메모리 낭비를 줄일 수 있습니다.

public class OracleDBConnector {

private static OracleDBConnector oracleDBConnector = new  OracleDBConnector();

Connection con = null;

private OracleDBConnector() {}

public static OracleDBConnector getInstance(){

if(oracleDBConnector == null){

oracleDBConnector = new OracleDBConnector();

}

return oracleDBConnector;

}

public Connection getConnection() {

try {

Class.forName("oracle.jdbc.driver.OracleDriver");

String url="jdbc:oracle:thin:@127.0.0.1:1521:XE";

con = DriverManager.getConnection(url, "pjc", "pjc");

} catch (Exception e) {

e.printStackTrace();

}

return con;

}

}



커넥션을 만들었으니 이제는 User의 Data 를 만들어 줍니다.

geter/seter 를 만들어주고 있습니다.


UserData.java

package com.lg.messenger;


public class UserData {

private String id;

private String pw;

private String name;

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getPw() {

return pw;

}

public void setPw(String pw) {

this.pw = pw;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}


다음은 UserDao.java 파일 입니다.

조큼 깁니다..

UserDao.java

package com.lg.messenger;


import java.awt.EventQueue;

import java.net.InetAddress;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.util.ArrayList;


// 오라클 접속합시다.

// 그리고 쿼리문을 날리기 위한 PreparedStatement 문을 준비합니다.

public class UserDao {

private static UserDao userDao = new UserDao();

private static OracleDBConnector oracleDBConnector = OracleDBConnector.getInstance();

Connection con;

PreparedStatement pstmt;

ResultSet rs;

UserData user;

ArrayList<UserData> userList;


private UserDao() {

}

 // 마찬가지로 뭔가 있어 보입니다.

public static UserDao getInstance() {

if (userDao == null) {

userDao = new UserDao();

}

return userDao;

}

       // UserData 를 가지고 있는 ArrayList 를 반환합니다. 

public ArrayList<UserData> select() throws Exception {

con = oracleDBConnector.getConnection();

String sql = "SELECT * FROM customer";

pstmt = con.prepareStatement(sql);

rs = pstmt.executeQuery();

userList = new ArrayList<>();

while (rs.next()) {

user = new UserData();

user.setId(rs.getString("id"));

user.setPw(rs.getString("pw"));

user.setName(rs.getString("name"));

userList.add(user);

}

return userList;

}

        // 회원가입에 성공하게 된다면 발생되는 메소드입니다

public int insert(String id, String pw, String name) {

con = oracleDBConnector.getConnection();

int loginOk;

try {

String sql = "INSERT INTO CUSTOMER VALUES ('" + id + "','" + pw + "','" + name + "')";

pstmt = con.prepareStatement(sql);

loginOk = pstmt.executeUpdate();

} catch (Exception e) {

return loginOk = 0;

}

return loginOk;

}


  // 회원가입된 인간인지 확인하기 위하여 만들어줍니다.

public boolean loginCheck(String id, String pw) throws Exception {

con = oracleDBConnector.getConnection();

userList = this.select();

boolean loginOk = false;

for (UserData user : userList) {

if (id.equals(user.getId()) && pw.equals(user.getPw()))

return loginOk = true;

}

return loginOk;

}

       

        // 로그인을 성공했을때 발생합니다.

public void loginSuccess(String id) throws Exception {

con = oracleDBConnector.getConnection();


for (UserData user : userList) {

if (id.equals(user.getId())) {

String loginName = user.getName();

EventQueue.invokeLater(new Runnable() {

public void run() {

try {

InetAddress address = InetAddress.getByName("224.0.1.100");

new Messenger(id,loginName, address , 9999);

} catch (Exception e) {

e.printStackTrace();

}

}

});

break;

}

}

}

// 회원정보를 구지 수정하겠다는 사람을 위해 만들었습니다.

public int userUpdate(String id, String pw, String cPw, String name) throws Exception {

con = oracleDBConnector.getConnection();

int update = 0;

for (UserData user : userList) {

if (id.equals(user.getId()) && pw.equals(user.getPw())){

String sql = "UPDATE CUSTOMER SET PW = '"+cPw+"', NAME = '"+name+"' WHERE ID = '"+id+"'";

pstmt = con.prepareStatement(sql);

update = pstmt.executeUpdate();

break;

}

}

return update;

}

// 이 프로그램이 쓸모 없다는걸 안 사람들이 회원 탈퇴를 하기 시작합니다.

public int userDelete(String id, String pw) throws Exception {

con = oracleDBConnector.getConnection();

int delete = 0;

for (UserData user : userList) {

if (id.equals(user.getId()) && pw.equals(user.getPw())){

String sql = "DELETE FROM CUSTOMER WHERE ID = '"+id+"'";

pstmt = con.prepareStatement(sql);

delete = pstmt.executeUpdate();

break;

}

}

return delete;

}

}



메신저를 보기 전 회원수정 창과 회원 탈퇴 창을 먼저 보겠습니다.


UserDelete.java


package com.lg.messenger;


import java.awt.BorderLayout;

import java.awt.EventQueue;


import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.border.EmptyBorder;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JTextField;

import javax.swing.JButton;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;


// JFrame을 사용합니다.

public class UserDelete extends JFrame {


private JPanel contentPane;

private JTextField tf_UpdatePw;

JLabel lb_DeleteId;

UserDao ud;

        // 회원탈퇴 창을 만들어 줍니다.

public UserDelete(String id) {

setTitle("\uD68C\uC6D0\uD0C8\uD1F4");

setBounds(100, 100, 311, 233);

contentPane = new JPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

setContentPane(contentPane);

contentPane.setLayout(null);

JLabel lblNewLabel = new JLabel("ID :");

lblNewLabel.setBounds(49, 48, 57, 15);

contentPane.add(lblNewLabel);

JLabel lblNewLabel_1 = new JLabel("PW :");

lblNewLabel_1.setBounds(49, 98, 57, 15);

contentPane.add(lblNewLabel_1);

tf_UpdatePw = new JTextField();

tf_UpdatePw.setBounds(95, 95, 116, 21);

contentPane.add(tf_UpdatePw);

tf_UpdatePw.setColumns(10);

// 로그인 , 회원가입과 다를 바가 없습니다.

JButton btnDeleteOk = new JButton("\uC0AD\uC81C");

btnDeleteOk.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

try {

int deleteOk = 0;

deleteOk = UserDao.getInstance().userDelete(lb_DeleteId.getText(), tf_UpdatePw.getText());

if(deleteOk !=0){

JOptionPane.showMessageDialog(null, "삭제완료 바이!");

System.exit(0);

}else{

JOptionPane.showMessageDialog(null, "삭제실패");

}

} catch (Exception e1) {

e1.printStackTrace();

}

}

});

btnDeleteOk.setBounds(49, 136, 97, 23);

contentPane.add(btnDeleteOk);

JButton btnUpdateBack = new JButton("\uCDE8\uC18C");

btnUpdateBack.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

dispose();

}

});

btnUpdateBack.setBounds(158, 136, 97, 23);

contentPane.add(btnUpdateBack);

lb_DeleteId = new JLabel(id);

lb_DeleteId.setBounds(95, 48, 57, 15);

contentPane.add(lb_DeleteId);

}

}



다음은 회원 수정입니다


UserUpdate.java

package com.lg.messenger;


import java.awt.BorderLayout;

import java.awt.EventQueue;


import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.border.EmptyBorder;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JTextField;

import javax.swing.JButton;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;


public class UserUpdate extends JFrame {


private JPanel contentPane;

private JTextField tf_UpdatePw;

private JTextField tf_UpdateUserName;

private JLabel lb_UpdateId;

private JTextField tf_ChangePw;

  // 회원정보를 수정하기 위한 창을 만듭니다.

public UserUpdate(String id) {

setTitle("\uD68C\uC6D0\uC815\uBCF4\uC218\uC815");

setBounds(100, 100, 315, 220);

contentPane = new JPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

setContentPane(contentPane);

contentPane.setLayout(null);

JLabel lblNewLabel = new JLabel("ID :");

lblNewLabel.setBounds(49, 28, 57, 15);

contentPane.add(lblNewLabel);

JLabel lblNewLabel_1 = new JLabel("PW :");

lblNewLabel_1.setBounds(49, 53, 57, 15);

contentPane.add(lblNewLabel_1);

tf_UpdatePw = new JTextField();

tf_UpdatePw.setBounds(118, 50, 116, 21);

contentPane.add(tf_UpdatePw);

tf_UpdatePw.setColumns(10);

// 버튼을 클릭했을때 발생하는 이벤트입니다.

// 구지 수정을하니 재접속을 하라고 시켰습니다.

JButton btnUpdateOk = new JButton("\uC218\uC815");

btnUpdateOk.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

try {

int udateOk = 0;

udateOk = UserDao.getInstance().userUpdate(lb_UpdateId.getText(), tf_UpdatePw.getText(),tf_ChangePw.getText(), tf_UpdateUserName.getText());

if(udateOk != 0){

JOptionPane.showMessageDialog(null, "수정완료 재실행 부탁!");

System.exit(0);

}else{

JOptionPane.showMessageDialog(null, "수정실패 비밀번호 확인!");

}

} catch (Exception e1) {

e1.printStackTrace();

}

}

});

btnUpdateOk.setBounds(49, 148, 97, 23);

contentPane.add(btnUpdateOk);

JButton btnUpdateBack = new JButton("\uCDE8\uC18C");

btnUpdateBack.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

dispose();

}

});

btnUpdateBack.setBounds(158, 148, 97, 23);

contentPane.add(btnUpdateBack);

lb_UpdateId = new JLabel(id);

lb_UpdateId.setBounds(118, 28, 113, 15);

contentPane.add(lb_UpdateId);

JLabel lblNewLabel_2 = new JLabel("NAME :");

lblNewLabel_2.setBounds(49, 103, 57, 15);

contentPane.add(lblNewLabel_2);

tf_UpdateUserName = new JTextField();

tf_UpdateUserName.setBounds(118, 100, 116, 21);

contentPane.add(tf_UpdateUserName);

tf_UpdateUserName.setColumns(10);

JLabel lblChangePw = new JLabel("\uBCC0\uACBD PW:");

lblChangePw.setBounds(49, 78, 57, 15);

contentPane.add(lblChangePw);

tf_ChangePw = new JTextField();

tf_ChangePw.setBounds(118, 75, 116, 21);

contentPane.add(tf_ChangePw);

tf_ChangePw.setColumns(10);

}

}



대망의 채팅방입니다.

사실 별거 없어서 맨 마지막에 올렸습니다.

별거 없습니다.


Messenger.java

package com.lg.messenger;


import java.awt.BorderLayout;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.MulticastSocket;

import java.net.UnknownHostException;

import java.util.Vector;


import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTable;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import javax.swing.table.DefaultTableModel;

import javax.swing.JScrollPane;

import javax.swing.JButton;


// implements 문을 잘 보도록합니다. ActionListener를 이용합니다.

public class Messenger extends JFrame implements ActionListener {

// 연결할 포트를 설정하기 위한 변수입니다.

  private InetAddress inetAddress;

private int port;

  // 기억을 되살려 맨 위에서 보았던 UDP에서 사용하는 소켓들입니다.

private MulticastSocket Socket;

private DatagramPacket Packet;

private DatagramSocket dataSocket;


String userId;

String userName;

private JTextField textField;

private JTextArea textArea;


public Messenger(String id, String name, InetAddress ip, int p) throws UnknownHostException, IOException {

inetAddress = ip;

port = p;

userName = name;

userId = id;

setTitle("\uCC44\uD305\uBC29");

setBounds(100, 100, 400, 280);


getContentPane().setLayout(new BorderLayout(0, 0));


JPanel panel = new JPanel();

getContentPane().add(panel, BorderLayout.SOUTH);

panel.setLayout(new GridLayout(1, 0, 0, 0));


textField = new JTextField();

textField.setColumns(10);


JPanel panel_2 = new JPanel();

getContentPane().add(panel_2, BorderLayout.CENTER);

panel_2.setLayout(new GridLayout(0, 1, 0, 0));


JScrollPane scrollPane = new JScrollPane();

panel_2.add(scrollPane);


textArea = new JTextArea();

scrollPane.setViewportView(textArea);

JPanel panel_1 = new JPanel();

scrollPane.setColumnHeaderView(panel_1);

panel_1.setLayout(new GridLayout(0, 2, 0, 0));

// 누르면 수정창

JButton btnUpdate = new JButton("\uC815\uBCF4\uC218\uC815");

btnUpdate.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent arg0) {

UserUpdate update = new UserUpdate(userId);

update.setVisible(true);

}

});

panel_1.add(btnUpdate);

// 누르면 삭제창

JButton btnDelete = new JButton("\uD68C\uC6D0\uD0C8\uD1F4");

btnDelete.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

UserDelete delete = new UserDelete(userId);

delete.setVisible(true);

}

});

panel_1.add(btnDelete);


textField.addActionListener(this);

panel.add(textField);

this.setVisible(true);

// 누구누구가 접속하였습니다를 구현하였습니다.

Runnable r = new Runnable() {

public void run() {

byte[] buffer = new byte[512];

try {

// socket에 joinGroup을 해줘야합니다.

Socket = new MulticastSocket(port);

Socket.joinGroup(inetAddress);

dataSocket = new DatagramSocket();

String connect = "[ " + userName + "님 이 접속하셨습니다. 종료는 exit ]";

buffer = connect.getBytes();

Packet = new DatagramPacket(buffer, buffer.length, inetAddress, port);

Socket.send(Packet);

while (true) {

Packet = new DatagramPacket(buffer, buffer.length);

Socket.receive(Packet);

String msg = new String(Packet.getData(), 0, Packet.getLength());

textArea.append(msg + "\n");

textArea.setCaretPosition(textArea.getDocument().getLength());

}

} catch (IOException e) {

e.printStackTrace();

System.exit(0);

} finally {

Socket.close();

}

}

};

new Thread(r).start();

}

  

   // exit를 입력했을때 퇴장되게 만들었습니다.

@Override

public void actionPerformed(ActionEvent evt) {

String s = textField.getText();

textField.setText(null);

byte[] buffer = new byte[512];


if (s == null || s == "" || s == "\n" || s.length() == 0) {

return;

} else if (s.equals("exit")) {

String connect = "[" + userName + "님 이 퇴장하셨습니다.]";

buffer = connect.getBytes();

Packet = new DatagramPacket(buffer, buffer.length, inetAddress, port);

try {

Socket.send(Packet);

} catch (IOException e) {

e.printStackTrace();

}

Socket.close();

System.exit(0);

}

try {

dataSocket = new DatagramSocket();

String msg = "[" + userName + "] " + s;

buffer = msg.getBytes();

Packet = new DatagramPacket(buffer, buffer.length, inetAddress, port);

Socket.send(Packet);

} catch (IOException ie) {

System.out.println("send 오류");

} finally {

dataSocket.close();  // 연결을 종료합니다.

}

}

}


맨 마지막이 되니 설명이 부족해보입니다.

하지만 여러분은 모두 천재이니 쉽게 이해하셨으리라 믿습니다.


이상으로 UDP 를 이용한 다중 채팅 프로그램 만들기 포스팅을 마치도록 하겠습니다.


도움이 되셨다면 공감 + a 감사합니다.

엉망진창

개인 블로그 입니다. 코딩, 맛집, 정부정책, 서비스, ~방법 등 다양한 정보를 소개합니다