네트워크 이야기에 써야 마땅할 ARP 프로토콜을 프로그래밍 이야기에 적으려 합니다.
제가 04년에 학과 과목 중 한 과목 텀 프로젝트로.....
만들었던 프로그램입니다.
ARP 프로토콜... 움직임을 네트워크 상에 표현한 소스 코드 입니다.
첫번째 소스 코드 입니다.
// eXtream.java ........................................................................
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.border.*;
import java.io.*;
import java.net.*;
/**
* main class
* class의 기능
* 1. 패킷 이동 모습을 보여주는 것과
* 2. 실제 C/S환경을 만들어 패킷을 전송하는것을 보여줌
* 3. Server는 network의 회선을 지칭한다.
* 4. Client는 network에 접속된 Computer로 지칭된다.
*/
public class eXtream extends JFrame implements Runnable, ActionListener {
/**
* // 사용자 정의 클래스 Object로 선언
* 사용자 정의 class의 객체를 선언하는 부분
*/
myObject my_ob = new myObject();
myTable ta[] = new myTable[8];
Network2 nt = new Network2();
One_1 oe[] = new One_1[8];
//////////////////////////////////////////////////////////////////////
// GUI Component 부분
JPanel com1 = new JPanel();
JPanel com2 = new JPanel();
JPanel com3 = new JPanel();
JPanel com4 = new JPanel();
JPanel com5 = new JPanel();
JPanel com6 = new JPanel();
JPanel com7 = new JPanel();
JPanel com8 = new JPanel();
ImageIcon ic = new ImageIcon("bg.gif");
ImageIcon con = new ImageIcon("icon.gif");
JButton bu_init = new JButton();
JLabel bg = new JLabel();
JButton effect = new JButton();
JButton bu_Kill = new JButton();
Graphics g = null;
//////////////////////////////////////////////////////////////////
int center_XY[][] = new int[17][2];
int one_XY[][] = new int[5][2];
int two_XY[][] = new int[5][2];
int thd_XY[][] = new int[5][2];
int fth_XY[][] = new int[5][2];
String log_hard[][] = // IP주소와 MAC주소를 지정하였다.
{{"130.23.43.20","B23455102210"}, {"130.23.43.21", "46EF45983AB"},
{"130.23.43.22","A23EF5510210"}, {"130.23.43.23", "BA021434EECD"},
{"130.23.43.24","B4512340113"}, {"130.23.53.25","CEFE4213420"},
{"130.23.43.25","B2345522110"}, {"130.23.43.26","46FE45938BA"}
};
int th_type = 0; // thread 돌아갈때 애니메이션의 어느부분인가 지정하는것
Thread th = null; // Thread 객체 선언....
GridLayout gridLayout1 = new GridLayout();
JButton bu1_com1 = new JButton();
JButton bu2_com1 = new JButton();
JLabel jLabel1 = new JLabel();
JButton bu1_com2 = new JButton();
JButton bu2_com2 = new JButton();
JLabel jLabel2 = new JLabel();
GridLayout gridLayout2 = new GridLayout();
GridLayout gridLayout3 = new GridLayout();
JButton bu1_com3 = new JButton();
JButton bu2_com3 = new JButton();
JLabel jLabel3 = new JLabel();
GridLayout gridLayout4 = new GridLayout();
JButton bu1_com4 = new JButton();
JButton bu2_com4 = new JButton();
JLabel jLabel4 = new JLabel();
GridLayout gridLayout5 = new GridLayout();
JButton bu1_com5 = new JButton();
JButton bu2_com5 = new JButton();
JLabel jLabel5 = new JLabel();
GridLayout gridLayout6 = new GridLayout();
JButton bu1_com6 = new JButton();
JButton bu2_com6 = new JButton();
JLabel jLabel6 = new JLabel();
GridLayout gridLayout7 = new GridLayout();
GridLayout gridLayout8 = new GridLayout();
JButton bu1_com7 = new JButton();
JButton bu2_com7 = new JButton();
JLabel jLabel7 = new JLabel();
JButton bu1_com8 = new JButton();
JButton bu2_com8 = new JButton();
JLabel jLabel8 = new JLabel();
TitledBorder titledBorder1;
/**
* 생성자 Design 설정 메소드를 호출한다.
*/
public eXtream() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
eXtream eXtream = new eXtream();
}
/**
* jbInit() Design을 설정하는 메소드
* @throws java.lang.Exception
*/
private void jbInit() throws Exception {
titledBorder1 = new TitledBorder("");
this.getContentPane().setBackground(Color.white);
this.setResizable(false);
this.setState(Frame.NORMAL);
this.setTitle("ARP Emulator");
this.getContentPane().setLayout(null);
com1.setBackground(Color.lightGray);
com1.setBorder(BorderFactory.createRaisedBevelBorder());
com1.setBounds(new Rectangle(21, 28, 67, 57));
com1.setLayout(gridLayout1);
com2.setBackground(Color.lightGray);
com2.setBorder(BorderFactory.createRaisedBevelBorder());
com2.setBounds(new Rectangle(125, 28, 67, 57));
com2.setLayout(gridLayout2);
com3.setBackground(Color.lightGray);
com3.setBorder(BorderFactory.createRaisedBevelBorder());
com3.setBounds(new Rectangle(233, 28, 67, 57));
com3.setLayout(gridLayout3);
com4.setBackground(Color.lightGray);
com4.setBorder(BorderFactory.createRaisedBevelBorder());
com4.setBounds(new Rectangle(346, 28, 67, 57));
com4.setLayout(gridLayout4);
com5.setBackground(Color.lightGray);
com5.setBorder(BorderFactory.createRaisedBevelBorder());
com5.setBounds(new Rectangle(21, 186, 67, 57));
com5.setLayout(gridLayout5);
com6.setBackground(Color.lightGray);
com6.setBorder(BorderFactory.createRaisedBevelBorder());
com6.setBounds(new Rectangle(125, 186, 67, 57));
com6.setLayout(gridLayout6);
com7.setBackground(Color.lightGray);
com7.setBorder(BorderFactory.createRaisedBevelBorder());
com7.setBounds(new Rectangle(233, 186, 67, 57));
com7.setLayout(gridLayout7);
com8.setBackground(Color.lightGray);
com8.setBorder(BorderFactory.createRaisedBevelBorder());
com8.setBounds(new Rectangle(346, 186, 67, 57));
com8.setLayout(gridLayout8);
bu_init.setBounds(new Rectangle(421, 27, 84, 66));
bu_init.setFont(new java.awt.Font("SansSerif", 0, 12));
bu_init.setMargin(new Insets(0, 0, 0, 0));
bu_init.setText("System Init");
bg.setBackground(Color.white);
bg.setOpaque(true);
bg.setBounds(new Rectangle(49, 85, 342, 101));
effect.setBounds(new Rectangle(421, 175, 84, 66));
effect.setEnabled(false);
effect.setFont(new java.awt.Font("SansSerif", 0, 12));
effect.setMargin(new Insets(0, 0, 0, 0));
effect.setText("효과가동");
bu_Kill.setBounds(new Rectangle(421, 101, 84, 66));
bu_Kill.setFont(new java.awt.Font("SansSerif", 0, 12));
bu_Kill.setMargin(new Insets(0, 0, 0, 0));
bu_Kill.setText("System Term.");
bu1_com1.setFont(new java.awt.Font("SansSerif", 0, 12));
bu1_com1.setMargin(new Insets(0, 0, 0, 0));
bu1_com1.setText("정보보기");
gridLayout1.setRows(3);
bu2_com1.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com1.setMargin(new Insets(0, 0, 0, 0));
bu2_com1.setText("ARP요청");
jLabel1.setText("Com1");
bu1_com2.setText("정보보기");
bu1_com2.setMargin(new Insets(0, 0, 0, 0));
bu1_com2.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com2.setText("ARP요청");
bu2_com2.setMargin(new Insets(0, 0, 0, 0));
bu2_com2.setFont(new java.awt.Font("SansSerif", 0, 12));
jLabel2.setToolTipText("");
jLabel2.setText("Com2");
gridLayout2.setRows(3);
gridLayout3.setRows(3);
bu1_com3.setText("정보보기");
bu1_com3.setMargin(new Insets(0, 0, 0, 0));
bu1_com3.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com3.setText("ARP요청");
bu2_com3.setMargin(new Insets(0, 0, 0, 0));
bu2_com3.setFont(new java.awt.Font("SansSerif", 0, 12));
jLabel3.setText("Com3");
gridLayout4.setRows(3);
bu1_com4.setText("정보보기");
bu1_com4.setMargin(new Insets(0, 0, 0, 0));
bu1_com4.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com4.setText("ARP요청");
bu2_com4.setMargin(new Insets(0, 0, 0, 0));
bu2_com4.setFont(new java.awt.Font("SansSerif", 0, 12));
jLabel4.setText("Com4");
jLabel4.setVerticalAlignment(SwingConstants.CENTER);
jLabel4.setVerticalTextPosition(SwingConstants.CENTER);
gridLayout5.setRows(3);
bu1_com5.setText("정보보기");
bu1_com5.setMargin(new Insets(0, 0, 0, 0));
bu1_com5.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com5.setText("ARP요청");
bu2_com5.setMargin(new Insets(0, 0, 0, 0));
bu2_com5.setFont(new java.awt.Font("SansSerif", 0, 12));
jLabel5.setText("Com5");
gridLayout6.setRows(3);
bu1_com6.setText("정보보기");
bu1_com6.setMargin(new Insets(0, 0, 0, 0));
bu1_com6.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com6.setText("ARP요청");
bu2_com6.setMargin(new Insets(0, 0, 0, 0));
bu2_com6.setFont(new java.awt.Font("SansSerif", 0, 12));
jLabel6.setForeground(Color.black);
jLabel6.setText("Com6");
bu1_com7.setText("정보보기");
bu1_com7.setMargin(new Insets(0, 0, 0, 0));
bu1_com7.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com7.setText("ARP요청");
bu2_com7.setMargin(new Insets(0, 0, 0, 0));
bu2_com7.setFont(new java.awt.Font("SansSerif", 0, 12));
jLabel7.setText("Com7");
bu1_com8.setText("정보보기");
bu1_com8.setMargin(new Insets(0, 0, 0, 0));
bu1_com8.setFont(new java.awt.Font("SansSerif", 0, 12));
bu2_com8.setText("ARP요청");
bu2_com8.setMargin(new Insets(0, 0, 0, 0));
bu2_com8.setFont(new java.awt.Font("SansSerif", 0, 12));
jLabel8.setText("Com8");
gridLayout8.setRows(3);
gridLayout7.setRows(3);
this.getContentPane().add(com1, null);
com1.add(jLabel1, null);
com1.add(bu1_com1, null);
com1.add(bu2_com1, null);
this.getContentPane().add(com4, null);
this.getContentPane().add(com3, null);
this.getContentPane().add(com2, null);
this.getContentPane().add(com6, null);
this.getContentPane().add(com7, null);
this.getContentPane().add(com8, null);
this.getContentPane().add(com5, null);
this.getContentPane().add(bg, null);
com3.add(jLabel3, null);
com4.add(jLabel4, null);
com4.add(bu1_com4, null);
com4.add(bu2_com4, null);
com2.add(jLabel2, null);
com2.add(bu1_com2, null);
com2.add(bu2_com2, null);
com3.add(bu1_com3, null);
com3.add(bu2_com3, null);
com5.add(jLabel5, null);
com6.add(jLabel6, null);
com7.add(jLabel7, null);
com7.add(bu1_com7, null);
com7.add(bu2_com7, null);
com8.add(jLabel8, null);
com8.add(bu1_com8, null);
com8.add(bu2_com8, null);
com5.add(bu1_com5, null);
com5.add(bu2_com5, null);
com6.add(bu1_com6, null);
com6.add(bu2_com6, null);
this.getContentPane().add(bu_init, null);
this.getContentPane().add(bu_Kill, null);
this.getContentPane().add(effect, null);
this.setSize(new Dimension(530, 281));
this.setVisible(true);
g = bg.getGraphics();
conXY();
addEvent(); // GUI 컴포넌트 Event 등록용 메소드
}
/**
* GUI component의 Event를 시스템에 등록시키는 메소드
*/
private void addEvent() {
bu_init.addActionListener(this);
effect.addActionListener(this);
bu_Kill.addActionListener(this);
bu1_com1.addActionListener(this);
bu2_com1.addActionListener(this);
bu1_com2.addActionListener(this);
bu2_com2.addActionListener(this);
bu1_com3.addActionListener(this);
bu2_com3.addActionListener(this);
bu1_com4.addActionListener(this);
bu2_com4.addActionListener(this);
bu1_com5.addActionListener(this);
bu2_com5.addActionListener(this);
bu1_com6.addActionListener(this);
bu2_com6.addActionListener(this);
bu1_com7.addActionListener(this);
bu2_com7.addActionListener(this);
bu1_com8.addActionListener(this);
bu2_com8.addActionListener(this);
my_ob.bu_ok.addActionListener(this);
my_ob.bu_cancel.addActionListener(this);
}
/**
* ActionEvent를 처리 하기 위한 메소드로써 ActionEvent 객체를 parameter값으로 받아온다.
* @param ev ActionEvent
*/
public void actionPerformed(ActionEvent ev) {
Object ob = ev.getSource();
if(ob == bu_init){
set_Network();
setImage();
bu_init.setEnabled(false);
}
if(ob == bu_Kill) {
try {
this.setVisible(false);
System.exit(0);
} catch(Exception ex) {}
}
if(ob == effect) {
}
if(ob == bu1_com1) { show_Table(0); }
if(ob == bu1_com2) { show_Table(1); }
if(ob == bu1_com3) { show_Table(2); }
if(ob == bu1_com4) { show_Table(3); }
if(ob == bu1_com5) { show_Table(4); }
if(ob == bu1_com6) { show_Table(5); }
if(ob == bu1_com7) { show_Table(6); }
if(ob == bu1_com8) { show_Table(7); }
if(ob == bu2_com1) { show_Arp(0); }
if(ob == bu2_com2) { show_Arp(1); }
if(ob == bu2_com3) { show_Arp(2); }
if(ob == bu2_com4) { show_Arp(3); }
if(ob == bu2_com5) { show_Arp(4); }
if(ob == bu2_com6) { show_Arp(5); }
if(ob == bu2_com7) { show_Arp(6); }
if(ob == bu2_com8) { show_Arp(7); }
if(ob == my_ob.bu_cancel) {
if(my_ob.isVisible() == true) {
my_ob.tf_ip.setText("");
my_ob.setVisible(false);
}
}
if(ob == my_ob.bu_ok) {
arp_Request(my_ob.get_ProcessNum()); //arp 요청
my_ob.tf_ip.setText("");
my_ob.setVisible(false);
}
if(ob == ta[0].bu_update) { update_Table(0); }
if(ob == ta[1].bu_update) { update_Table(1); }
if(ob == ta[2].bu_update) { update_Table(2); }
if(ob == ta[3].bu_update) { update_Table(3); }
if(ob == ta[4].bu_update) { update_Table(4); }
if(ob == ta[5].bu_update) { update_Table(5); }
if(ob == ta[6].bu_update) { update_Table(6); }
if(ob == ta[7].bu_update) { update_Table(7); }
}
/**
* ARP 에뮬레이팅을 위한 네트워크 환경 구축용 메소드
*/
private void set_Network() {
nt.servStart();
for(int i=0;i<8;i++) {
ta[i] = new myTable();
ta[i].set_IP(log_hard[i][0]);
ta[i].set_Mac(log_hard[i][1]);
ta[i].bu_update.addActionListener(this);
oe[i] = new One_1();
oe[i].connProcess(log_hard[i][0],log_hard[i][1]);
oe[i].set_Num(i);
}
}
/**
* Table을 Update시키게 하는 메소드
* @param num table이 몇번인지 파악한다.
*/
private void update_Table(int num) {
ta[num].validate();
}
/**
* Table Frame을 사용자에게 보여주는 메소드
* @param num Table의 몇번인지 파악한다.
*/
private void show_Table(int num) {
ta[num].setVisible(true);
}
/**
* arp요청시 필요한 IP정보를 받아오기 위한 메소드
* @param pid 몇번째 Table에서 요청하는지 파악하지 위한 값전달
*/
private synchronized void show_Arp(int pid) {
my_ob.setLocation(400,300);
my_ob.set_ProcessNum(pid);
my_ob.setVisible(true);
}
/**
* ARP를 요청 하여 처리
* @param i 몇번째 Client에서 요청하였는지 파악하는 인수값
*/
private void arp_Request(int i) {
String ip = my_ob.tf_ip.getText().trim();
boolean tf = ta[i].isIpRow(ip);
if(tf == false) {
String temp = ta[i].get_State(ip);
if(temp == "R") {// resolved 상태이면
JOptionPane.showMessageDialog(this,"이미 Table에 해당 ip에 대한 mac이 등록되어 있습니다.");
} else if(temp == "P") {
JOptionPane.showMessageDialog(this,"Physical address를 기다리는중입니다. 잠시만 기다리세요");
}
} else {
int proc_num = my_ob.get_ProcessNum();
oe[i].sendProcess(ip);
}
}
/**
* 5개의 배열에 초기값을 저장하는 메소드
*/
private void conXY() {
int i;
for(i=0;i<17;i++) {
center_XY[i][1] = 41;
}
center_XY[0][0] = 1;
for(i=1;i<17;i++) {
center_XY[i][0] = 1 + (20 * i);
}
for(i=0;i<5;i++) {
one_XY[i][0] = 1;
two_XY[i][0] = 101;
thd_XY[i][0] = 221;
fth_XY[i][0] = 321;
}
one_XY[0][1] = 1;
two_XY[0][1] = 1;
thd_XY[0][1] = 1;
fth_XY[0][1] = 1;
for(i=1;i<5;i++) {
one_XY[i][1] = 1 + (20 * i);
two_XY[i][1] = 1 + (20 * i);
thd_XY[i][1] = 1 + (20 * i);
fth_XY[i][1] = 1 + (20 * i);
}
}
/**
* 애니메이션 효과를 위한 배경 이미지 삽입
*
* */
public void setImage() {
bg.setIcon(ic);
}
/**
* i번 computer에서 전체로 broadCasting할때 패킷 보여주는것
* @param i 몇 번째 가상 client에서 broadcasting하는 알려주기 위한것
*/
public void show_All(int i) {
switch(i) {
case 1: one_to_All(); break;
case 2: two_to_All(); break;
case 3: thd_to_All(); break;
case 4: fth_to_All(); break;
case 5: fiv_to_All(); break;
case 6: six_to_All(); break;
case 7: sev_to_All(); break;
case 8: egh_to_All(); break;
}
}
/**
* 1번에서 Broadcasting 할때
*/
public void one_to_All() {
one_1();
one_2();
one_3();
one_4();
} // end of one_to_All();
/**
* 5번에서 broadCasting 할때
*/
public void fiv_to_All() {
one_other();
one_2();
one_3();
one_4();
} // end of fiv_to_All()
/**
* 4번에서 broadCasting 할때
*/
public void fth_to_All() {
two_1();
two_2();
two_3();
two_4();
} // end of fth_to_All()
/**
* 8번에서 broadcasting 할때
*/
public void egh_to_All() {
two_other();
two_2();
two_3();
two_4();
} // end of egh_to_All()
/**
* 2번에서 BroadCasting시...
*/
public void two_to_All() {
// 왼쪽과 아래에 위치한 Computer로 패킷으로 전송
two_move2();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(8);
th = new Thread(this);
th_type = 23;
th.start();
try {
Thread.sleep(400);
} catch(Exception ex) {}
two_4();
// 아래로 내려와 오른쪽에 위치한 Computer로 패킷으로 전송
try {
Thread.sleep(100);
} catch(Exception ex) {}
two_move2();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(3);
try {
Thread.sleep(500);
} catch(Exception ex) {}
one_3();
one_4();
} // end of two_to_All()
/**
* 6번에서 BroadCasting할 경우
*/
public void six_to_All() {
// 왼쪽과 위에 위치한 Computer로 패킷으로 전송
two_move5();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(8);
th = new Thread(this);
th_type = 26;
th.start();
try {
Thread.sleep(400);
} catch(Exception ex) {}
two_4();
// 위로 올라가 오른쪽에 위치한 Computer로 패킷으로 전송
try {
Thread.sleep(100);
} catch(Exception ex) {}
two_move5();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(3);
try {
Thread.sleep(500);
} catch(Exception ex) {}
one_3();
one_4();
} // end of six_to_All();
/**
* 3번에서 BroadCasting 할경우
*/
public void thd_to_All() {
// 왼쪽과 아래에 위치한 Computer로 패킷으로 전송
thd_move2();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(7);
th = new Thread(this);
th_type = 33;
th.start();
try {
Thread.sleep(400);
} catch(Exception ex) {}
two_3();
two_4();
// 아래로 내려와 오른쪽에 위치한 Computer로 패킷으로 전송
try {
Thread.sleep(100);
} catch(Exception ex) {}
thd_move2();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(4);
try {
Thread.sleep(500);
} catch(Exception ex) {}
one_4();
} // end of thd_to_All()
/**
* 7번에서 BroadCasting을 할경우
*/
public void sev_to_All() {
// 왼쪽과 아래에 위치한 Computer로 패킷으로 전송
thd_move5();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(7);
th = new Thread(this);
th_type = 36;
th.start();
try {
Thread.sleep(400);
} catch(Exception ex) {}
two_3();
two_4();
// 아래로 내려와 오른쪽에 위치한 Computer로 패킷으로 전송
try {
Thread.sleep(100);
} catch(Exception ex) {}
thd_move5();
try {
Thread.sleep(100);
} catch(Exception ex) {}
second_th(4);
try {
Thread.sleep(500);
} catch(Exception ex) {}
one_4();
}
/**
* 4번에서 broadCasting 할때 기본 설정
*/
public void two_1() { //
fth_move2();
second_th(6);
time_move(43);
}
/**
* 8번에서 broadCasting 할때는 위에 있는 two_1()의 메소드의 일부만 수정사용
*/
public void two_other() {
fth_move5();
second_th(6);
time_move(46);
}
/** 애니메이션 효과를 위한 메소드
* ↑
* ← // 이런식으로 움직임을 보여주는 메소드
* ↓ // 아래에 있는 two_3(), two_4() 메소드도 같은 역할을 한다.
*/
public void two_2() {
try {
Thread.sleep(400);
} catch(Exception ex) {}
second_th(7);
th = new Thread(this);
th_type = 36;
th.start();
time_move(33);
}
public void two_3() {
try {
Thread.sleep(400);
} catch(Exception ex) {}
second_th(8);
th = new Thread(this);
th_type = 26;
th.start();
time_move(23);
}
public void two_4() {
try {
Thread.sleep(400);
} catch(Exception ex) {}
th = new Thread(this);
th_type = 16;
th.start();
time_move(13);
}
/**
* 1번 시작 할때 첫번째 이동 메소드
*/
public void one_1() { //
one_move2();
second_th(2);
time_move(13);
}
/**
* 1번 아래 있는 5번에서 시작할때 첫번째 이동 메소드
*/
public void one_other() { //
one_move5();
second_th(2);
time_move(16);
}
/**
* 위에 있는 two_x메소드와 반대방향 → 이런식으로 패킷을 보내는 기능을 가진 메소드
*/
public void one_2() {
try {
Thread.sleep(300);
} catch(Exception ex) {}
th = new Thread(this);
th_type = 23;
th.start();
second_th(3);
time_move(26);
}
/**
* 위의 one_2()의 오른쪽으로 한블럭이동된 곳에서 시작한다.
*/
public void one_3() {
try {
Thread.sleep(300);
} catch(Exception ex) {}
th = new Thread(this);
th_type = 33;
th.start();
second_th(4);
time_move(36);
}
/**
* one_3에서 오른쪽 방향으로 진행하는 패킷 이동 효과용 메소드
*
*/
public void one_4() {
try {
Thread.sleep(300);
} catch(Exception ex) {}
th = new Thread(this);
th_type = 43;
th.start();
time_move(46);
}
/**
* Second_th 메소드는 Second Thread를 이용하기 위한 메소드
* @param i i번째 Thread를 시작하기 위해서 지정
*/
private void second_th(int i) {
Second se = new Second(i);
se.start();
}
/**
* 두번째 Thread로 애니메이션 효과를 위해 만든 것으로
* inner class로 구현하였다.
*/
class Second extends Thread {
int i;
Second(int item) {
i = item;
}
public void run() {
try {
Thread.sleep(25);
} catch(Exception ex) {}
if(i == 2) { run_case2(); // 왼쪽에서 오른쪽 1번 메소드
} else if(i == 3) { run_case3(); // 2번 메소드
} else if(i == 4) { run_case4(); // 3번 메소드
} else if(i == 6) { run_case6(); // 오른쪽에서 왼쪽 1번 메소드
} else if(i == 7) { run_case7(); // 2번 메소드
} else if(i == 8) { run_case8(); // 3번 메소드
}
}
}
/**
* TimerTack를 상속 받아온 inner class로...
* 애니메이션 효과를 위해서 Thread와 유사한 TimerTask를 이용하여 제작함
*
*/
class Timer extends TimerTask {
int i = 1;
Timer(int i) {
this.i = i;
}
public void run() {
try {
Thread.sleep(25);
} catch(Exception ex) {}
if(i == 12) { one_move2();
} else if(i == 13) { one_move3();
} else if(i == 15) { one_move5();
} else if(i == 16) { one_move6();
} else if(i == 22) { two_move2();
} else if(i == 23) { two_move3();
} else if(i == 25) { two_move5();
} else if(i == 26) { two_move6();
} else if(i == 32) { thd_move2();
} else if(i == 33) { thd_move3();
} else if(i == 35) { thd_move5();
} else if(i == 36) { thd_move6();
} else if(i == 42) { fth_move2();
} else if(i == 43) { fth_move3();
} else if(i == 45) { fth_move5();
} else if(i == 46) { fth_move6();
}
}
}
/**
* 위에 있는 Timer 클래스를 사용하기 위한 메소드임
* @param in in의 값의 timer를 실행할건지 결정하기 위해서
*/
private void time_move(int in) {
Timer ti = new Timer(in);
ti.run();
}
public synchronized void run() {
try { // 다른 스레드 또는 TimerTask랑 속도를 맞추기 위해 sleep을 건다.
Thread.sleep(25);
} catch(Exception ex) {}
if(th_type == 9) {
if(th_type == 1) { run_case1();
} else if(th_type == 2) { run_case2();
} else if(th_type == 3) { run_case3();
} else if(th_type == 4) { run_case4();
} else if(th_type == 5) { run_case5();
} else if(th_type == 6) { run_case6();
} else if(th_type == 7) { run_case7();
} else if(th_type == 8) { run_case8();
}
} else if((th_type > 10) && (th_type < 20)) {
if(th_type == 11) { one_move1();
} else if(th_type == 12) { one_move2();
} else if(th_type == 13) { one_move3();
} else if(th_type == 14) { one_move4();
} else if(th_type == 15) { one_move5();
} else if(th_type == 16) { one_move6();
}
} else if((th_type > 20) && (th_type < 30)) {
if(th_type == 21) { two_move1();
} else if(th_type == 22) { two_move2();
} else if(th_type == 23) { two_move3();
} else if(th_type == 24) { two_move4();
} else if(th_type == 25) { two_move5();
} else if(th_type == 26) { two_move6();
}
} else if((th_type > 30) && (th_type < 40)) {
if(th_type == 31) { thd_move1();
} else if(th_type == 32) { thd_move2();
} else if(th_type == 33) { thd_move3();
} else if(th_type == 34) { thd_move4();
} else if(th_type == 35) { thd_move5();
} else if(th_type == 36) { thd_move6();
}
} else if((th_type > 40) && (th_type < 50)) {
if(th_type == 41) { fth_move1();
} else if(th_type == 42) { fth_move2();
} else if(th_type == 43) { fth_move3();
} else if(th_type == 44) { fth_move4();
} else if(th_type == 45) { fth_move5();
} else if(th_type == 46) { fth_move6();
}
}
} // end of run();
/**
* 패킷 이동을 보여 주기 위한 애니메이션 효과 처리 부분 으로
* run_case'X'()메소드들은 부분별 효과를 담당하고 있다.('X'는 숫자)
*/
/**
* run_case1()은 왼쪽에서 오른쪽으로 이동하는 효과
*/
private void run_case1() {
run_case2();
run_case3();
run_case4();
}
private void run_case2() { move_Process(0,6,1,5); }
private void run_case3() { move_Process(5,12,1,5); }
private void run_case4() { move_Process(11,17,1,5); }
/**
* run_case5는 오른쪽에서 왼쪽으로 이동하는 효과
*/
private void run_case5() {
run_case6();
run_case7();
run_case8();
}
private void run_case6() { move_Process(16,11,2,5); }
private void run_case7() { move_Process(11,5,2,5); }
private void run_case8() { move_Process(5,0,2,5); }
// one_moveX() 시리즈 메소드는 맨 왼쪽에 위치한 패킷 이동지역의 이동을 담당한다.
private void one_move1() {
one_move2();
one_move3();
}
// one_move1,2,3 메소드는 위에서 아래 방향으로
private void one_move2() { move_Process(0,3,1,1); }
private void one_move3() { move_Process(2,5,1,1); }
// one_move4,5,6 메소드는 아래에서 윗 방향으로 ...
private void one_move4() {
one_move5();
one_move6();
}
private void one_move5() { move_Process(4,2,2,1); }
private void one_move6() { move_Process(2,0,2,1); }
// one_moveX()와 같다.. 왼쪽에서 2번째 위치한 패킷 움직임을 지정하기 위한 메소드
private void two_move1() { // 위에서 아래로
two_move2();
two_move3();
}
private void two_move2() { move_Process(0,3,1,2); }
private void two_move3() { move_Process(2,5,1,2); }
// 아래에서 위로...
private void two_move4() {
two_move5();
two_move6();
}
private void two_move5() { move_Process(4,2,2,2); }
private void two_move6() { move_Process(2,0,2,2); }
// thd_move1() 오른쪽에서 2번째 위치한 수직 패킷 이동 처리용 메소드
private void thd_move1() { // 위에서 아래로 내려가는 처리뿐이다.
thd_move2();
thd_move3();
}
private void thd_move2() { move_Process(0,3,1,3); }
private void thd_move3() { move_Process(2,5,1,3); }
// 아래에서 위로 올라가는 처리만
private void thd_move4() {
thd_move5();
thd_move6();
}
private void thd_move5() { move_Process(4,2,2,3); }
private void thd_move6() { move_Process(2,0,2,3); }
// 맨 오른쪽 수직 패킷 이동 처리를 위한 메소드
// 1~3번까지는 위에서 아래로
// 4~6번은 아래에서 위로 처리 한다.
private void fth_move1() {
fth_move2();
fth_move3();
}
private void fth_move2() { move_Process(0,3,1,4); }
private void fth_move3() { move_Process(2,5,1,4); }
private void fth_move4() {
fth_move5();
fth_move6();
}
private void fth_move5() { move_Process(4,2,2,4); }
private void fth_move6() { move_Process(2,0,2,4); }
/**
* move_Process()는 애니메이션 효과의 핵심 부분으로 효과를 담당
* 총 5개의 parameter가 있는데 array_num에 해당하는 array의 start 번지부터
* stop 번지까지 type에 따라 효과를 보여준다.
* @param start 배열의 시작 번지
* @param stop 배열의 마지막 번지
* @param type 효과의 진행 방향 1은 왼쪽->오른쪽, 2는 오른쪽->왼쪽
* array 가 center를 제외한 나머지의 경우 1은 위->아래, 2는 아래->위 이다.
* @param array_num 해당 배열
*/
private void move_Process(int start, int stop, int type, int array_num) {
int array[][] = null;
switch(array_num) {
case 1: { array = one_XY; } break;
case 2: { array = two_XY; } break;
case 3: { array = thd_XY; } break;
case 4: { array = fth_XY; } break;
case 5: { array = center_XY; } break;
}
if(type == 1) {
for (int i = start; i < stop; i++) {
g.setColor(Color.GRAY);
g.fillRect(array[i][0], array[i][1], 19, 19);
if (i > 0) {
g.setColor(Color.WHITE);
g.fillRect(array[i - 1][0], array[i - 1][1], 19, 19);
}
try {
Thread.sleep(150);
} catch (InterruptedException ex) {}
}
g.setColor(Color.WHITE);
g.fillRect(array[stop - 1][0], array[stop - 1][1], 19, 19);
} else {
for (int i = start; i > (stop-1); i--) {
g.setColor(Color.GRAY);
g.fillRect(array[i][0], array[i][1], 19, 19);
if(array_num != 5) {
if(i < 4) {
g.setColor(Color.WHITE);
g.fillRect(array[i + 1][0], array[i + 1][1], 19, 19);
}
} else {
if(i < 16) {
g.setColor(Color.WHITE);
g.fillRect(array[i + 1][0], array[i + 1][1], 19, 19);
}
}
try {
Thread.sleep(150);
} catch (InterruptedException ex) {}
}
g.setColor(Color.WHITE);
g.fillRect(array[stop][0], array[stop][1], 19, 19);
}
}
/**
* uniCasting() 기능은 process to process로 패킷이 이동하는걸 보여주기 위해
* 경우의 수에 따른 이동경로를 지정해 준 메소드로
* start와 stop process를 지정해 주면 해당 경우에 따라 패킷이 이동한다.
* @param start 시작 process의 번호
* @param stop 도착 지점의 process의 번호
*/
public void uniCasting(int start, int stop) {
if(start == 1) {
one_move2();
if (stop == 2 || stop == 6) {
run_case2();
if(stop == 2) two_move6();
else two_move3();
} else if(stop == 3 || stop == 7) {
run_case2(); run_case3();
if(stop == 3) thd_move6();
else thd_move3();
} else if(stop == 4 || stop == 8) {
run_case1();
if(stop == 4) fth_move6();
else fth_move3();
} else if(stop == 5) {
one_move3();
}
} else if(start == 2) {
two_move2();
if (stop == 3 || stop == 7) {
run_case3();
if(stop == 3) thd_move6();
else thd_move3();
} else if(stop == 4 || stop == 8) {
run_case3(); run_case4();
if(stop == 4) fth_move6();
else fth_move3();
} else if(stop == 1 || stop == 5) {
run_case8();
if(stop == 1) one_move6();
else one_move3();
} else if(stop == 6) {
two_move3();
}
} else if(start == 3) {
thd_move2();
if(stop == 1 || stop == 5) {
run_case7(); run_case8();
if(stop == 1) one_move6();
else one_move3();
} else if (stop == 2 || stop == 6) {
run_case7();
if(stop == 2) two_move6();
else two_move3();
} else if(stop == 4 || stop == 8) {
run_case4();
if(stop == 4) fth_move6();
else fth_move3();
} else if(stop == 7) {
thd_move3();
}
} else if(start == 4) {
fth_move2();
if(stop == 8) {
fth_move3();
} else if(stop == 3 || stop == 7) {
run_case6();
if(stop == 3) thd_move6();
else thd_move3();
} else if(stop == 2 || stop == 6) {
run_case6(); run_case7();
if(stop == 2) two_move6();
else two_move3();
} else if(stop == 1 || stop == 5) {
run_case5();
if(stop == 1) one_move6();
else one_move3();
}
} else if(start == 5) {
one_move5();
if(stop == 1) {
one_move6();
} else if(stop == 2 || stop == 6) {
run_case2();
if(stop == 2) two_move6();
else two_move3();
} else if(stop == 3 || stop == 7) {
run_case2(); run_case3();
if(stop == 3) thd_move6();
else thd_move3();
} else if(stop == 4 || stop == 8) {
run_case1();
if(stop == 4) fth_move6();
else fth_move3();
}
} else if(start == 6) {
two_move5();
if (stop == 3 || stop == 7) {
run_case3();
if(stop == 3) thd_move6();
else thd_move3();
} else if(stop == 4 || stop == 8) {
run_case3(); run_case4();
if(stop == 4) fth_move6();
else fth_move3();
} else if(stop == 1 || stop == 5) {
run_case8();
if(stop == 1) one_move6();
else one_move3();
} else if(stop == 2) {
two_move6();
}
} else if(start == 7) {
thd_move5();
if(stop == 1 || stop == 5) {
run_case7(); run_case8();
if(stop == 1) one_move6();
else one_move3();
} else if (stop == 2 || stop == 6) {
run_case7();
if(stop == 2) two_move6();
else two_move3();
} else if(stop == 4 || stop == 8) {
run_case4();
if(stop == 4) fth_move6();
else fth_move3();
} else if(stop == 3) {
thd_move6();
}
} else if(start == 8) {
fth_move5();
if(stop == 4) {
fth_move6();
} else if(stop == 3 || stop == 7) {
run_case6();
if(stop == 3) thd_move6();
else thd_move3();
} else if(stop == 2 || stop == 6) {
run_case6(); run_case7();
if(stop == 2) two_move6();
else two_move3();
} else if(stop == 1 || stop == 5) {
run_case5();
if(stop == 1) one_move6();
else one_move3();
}
}
} // end of unicasting
/**
* inner class 1, 직접 소켓으로 이동한다.
*/
class Network2 implements Runnable {
ServerSocket ss = null;
Thread th = null;
Vector globalvc = new Vector(); // Client정보를 저장하기 위한 벡터 Object
Network2() { //Network 클래스의 생성자
try {
ss = new ServerSocket(7728);
} catch(Exception ex) {}
}
// 네트워크 서버 가동
public void servStart() {
th = new Thread(this);
th.start();
System.out.println("server Start");
}
public void run() {
while(!th.isInterrupted()) {
try {
System.out.println("thread 가동중...");
Socket s = ss.accept();
System.out.println(s);
Service sv = new Service(s);
sv.start();
} catch(IOException ex) {}
}
} // end of Run()
/**
* Network 에서 서버에세 메세지를 처리 하기 위한 서비스 클래스
*/
class Service extends Thread {
Socket s;
String ip = "127.0.0.1";
String mac = "abse2c2ro1ce";
BufferedReader in; // 값을 받아 오기 위해
OutputStream out; // 값을 보내 주기 위해
Service(Socket s) { // 생성자 생성
try {
System.out.println("Service 객체 생성");
this.s = s;
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = s.getOutputStream();
} catch(Exception ex) {}
} // end of Service
public void run() {
while(true) {
System.out.println("Service의 Thread 가동중...");
try {
String msg = in.readLine();
if(msg == null) return;
System.out.println("client : " + msg);
StringTokenizer st = new StringTokenizer(msg,"|");
int prot = Integer.parseInt(st.nextToken());
switch(prot) {
case 100: { // 접속
ip = st.nextToken();
mac = st.nextToken();
globalvc.addElement(this);
}break;
case 200: { // request
String myMac = st.nextToken(); // 요청자의 mac주소
String myIP = st.nextToken(); // 요청자의 ip주소
String youMac = st.nextToken();
String youIp = st.nextToken(); // mac을 원하는 ip주소
for(int i=0;i<8;i++) {
if(myIP.equals(log_hard[i][0])) {
show_All(i+1);
}
}
try {
outMessageAll("200" + "|" // 메세지 전달
+ myMac + "|"
+ myIP + "|"
+ youMac + "|"
+ youIp);
} catch(Exception ex) {}
} break;
case 300: { // response
String seMac = st.nextToken();
String seIp = st.nextToken();
String tarMac = st.nextToken();
String tarIp = st.nextToken();
for(int i=0;i Service sv = (Service)globalvc.elementAt(i);
if(sv.ip.equals(tarIp)) {
find_item(seIp,tarIp);
sv.outMessageTo("300|" +
seMac + "|" +
seIp + "|" +
tarMac + "|" +
tarIp);
//t//able_up(seIp,seMac,find_num(seIp));
break;
}
}
} break;
case 400: {
}break;
}
} catch(Exception ex) {
break;
}
}
} // end of run()
public int find_num(String ip) {
int tem = 0;
for(int i=0;i<8;i++) {
if(ip.equals(log_hard[i][0])) tem = i;
}
return tem;
}
private void find_item(String one, String two) {
int on1 = 0, tw2 = 0;
System.out.println("find_item");
for(int i=0;i<8;i++) {
if(one.equals(log_hard[i][0])) on1 = i+1;
if(two.equals(log_hard[i][0])) tw2 = i+1;
}
if((on1 != tw2) && (on1 != 0) && (tw2 != 0))
uniCasting(on1,tw2);
}
// 연결된 Client들에게 모두 메세지를 전송할때...
protected synchronized void outMessageAll(String msg) {
for(int i=0; i Service sv = (Service)globalvc.elementAt(i);
try {
sv.outMessageTo(msg);
} catch(Exception ex) {
globalvc.removeElementAt(i--);
}
}
} // end of putMessageAll
// 연결된 Client중 특정 Client에만 메세지를 전송할때...
protected synchronized void outMessageTo(String msg) throws Exception {
System.out.println("\nServer Out(outMessageTo) : " + msg);
try {
out.write((msg + "\r\n").getBytes());
} catch(Exception ex) {}
} // end of putMessageTo
}
} // end of network2
//////////////////////////////////////////////////////////////////////////////////
/** one_1 innerClass
* One_1 innerClass 로 Runnable을 implements함
* 여기서 하는일은 가상 c/s환경중 Client 환경을 제공함
*/
class One_1 implements Runnable {
Socket s = null; // C/S 통신용 소켓 선언
BufferedReader in; // socket으로 입력을 받기위한 객체
OutputStream out; // socket으로 출력하기 위한 객체
String myIp = "245.123.123.123";
String myMac = "ad42cb21ff1e";
int myNum = 0; // 내 번호
public One_1() { }
/**
* 자기 자신의 Num이 몇번인지 설정하기 위한 메소드
* @param my num값을 받아온다.
*/
public void set_Num(int my) {
myNum = my;
}
/**
* 새로 protocol Address를 추가할때 쓰이는 메소드
* @param pt pt is Protocol Address
*/
public void add_item(String pt) {
System.out.println("call add_item");
add_item("P",0, 0, 0, pt, "");
}
/**
* add_item의 오버로딩된 메소드로 총 6개의 값을 받아와 Table에 새로 추가한다.
* @param st state 정보값
* @param que queue의 값
* @param atem attemp의 값
* @param ti time-out의 값
* @param pt protocol address의 값
* @param hd hardware address의 값
*/
public void add_item(String st, int que, int atem, int ti, String pt, String hd) {
System.out.println("call add_item2");
ta[myNum].addRow(st,String.valueOf(que),String.valueOf(atem),String.valueOf(ti),pt,hd);
}
/**
* 서버에 접속하기 위한 메소드
* @param ip Protocol Address
* @param mac Physical Address
*/
public void connProcess(String ip, String mac) {
try {
s = new Socket("localhost", 7728);
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = s.getOutputStream();
myIp = ip;
myMac = mac;
out.write( ("100" + "|" + myIp + "|" + myMac + "\n").getBytes());
new Thread(this).start();
} catch (Exception ex) {}
}
/**
* 내가 다른 터미널에 mac을 요청할경우
* @param endIP Target IP
*/
public void sendProcess(String endIP) {
if(myIp.equals(endIP)) {
} else {
System.out.println("다른 터미널에게 mac addr. 요청...");
try {
out.write( ("200|" + myMac + "|" + myIp + "|not|" + endIP + "\n").
getBytes());
}
catch (IOException ex) {}
add_item(endIP);
System.out.println("mynum is : " + myNum);
}
}
/**
* run() One_1 class의 Thread 처리 메소드
* ARP를 요청 할경우 상대방에게 내 MAC 정보를 넘겨 준다.
* 내가 ARP를 요청 했을때 반환되서 돌아오는 MAC정보를 받아 Table을 update를 시킨다.
*/
public void run() {
while(true) {
try {
String msg = in.readLine();
if(msg == null) return;
System.out.println("client : " + msg);
StringTokenizer st = new StringTokenizer(msg,"|");
int prot = Integer.parseInt(st.nextToken());
switch(prot) {
case 200 : {
String one_mac = st.nextToken(); // 요청한 유저의 mac
String one_ip = st.nextToken(); // 요청한 유저의 주소
String two_mac = st.nextToken(); // 메세지 보낸 위치 물리적 주소
String two_ip = st.nextToken(); // 메세지 보낸 위치 주소
if(two_ip.equals(myIp)) {
try {
out.write(("300|" + myMac + "|" + myIp + "|" + one_mac
+ "|" + one_ip + "\n").getBytes());
} catch(IOException ex) {}
}
}break;
case 300 : {
String one_mac = st.nextToken(); // 요청한 유저의 mac
String one_ip = st.nextToken(); // 요청한 유저의 주소
String two_mac = st.nextToken(); // 메세지 보낸 위치 물리적 주소
String two_ip = st.nextToken(); // 메세지 보낸 위치 주소
ta[myNum].updateRow("R","1",one_ip,one_mac);
System.out.println("this num is : " + myNum);
} break;
}
} catch(Exception ex) {
break;
}
}
}
} // end of Client 클래스
} // end of main class