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() + "\n");
}
}// 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) + "\n");
// ; 수신데이터는 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() + "\n"); // 나가는 데이터를 나타내기 위해 >>
/* 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() + "\n" );
}// 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