본문 바로가기

Java/java 기초

awt 로 채팅 프로그램 구현하기

서버 부분

 

서버 쓰레드 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.List;

public class ServerThread extends Thread {

	Socket socket;
	List<Socket> list;

	public ServerThread(Socket socket, List<Socket> list) {
		this.socket = socket;
		this.list = list;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		// 1. recv

		try {

			while (true) {
				BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

				String str = reader.readLine();

				System.out.println("클라이언트로 부터 받은 메시지 " + str);

				// 2. send
				
				for(Socket sock : list) {
					//담당자 소켓
					//본인을 제외하고 받고싶을때
					if(socket != sock) {
						PrintWriter writer = new PrintWriter(sock.getOutputStream());
						writer.println(str); // 실질적으로 전송
						writer.flush(); // 중요 끝맺음	
					}
				}
				Thread.sleep(300);
			}
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}catch (Exception e) {
//			e.printStackTrace();
			System.out.println("연결이 끊긴 IP: " + socket.getInetAddress());
			list.remove(socket);
		
			
			// 남은 클라이언트 확인
			for (Socket s : list) {
				System.out.println("접속 되어있는 IP:" + s.getInetAddress()
									+ " Port: "+ s.getPort());
			}
			
			try {
				socket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}

	}
}

 

메인파트 

 

 

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.ArrayList;
import java.util.List;

public class mainClass {
	public static void main(String[] args) {
		
		Socket clientSocket = null;

		try {

			// 문지기 소켓
			ServerSocket serverSocket = new ServerSocket(9000);
			// 자동으로 자신의 IP를 설정, binding, listen 포함
			
			List<Socket> list = new ArrayList<Socket>();
			
			while (true) {
				System.out.println("접속 대기중...");
				clientSocket = serverSocket.accept();
				
				list.add(clientSocket);
				
				// 담당자 소켓
				// 어떤 클라이언트의 IP
				System.out.println("client IP:" + clientSocket.getInetAddress() + "Port:" + clientSocket.getPort());

				// 1. recv
				// 문지기 소켓이 아니다
				BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

				new ServerThread(clientSocket, list).start();

			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

 

 

 

클라이언트 부분 

 

 

VIew 부분,  Controller 부분, main부분(실행), ReadTread(쓰레드 읽기), Singleton으로 나눠서 진행하였다.

import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ClientView extends JFrame {
	JLabel statusLabel;

	JTextArea area;

	JTextField textField;

	JButton sendBtn;

	public ClientView() {
		super("채팅 프로그램");
		setLayout(null);
		area = new JTextArea();
		area.setLineWrap(true);

		JScrollPane scrPane = new JScrollPane(area);

		scrPane.setPreferredSize(new Dimension(400, 300));

		textField = new JTextField();
		sendBtn = new JButton("전송");

		statusLabel = new JLabel("온라인 접속 상태");

		statusLabel.setBounds(20, 10, 200, 30);

		area.setBounds(80, 40, 300, 600);
		textField.setBounds(80, 700, 200, 40);
		sendBtn.setBounds(300, 700, 80, 40);

		add(scrPane);
		add(area);
		add(textField);
		add(sendBtn);

		setSize(1200, 800);
		setLocation(100, 0);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

}

 

 

단순한 뷰만 들어있는 java class  뷰의 관리는 싱글톤을 활용하여 하기로 하였다.

 

싱글톤 파트 

public class Singleton {
	private static Singleton s = null;
	
	ClientView client = new ClientView();	
	
	private Singleton() {
		
	}
	
	public static Singleton getInstance() {
		if(s == null) {
			s = new Singleton();
		}
		return s;
	}
	
}

 

뷰를 관리하기위해서 싱글톤 패턴을 생성하였다. 

 

ReadThread

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

public class ReadThread extends Thread {
	// 클라이언트단은 받기만 하면 된다.

	Socket socket;

	public ReadThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		super.run();
		while (true) {
			try {
				BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

				Singleton s = Singleton.getInstance();
				String str = reader.readLine();
				System.out.println("서버로 부터 받은 메시지 " + str);
				s.client.area.append(str + "\n");
//				s.client.area
				
				Thread.sleep(300);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

 

서버로부터 데이터를 수신받기 위해 만든 클래스 

서버로 부터 데이터를 받은걸 append를 통해 View에 값을 추가해준다.

 

 

 

ClientController

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;

public class ClientController {
	public ClientController() {
		InetSocketAddress sockAddress = new InetSocketAddress("192.168.2.5", 9000);

		Socket socket = new Socket();

		Singleton s = Singleton.getInstance();

		s.client.sendBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
//				JOptionPane.showConfirmDialog(null, "test");
				if (!s.client.textField.getText().equals("")) {
					PrintWriter writer;
					try {
						writer = new PrintWriter(socket.getOutputStream());
						System.out.println("전송 문자열: ");
						String msg = s.client.textField.getText() + "\n";
//						s.client.area.append(msg);
						writer.println(msg);
						writer.flush();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}

				}
			}
		});
		try {
			socket.connect(sockAddress, 10000);
			InetAddress inetAdddress;
			if ((inetAdddress = socket.getInetAddress()) != null) {
				s.client.textField.setText("서버 연결 성공 :" + inetAdddress);
			} else {
				s.client.textField.setText("서버 연결 실패");
			}
			new ReadThread(socket).start();

		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
}

 

뷰의 데이터를 조작하는 ClientController이다.

클릭시에 writer를 통해 서버에 데이터를 전송하도록 하였고 

쓰레드는 계속 돌면서 데이터가 올때 받는다.

 

메인클래스 (실행 파트)

public class mainClass {
	public static void main(String[] args) {
		new ClientController();

	}
}

 

결과창 

 

 

 

 

'Java > java 기초' 카테고리의 다른 글

쓰레드를 활용한 오브젝트 전송하기  (0) 2019.12.10
쓰레드 공부하기  (0) 2019.12.10
네트워크 공부  (0) 2019.12.09
awt - 이미지 올리기  (0) 2019.12.06
awt로 가위바위보 프로그램 만들기  (0) 2019.12.05