-
자바 네트워크(2.5) / UDP카테고리 없음 2021. 9. 9.반응형
TCP/IP가 양방향 통신이라면 UDP는 그냥 일방적으로 한쪽에서 상대가 받든 말든 계속 쏘는 것
TCP와 UDP의 차이점
- 신뢰성 보장 힘듬
- 데이터 손실 여부 있음
- 패킷을 관리 해야함
- TCP보다 전송 속도는 빠름
자바에서 UDP 통신을 하려면 위의 DatagramPacket 클래스와 DatagramSocket 클래스를 사용해야 한다.
주고 받을 데이터와 관련된 클래스는 = DatagramPacket
실제 데이터의 전송과 관련된 클래스는 = DatagramSocket
UDP 서버 코드
package udpEx; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Random; // 1:1 public class UDPServer implements Runnable { private int SIZE = 80; private InetAddress ia = null; private int port1 = 7788, port2 = 7799; private DatagramSocket ds1, ds2; private DatagramPacket dp1, dp2; private int guess; public UDPServer() { Thread th = new Thread(this); th.start(); System.out.println("UDP 서버 시작 !!!"); } public void run() { try { guess = getNumber(); // System.out.println("게스:"+guess); String str; int num; ds1 = new DatagramSocket(port1); byte[] buffer; while (true) { buffer = new byte[SIZE]; dp1 = new DatagramPacket(buffer, SIZE); ds1.receive(dp1); ia = dp1.getAddress(); str = new String(dp1.getData()); str = str.trim(); num = Integer.parseInt(str); str = check(num, guess); sendData(str); // 게임을 다시 시작할 경우 if (str.equals("success")) { guess = getNumber(); } } } catch (IOException e) { e.printStackTrace(); } } public void sendData(String msg) { try { if (ia == null) return; byte[] buffer = msg.getBytes(); ds2 = new DatagramSocket(); dp2 = new DatagramPacket(buffer, buffer.length, ia, port2); ds2.send(dp2); } catch (Exception e) { e.printStackTrace(); } } // 세자리의 난수를 발생함 public int getNumber() { int comNum; Random rd = new Random(); int m1, m2, m3; m1 = rd.nextInt(9) + 1; do { m2 = rd.nextInt(9) + 1; } while (m1 == m2); do { m3 = rd.nextInt(9) + 1; } while (m1 == m3 || m2 == m3); comNum = (m1 * 100 + m2 * 10 + m3); return comNum; } public String check(int num, int guess) { String s; int hits = 0, balls = 0; int[] n = new int[3], m = new int[3]; for (int i = 0; i < 3; i++) { n[i] = num % 10; m[i] = guess % 10; num = (int) num / 10; guess = (int) guess / 10; } for (int i = 0; i < 3; i++) { if (n[i] == m[i]) hits++; for (int j = 0; j < 3; j++) if (n[i] == m[j] && i != j) balls++; } if (hits == 3) { s = "success"; } else { s = hits + " hits, " + balls + " balls"; } return s; } public static void main(String args[]) { new UDPServer(); } }
UDP 클라이언트 코드
package udpEx; import java.awt.BorderLayout; 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.util.regex.Pattern; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; // 1:1 public class UDPClient extends JFrame implements Runnable, ActionListener { private static final long serialVersionUID = 1L; private JTextArea ta = new JTextArea(); private JTextField tf = new JTextField(7); private JButton btn = new JButton("확인"); private int SIZE = 80; private String host = "127.0.0.1"; private InetAddress ia = null; private int port1 = 7788, port2 = 7799; private DatagramSocket ds1, ds2; private DatagramPacket dp1, dp2; private String myNum; private int count; public UDPClient() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ta.setEditable(false); add(new JScrollPane(ta), BorderLayout.CENTER); JPanel p = new JPanel(); p.add(new JLabel("your guess : ")); p.add(tf); p.add(btn); btn.addActionListener(this); add(p, BorderLayout.SOUTH); setLocation(400, 300); setSize(400, 300); setResizable(false); setVisible(true); try { ia = InetAddress.getByName(host); Thread th = new Thread(this); th.start(); ta.setText("게임을 시작합니다.\n"); } catch (Exception e) { } } public void run() { try { String str; ds2 = new DatagramSocket(port2); count = 0; byte[] buffer; while (true) { buffer = new byte[SIZE]; dp2 = new DatagramPacket(buffer, SIZE); ds2.receive(dp2); str = new String(dp2.getData()); str = str.trim(); if (str.equals("success")) { ta.append("성공 입니다. !!!\n"); int result; result = JOptionPane.showConfirmDialog(this, "계속 하시겠습니까?", "확인", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (result == JOptionPane.OK_OPTION) { ta.setText("게임을 시작합니다.\n"); count = 0; continue; } else { ia = null; System.exit(0); } } count++; ta.append(count + " your guess : " + myNum + " -> " + str + "\n"); } } catch (IOException e) { e.printStackTrace(); } } public void actionPerformed(ActionEvent e) { try { if (ia == null) return; myNum = tf.getText().trim(); if (myNum.length() == 0) { tf.requestFocus(); return; } boolean b = Pattern.matches("\\d{3}", myNum); if (!b || !formatOK(Integer.parseInt(myNum))) { JOptionPane.showMessageDialog(this, "서로 다른 1~9까지의 세자리 정수만 입력 가능합니다.", "정보", JOptionPane.INFORMATION_MESSAGE); tf.requestFocus(); return; } byte[] buffer = myNum.getBytes(); ds1 = new DatagramSocket(); dp1 = new DatagramPacket(buffer, buffer.length, ia, port1); ds1.send(dp1); tf.setText(""); tf.requestFocus(); } catch (Exception exp) { exp.printStackTrace(); } } // 서로 다른 세자리 수인지 확인 public boolean formatOK(int num) { if (num < 123 || num > 987) return false; int n1 = (int) num / 100; int n2 = ((int) num / 10) % 10; int n3 = num % 10; return (n1 != n2 && n2 != n3 && n1 != n3); } public static void main(String args[]) throws Exception { new UDPClient(); } }
반응형