본문 바로가기

JAVA/기초 프로그래밍

ID입력받아 채팅창에서 채팅하기

Server

package main;
import thread.ServerThread;

public class mainClass {
	public static void main(String[] args) {
		Socket clientsocket = null;
		
		List<Socket> list = new ArrayList<Socket>();
		
		try {
			// 문지기 소켓
			// 192.168.7.66			
			ServerSocket serSocket = new ServerSocket(9000);
			// IP, Port 설정 
			// binding(적용)
			// listen
			while(true) {
			
				// client를 기다림
				System.out.println("접속 대기중...");
				clientsocket = serSocket.accept();
				
				list.add(clientsocket);
				
				System.out.println("client IP:" + clientsocket.getInetAddress() 
									+ " Port:" + clientsocket.getPort());				
				
				new ServerThread(clientsocket, list).start();
				
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
package thread;

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 clientsocket;
	List<Socket> list;
	
	public ServerThread(Socket clientsocket, List<Socket> list) {
		this.clientsocket = clientsocket;	// 자기 자신의 Socket
		this.list = list;					// Socket의 묶음
	}

	@Override
	public void run() {		
		super.run();
		
		try {
			
			while(true) {
		
				BufferedReader reader 
					= new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
				String packetStr = reader.readLine();	// 실제 수신	
				
				System.out.println("클라이언트로부터 패킷:" + packetStr);
				
				// send (보내다)	
				for (int i = 0; i < list.size(); i++) {					
					Socket soc = list.get(i);
					if(clientsocket != soc) {
						PrintWriter writer = new PrintWriter(soc.getOutputStream());
						writer.println(packetStr);		// 실제 송신
						writer.flush();
					}
				}
				Thread.sleep(100);
			}
		
		}catch (Exception e) {
			System.out.println("연결이 끊긴 IP:" + clientsocket.getInetAddress());
			
			list.remove(clientsocket);
			
			// 남은 client 확인
			for (Socket s : list) {
				System.out.println("접속되어 있는 IP:" + s.getInetAddress() + " Port:" + s.getPort());				
			}
			
			try {
				clientsocket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}			
		}
	}
}

 


 

Client

package main;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import net.ReadThread;
import view.ClientFrame;
import view.Id;

public class mainClass {
	public static void main(String[] args) {
		
		try {
			Socket socket = new Socket("192.168.7.40", 9000);
			System.out.println("Connection Success!");
			
			ClientFrame cf = new ClientFrame(socket);
			
			new ReadThread(socket, cf).start();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

ReadThread

package net;
public class ReadThread extends Thread {
	Socket socket;
	ClientFrame cf;
	
	public ReadThread(Socket socket, ClientFrame cf) {
		this.socket = socket;
		this.cf = cf;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		
		try {
			while(true) {
				BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				String str = br.readLine();
				if(str == null) {
					System.out.println("접속 끊김");
				}
				cf.textA.append(str + "\n");
				Thread.sleep(300);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

WriteClass

package net;

public class WriteClass {
	Socket socket;
	ClientFrame cf;
	
	String id;
	String msg;	

	public WriteClass(ClientFrame cf) {
		this.cf = cf;
		this.socket = cf.socket;
	}
	
	public void sendMessage() {
		try {
			PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
			
			// 첫번째 전송 -> id
			if(cf.isFirst == true) {
				InetAddress iaddr = socket.getLocalAddress();
				String ip = iaddr.getHostAddress();		// xxx.xxx.xxx.xxx
				id = Id.tf.getText();
				
				msg = "[" + id + "]님 로그인(" + ip + ")";
				
				cf.setTitle("접속자 ID:" + id);	// 타이틀 바에 ID 출력					
			}			
			// 그 다음부터 전송
			else {
				msg = "[" + id + "]" + cf.textF.getText();				
			}
			pw.println( msg );
			pw.flush();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

ClientFrame 

package view;
public class ClientFrame extends JFrame implements WindowListener, ActionListener {

	public Socket socket;
	WriteClass wc;	// 전송 클래스
	
	public JTextField textF = new JTextField(14);
	public JTextArea textA = new JTextArea();
	
	JButton btnTransfer = new JButton("send");
	JButton btnExit = new JButton("exit");
	
	JPanel panel = new JPanel();
	
	public boolean isFirst = true;	// 첫 전송을 판정 -> id
	
	public ClientFrame(Socket socket) {
		super("chatting");
		
		
		this.socket = socket;
		
		wc = new WriteClass(this);	// 전송 클래스 생성
		
		new Id(wc, this);
		
		JScrollPane scrPane = new JScrollPane(textA);
		scrPane.setPreferredSize(new Dimension(200, 120));
		
		add("Center", scrPane);
		
		panel.add(textF);
		panel.add(btnTransfer);
		panel.add(btnExit);
		
		add("South", panel);
		
		btnTransfer.addActionListener(this);
		btnExit.addActionListener(this);
		
		setBounds(200, 200, 450, 600);
		setVisible(false);	
		
		addWindowListener(this);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		Object obj = e.getSource();
		
		if(obj == btnTransfer) {
			
			if(textF.getText().trim().equals("")) return;
			
			String id = Id.tf.getText();
			
			// TextArea 문자열 작성해서 추가
			textA.append("[" + id + "]" + textF.getText() + "\n");
			
			// server로 전송
			wc.sendMessage();
			
			textF.setText("");
		}
		else if(obj == btnExit) {
		}
	}
	@Override
	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub
	}
	@Override
	public void windowClosing(WindowEvent e) {
		// TODO Auto-generated method stub
		System.exit(0);		
	}
	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
	}
	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub
	}
	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub
	}
	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub
	}
	@Override
	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub
	}
}

package view;
// ID를 입력하기 위한 Form

package view;
// ID를 입력하기 위한 Form
public class Id extends JFrame implements ActionListener{

	public static TextField tf = new TextField(8);
	Button btn = new Button("input");
	
	WriteClass wc;
	ClientFrame cf;
	
	public Id(WriteClass wc, ClientFrame cf) {
		
		this.wc = wc;
		this.cf = cf;
		
		setTitle("ID input");
		setLayout(null);
		
		Label label = new Label("id:");
		label.setBounds(50, 60, 30, 30);
		add(label);
		
		tf.setBounds(80, 60, 100, 30);
		add(tf);
		
		btn.setBounds(80, 110, 100, 30);
		btn.addActionListener(this);
		add(btn);
		
		setBounds(300, 300, 250, 200);
		setBackground(Color.green);
		setVisible(true);		
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		
		wc.sendMessage();	// ID 전송
		
		cf.isFirst = false;		// 첫번째 전송이 끝났음
		cf.setVisible(true);	// 채팅창을 활성화
		
		this.dispose();		
	}
}