채팅 프로그램
1) java 패키지명.ChatClient 닉네임 [enter]
- 서버에 접속을 한다.
2) 접속한 모든 사용자에게 "홍길동님이 접속하였습니다."
3) 채팅을 입력한 후 [enter]를 입력하면 모든 사용자(나 포함)에게 내 메세지가 전달되면 좋겠다.
4) /quit을 입력하면 연결이 끊어진다. 연결이 끊어질 때, 모든 사용자에게 "홍길동님이 연결을 끊었습니다."
5) 강제로 연결을 끊었을 때, (ex>프로그램 강제종료) 사용자에게 "홍길동님이 연결을 끊었습니다."
public class ChatThread extends Thread{
List<ChatThread> list;
}
public class ChatThread extends Thread{
List<ChatThread> list;
~~~
}
public ChatThread(Socket socket, List<ChatThread> list) throws Exception{
this.list = list;
this.list.add(this);
}
package chat2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.List;
public class ChatThread extends Thread {
private String name;
private BufferedReader br;
private PrintWriter pw;
private Socket socket;
List<ChatThread> list;
public ChatThread(Socket socket, List<ChatThread> list)throws Exception{
this.socket = socket;
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
this.br = br;
this.pw = pw;
this.name = br.readLine();
this.list = list;
this.list.add(this);
}
}
package chat2;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
}
}
package chat2;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ChatServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
// 동시성 문제를 해결하기 위해서..!
List<ChatThread> list = Collections.synchronizedList(new ArrayList<>());
while(true) {
Socket socket = serverSocket.accept();
ChatThread chatThread = new ChatThread(socket, list);
chatThread.start();
}
}
}
package chat2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.out.println("사용법 : java com.example.chat2.ChatClient 닉네임");
return;
}
String name = args[0];
Socket socket = new Socket("127.0.0.1", 8888);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
// 닉네임 전송
pw.println(name);
pw.flush();
}
}
class InputThread extends Thread{
BufferedReader br;
public InputThread(BufferedReader br){
this.br = br;
}
@Override
public void run(){
try{
String line = null;
while((line = br.readLine()) != null{
System.out.println(line);
}
}catch(Exception ex){
// 의미 없는 출력
System.out.println("....");
}
}
}
InputThread inputThread = new InputThread(br);
inputThread.start();
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
try{
String line = null;
while((line = br.readLine()) != null){
if("/quit".equals(line))
break;
pw.println(line);
pw.flush();
}
}catch(Exception ex){
System.out.println("....");
}
socket.close();
run() 메소드는 다음과 같은 특징을 갖는다.
List<ChatThread> list;
list에 현재 접속한 ChatThread가 들어가 있다.
public void sendMessage(String msg){
pw.println(msg);
pw.flush();
}
broadcast메소드는 접속된 모든 클라이언트에게 메세지를 보내는 메소드
private void broadcast(String msg, boolean includeMe){
List<ChatThread> chatThreads = new ArrayList<>();
for(int i=0;i<this.list.size();i++){
chatThreads.add(list.get(i));
}
try{
for(int i=0;i<chatThreads.size();i++){
ChatThread ct = chatThreads.get(i);
if(!includeMe){ // 나를 포함하고 있지 말아라.
if(ct == this){
continue;
}
}
ct.sendMessage(msg);
}
}catch(Exception ex) {
System.out.println("///");
}
}
package chat2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
public static void main(String[] args) throws Exception {
if(args.length != 1){
System.out.println("사용법 : java com.example.chat2.ChatClient 닉네임");
return;
}
String name = args[0];
Socket socket = new Socket("127.0.0.1", 8888);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
// 닉네임 전송
pw.println(name);
pw.flush();
// 백그라운드로 서버가 보내준 메세지를 읽여들여서 화면에 출력한다.
InputThread inputThread = new InputThread(br);
inputThread.start();
// 클라이언트는 읽어들인 메세지를 서버에 전송한다.
try{
String line = null;
while((line = keyboard.readLine()) != null) {
if("/quit".equals(line)) {
pw.println("/quit");
pw.flush();
break;
}
pw.println(line);
pw.flush();
}
}catch(Exception ex){
System.out.println("...");
}
try{
br.close();
}catch(Exception ex){
System.out.println("111");
}
try{
pw.close();
}catch(Exception ex){
System.out.println("222");
}
try{
System.out.println("socket close!!");
socket.close();
}catch(Exception ex){
System.out.println("333");
}
}
}
class InputThread extends Thread {
BufferedReader br;
public InputThread(BufferedReader br){
this.br = br;
}
@Override
public void run() {
try{
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
}catch(Exception ex){
System.out.println("...");
}
}
}
package chat2;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ChatServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
// 동시성 문제를 해결하기 위해서..!
List<ChatThread> list = Collections.synchronizedList(new ArrayList<>());
while(true) {
Socket socket = serverSocket.accept();
ChatThread chatThread = new ChatThread(socket, list);
chatThread.start();
}
}
}
package chat2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ChatThread extends Thread {
private String name;
private BufferedReader br;
private PrintWriter pw;
private Socket socket;
List<ChatThread> list;
public ChatThread(Socket socket, List<ChatThread> list)throws Exception {
this.socket =socket;
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
this.br = br;
this.pw = pw;
this.name = br.readLine();
this.list = list;
this.list.add(this);
}
public void sendMessage(String msg){
pw.println(msg);
pw.flush();
}
@Override
public void run() {
// ChatThread는 사용자가 보낸 메세지를 읽어들여서,
// 접속된 모든 클라이언트에게 메세지를 보낸다.
// 나를 제외한 모든 사용자에게 "00님이 연결되었습니다"..
try{
broadcast(name + "님이 연결되었습니다.", false);
String line = null;
while((line = br.readLine()) != null){
broadcast(name + " : " + line,true);
}
}catch(Exception ex){
// ChatThread가 연결이 끊어졌다는 것.
broadcast(name + "님이 연결이 끊어졌습니다.", false);
this.list.remove(this);
}
}
private void broadcast(String msg, boolean includeMe){
List<ChatThread> chatThreads = new ArrayList<>();
for(int i=0;i<this.list.size();i++){
chatThreads.add(list.get(i));
}
try{
for(int i=0;i<chatThreads.size();i++){
ChatThread ct = chatThreads.get(i);
if(!includeMe){ // 나를 포함하고 있지 말아라.
if(ct == this){
continue;
}
}
ct.sendMessage(msg);
}
}catch(Exception ex) {
System.out.println("///");
}
}
}
quit을 입력할시에, ~~가 접속을 종료했습니다. 메세지가 뜨지 않는다. 무엇이 잘못 되었을까?
@Override
public void run() {
// ChatThread는 사용자가 보낸 메세지를 읽어들여서,
// 접속된 모든 클라이언트에게 메세지를 보낸다.
// 나를 제외한 모든 사용자에게 "00님이 연결되었습니다"..
try{
broadcast(name + "님이 연결되었습니다.", false);
String line = null;
while((line = br.readLine()) != null){
if("/quit".equals(line)){
break;
}
broadcast(name + " : " + line,true);
}
}catch(Exception ex){
// ChatThread가 연결이 끊어졌다는 것.
ex.printStackTrace();
}
finally{
broadcast(name + "님이 연결이 끊어졌습니다.", false);
this.list.remove(this);
try{
br.close();
}catch(Exception ex){
}
try{
pw.close();
}catch(Exception ex){
}
try{
socket.close();
}catch(Exception ex){
}
}
}
클라이언트가 /quit
를 입력했을 때, while문을 빠져나가서 예외를 발생하지 않아 catch부분에 걸리지 않는다.
따라서 연결이 끊어졌다는 코드는 try부분이 끝나고 실행되는 finally 부분에 코드를 넣어야 한다.
finally{
broadcast(name + "님이 연결이 끊어졌습니다.", false);
this.list.remove(this);
try{
br.close();
}catch(Exception ex){
}
try{
pw.close();
}catch(Exception ex){
}
try{
socket.close();
}catch(Exception ex){
}
}
}
package chat2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ChatThread extends Thread {
private String name;
private BufferedReader br;
private PrintWriter pw;
private Socket socket;
List<ChatThread> list;
public ChatThread(Socket socket, List<ChatThread> list)throws Exception {
this.socket =socket;
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
this.br = br;
this.pw = pw;
this.name = br.readLine();
this.list = list;
this.list.add(this);
}
public void sendMessage(String msg){
pw.println(msg);
pw.flush();
}
@Override
public void run() {
// ChatThread는 사용자가 보낸 메세지를 읽어들여서,
// 접속된 모든 클라이언트에게 메세지를 보낸다.
// 나를 제외한 모든 사용자에게 "00님이 연결되었습니다"..
try{
broadcast(name + "님이 연결되었습니다.", false);
String line = null;
while((line = br.readLine()) != null){
if("/quit".equals(line)){
break;
}
broadcast(name + " : " + line,true);
}
}catch(Exception ex){
// ChatThread가 연결이 끊어졌다는 것.
//ex.printStackTrace();
broadcast(name + "님이 연결이 끊어졌습니다.", false);
this.list.remove(this);
}
}
private void broadcast(String msg, boolean includeMe){
List<ChatThread> chatThreads = new ArrayList<>();
for(int i=0;i<this.list.size();i++){
chatThreads.add(list.get(i));
}
try{
for(int i=0;i<chatThreads.size();i++){
ChatThread ct = chatThreads.get(i);
if(!includeMe){ // 나를 포함하고 있지 말아라.
if(ct == this){
continue;
}
}
ct.sendMessage(msg);
}
}catch(Exception ex) {
System.out.println("///");
}
}
}
package chat2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ChatThread extends Thread {
private String name;
private BufferedReader br;
private PrintWriter pw;
private Socket socket;
List<ChatThread> list;
public ChatThread(Socket socket, List<ChatThread> list)throws Exception {
this.socket =socket;
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
this.br = br;
this.pw = pw;
this.name = br.readLine();
this.list = list;
this.list.add(this);
}
public void sendMessage(String msg){
pw.println(msg);
pw.flush();
}
@Override
public void run() {
// ChatThread는 사용자가 보낸 메세지를 읽어들여서,
// 접속된 모든 클라이언트에게 메세지를 보낸다.
// 나를 제외한 모든 사용자에게 "00님이 연결되었습니다"..
try{
broadcast(name + "님이 연결되었습니다.", false);
String line = null;
while((line = br.readLine()) != null){
if("/quit".equals(line)){
break;
}
broadcast(name + " : " + line,true);
}
}catch(Exception ex){
// ChatThread가 연결이 끊어졌다는 것.
ex.printStackTrace();
}
finally{
broadcast(name + "님이 연결이 끊어졌습니다.", false);
this.list.remove(this);
try{
br.close();
}catch(Exception ex){
}
try{
pw.close();
}catch(Exception ex){
}
try{
socket.close();
}catch(Exception ex){
}
}
}
private void broadcast(String msg, boolean includeMe){
List<ChatThread> chatThreads = new ArrayList<>();
for(int i=0;i<this.list.size();i++){
chatThreads.add(list.get(i));
}
try{
for(int i=0;i<chatThreads.size();i++){
ChatThread ct = chatThreads.get(i);
if(!includeMe){ // 나를 포함하고 있지 말아라.
if(ct == this){
continue;
}
}
ct.sendMessage(msg);
}
}catch(Exception ex) {
System.out.println("///");
}
}
}
package chat2;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ChatServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
// 동시성 문제를 해결하기 위해서..!
List<ChatThread> list = Collections.synchronizedList(new ArrayList<>());
while(true) {
Socket socket = serverSocket.accept();
ChatThread chatThread = new ChatThread(socket, list);
chatThread.start();
}
}
}
package chat2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
public static void main(String[] args) throws Exception {
if(args.length != 1){
System.out.println("사용법 : java com.example.chat2.ChatClient 닉네임");
return;
}
String name = args[0];
Socket socket = new Socket("127.0.0.1", 8888);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
// 닉네임 전송
pw.println(name);
pw.flush();
// 백그라운드로 서버가 보내준 메세지를 읽여들여서 화면에 출력한다.
InputThread inputThread = new InputThread(br);
inputThread.start();
// 클라이언트는 읽어들인 메세지를 서버에 전송한다.
try{
String line = null;
while((line = keyboard.readLine()) != null) {
if("/quit".equals(line)) {
pw.println("/quit");
pw.flush();
break;
}
pw.println(line);
pw.flush();
}
}catch(Exception ex){
System.out.println("...");
}
try{
br.close();
}catch(Exception ex){
System.out.println("111");
}
try{
pw.close();
}catch(Exception ex){
System.out.println("222");
}
try{
System.out.println("socket close!!");
socket.close();
}catch(Exception ex){
System.out.println("333");
}
}
}
class InputThread extends Thread {
BufferedReader br;
public InputThread(BufferedReader br){
this.br = br;
}
@Override
public void run() {
try{
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
}catch(Exception ex){
System.out.println("...");
}
}
}