반응형

 

채팅 프로그램

 

 

- Sender

package kr.or.ddit.tcp;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class Sender extends Thread{
	private Scanner scan;
	private String name;
	private DataOutputStream dos;
	
	public Sender(Socket socket) {
		
		scan = new Scanner(System.in);
		
		name = "[" + socket.getLocalAddress() + " : " + socket.getLocalPort() + "]";
		
		try {
			dos = new DataOutputStream(socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		while(dos != null) {
			try {
				dos.writeUTF(name + " >>> " + scan.nextLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

- Receiver

package kr.or.ddit.tcp;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

public class Receiver extends Thread{
	private DataInputStream dis;
	
	public Receiver(Socket socket) {
		try {
			dis = new DataInputStream(socket.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		while(dis != null) {
			
			try {
				System.out.println(dis.readUTF());
				
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
}

 

-TcpChatServer

package kr.or.ddit.tcp;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpChatServer {
	public static void main(String[] args) {
		/*
		 * 서버 소켓을 만들고, 클라이언트가 접속하면 만들어진 소켓을 사용하여 클라이언트와 데이터를 주고 받는다.
		 */
		
		ServerSocket server = null;
		Socket socket = null;
		
		try {
			server = new ServerSocket(7777);
			System.out.println("채팅서버 대기 중...");
			socket = server.accept();
			
			System.out.println("클라이언트와 연결되었습니다.");
            
			Sender sender = new Sender(socket);
			sender.start();
			
			Receiver recv = new Receiver(socket);
			recv.start();
			
			
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
}

 

- TcpChatClient

package kr.or.ddit.tcp;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class TcpChatClient {
	public static void main(String[] args) throws IOException {
		
		// ip 변경해야 함
		Socket socket = new Socket("192.168.144.//", 7777);
		
		Sender send = new Sender(socket);
		send.start();
		
		Receiver recv = new Receiver(socket);
		recv.start();
		
		// socket.close(); 를 하면 안 됨.
	}
}

 

결과 화면1-1 : 다른 PC로 TcpChatSever 실행 후 자신의 PC로  TcpChatClient 실행하면 작동됨

 

결과 화면1-2 : 서버일때의 테스트

 

 

 

멀티 채팅 프로그램

 

package kr.or.ddit.tcp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MultiChatServer {
	// 대화명을 키, 해당 소켓을 값으로 하는 Map객체 변수 선언
	private Map<String, Socket> clients;
	
	public MultiChatServer() {
		clients = Collections.synchronizedMap(new HashMap<String, Socket>());
	}
	
	public void serverStart() {
		
		ServerSocket server = null;
		Socket socket = null;
		
		try {
			server = new ServerSocket(7777);
			System.out.println("서버가 시작되었습니다.");
			
			while(true) {
				// 클라이언트의 접속을 대기
				socket = server.accept();
				
				System.out.println("[" + socket.getInetAddress() + " : " 
									+ socket.getPort() + "] 에서 접속하였습니다.");
				
				// 사용자가 보내준 메시지를 받아서 처리하는 스레드 생성 및 실행
				ServerRecevier sr = new ServerRecevier(socket);
				sr.start();
			}
			
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	
	/**
	 * 대화방, 즉 Map에 저장된 모든 접속한 사람들에게 안내 메시지를 전송하기 위한 메서드
	 * @param msg 전송할 메시지
	 */
	public void sendMessage(String msg) {
		
		Iterator<String> it = clients.keySet().iterator();
		
		while(it.hasNext()) {
			try {
				String name = it.next(); //대화명
				
				// 해당 사용자에게 메시지 보내기..
				new DataOutputStream(
						clients.get(name).getOutputStream()).writeUTF(msg);
				
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
	
	/**
	 * 대화방, 즉 Map에 저장된 모든 접속한 사람들에게 채팅 메시지를 전송하기 위한 메서드
	 * @param msg 채팅 메시지
	 * @param from 메시지 보낸 대화명
	 */
	public void sendMessage(String msg, String from) {
		sendMessage("[" + from + "] " + msg);
	}
	
	/**
	 * 서버에서 클라이언트로부터 수신한 메세지를 처리하기 위한 클래스
	 * Inner클래스로 정의함.(Inner클래스에서는 부모클래스의 멤버들을 직접 접근할 수 있음)
	 * @author PC-10
	 *
	 */
	class ServerRecevier extends Thread{
		private Socket socket;
		private DataInputStream dis;
		private String name;
		
		public ServerRecevier(Socket socket) {
			this.socket = socket;
			
			try {
				dis = new DataInputStream(socket.getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		@Override
		public void run() {
			try {
				// 서버에서는 클라이언트가 보내온 최초의 메시지, 즉 대화명을 수신해야 한다.
				name = dis.readUTF();
				
				// 대화명을 받아서 다른 모든 클라이언트들에게 대화방 참여 메시지를 보낸다.
				sendMessage("#" + name + "님이 입장했습니다.");
				
				// 대화명을 사용하여 소켓객체를 Map에 저장한다.
				clients.put(name, socket);
				System.out.println("현재 서버 접속자 수는 " + clients.size() + "명 입니다.");

				// 이 이후의 처리는 반복문으로 처리한다.
				// 클라이언트가 보내온 메시지(대화내용)를 접속한 다른 모든 클라이언트
				while(dis != null) {
					sendMessage(dis.readUTF(), name);
				}
				
			} catch (IOException ex) {
				ex.printStackTrace();
			} finally {
				// 이 부분이 실행된다는 것은 클라이언트와의 접속에 문제가 생겼다는 의미이다.
				// 그래서 접속종료 처리를 한다.
				sendMessage(name + "님이 나가셨습니다.");
				
				// Map에서 해당 사용자를 삭제한다.
				clients.remove(name);
				
				System.out.println("[" + socket.getInetAddress() + " : " 
						+ socket.getPort() + "] 에서 종료하였습니다.");
				System.out.println("현재 서버 접속자 수는 " + clients.size() + "명 입니다.");
				
			}
		}
	}
	
//	public static void main(String[] args) {
//		new MultiChatServer().serverStart();
//	}
}

 

package kr.or.ddit.tcp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class MultiChatClient {
	
	public void start() {
		
		Socket socket = null;
		
		try {
			// IP 주소 변경해야 함
			socket = new Socket("192.168.144.//", 7777);
			
			System.out.println("멀티챗 서버에 접속했습니다...");
			
			// 송신용 스레드 생성 및 실행
			ClientSender sender = new ClientSender(socket);
			sender.start();
			
			// 수신용 스레드 생성 및 실행
			ClientReceiver receiver = new ClientReceiver(socket);
			receiver.start();

		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	
	// 메시지 전송을 위한 스레드 클래스
	class ClientSender extends Thread {
		private DataOutputStream dos;
		private Scanner scan;
		
		public ClientSender(Socket socket) {
			
			scan = new Scanner(System.in);
			
			try {
				dos = new DataOutputStream(socket.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		@Override
		public void run() {
			try {
				
				if(dos != null) {
					// 시작하자마자 자신의 대화명을 서버로 전송하기
					System.out.print("대화명 >>> ");
					dos.writeUTF(scan.nextLine());
				}
				
				while(dos != null) {
					// 이제부터는 일반 채팅 메시지 전송하기
					dos.writeUTF(scan.nextLine());
				}
				
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		
	}
	
	// 메시지 수신을 위한 스레드 클래스
	class ClientReceiver extends Thread {
		private DataInputStream dis;
		
		public ClientReceiver(Socket socket) {
			try {
				dis = new DataInputStream(socket.getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		@Override
		public void run() {
			while(dis != null) {
				try {
					// 서버로부터 받은 메시지 콘솔에 출력하기
					System.out.println(dis.readUTF());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args) {
		new MultiChatClient().start();
	}
}

 

 

 

채팅 파일 전송

 

 

package kr.or.ddit.tcp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpFileServer {
/*
 * 서버는 접속한 클라이언트가 요청한 파일이 있는지 확인 후 존재하면 해당 파일을 클라이언트에게 전송한다.
 */
	
	public void start() {
		ServerSocket server = null;
		
		try {
			
			server = new ServerSocket(7777);
			System.out.println("파일서버 준비 완료...");
			
			while(true) {
				Socket socket = server.accept();
				
				// 파일 전송 스레드 생성 및 실행
				FileSender sender = new FileSender(socket);
				sender.start();
			}
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	class FileSender extends Thread {
		private Socket socket;
		private FileInputStream fis;
		private DataInputStream dis;
		private DataOutputStream dos;
		
		public FileSender(Socket socket) {
			this.socket = socket;
			
			try {
				dis = new DataInputStream(socket.getInputStream());
				dos = new DataOutputStream(socket.getOutputStream());
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		
		@Override
		public void run() {
			BufferedInputStream bis = null;
			BufferedOutputStream bos = null;
			
			try {
				String downDir = "D:\\공유폴더\\WEB\\images";
				
				File file = new File(downDir + dis.readUTF());
				System.out.println("요청 파일 존재여부 체크 중...");
				
				if(!file.exists()) {
					System.out.println("요청 파일(" + file.getName() + ") 존재하지 않습니다.");
					dos.writeUTF("요청 파일(" + file.getName() + ") 존재하지 않습니다.");
				} else {
					dos.writeUTF("OK"); // 요청 파일 존재함을 알려줌...
					System.out.println("요청파일(" + file.getName() + ") 전송 시작...");
					
					fis = new FileInputStream(file);
					
					bis = new BufferedInputStream(fis);
					bos = new BufferedOutputStream(socket.getOutputStream());
					
					int data = 0;
					while((data = bis.read()) != -1) {
						bos.write(data);
					}
					
					System.out.println("요청파일(" + file.getName() + ") 전송 완료...");
				}
				
			} catch (IOException ex) {
				ex.printStackTrace();
			} finally {
				try {
					bis.close();
					bos.close();
					dis.close();
					dos.close();
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 

package kr.or.ddit.tcp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class TcpFileClient {
/*
 * 클라이언트는 서버에 접속하여 파일을 요청 후 서버가 보내주는 파일을 다운받는다.
 */
	
	private Socket socket;
	private FileOutputStream fos;
	private DataInputStream dis;
	private DataOutputStream dos;
	private Scanner scan;
	
	public TcpFileClient() {
		scan = new Scanner(System.in);
	}
	
	public void start() {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		
		try {
			// IP 변경 필요
			socket = new Socket("192.168.144.//", 7777);
			
			// 소켓 접속이 성공하면 받고 싶은 파일명을 전송한다.
			System.out.print("파일명 >>> ");
			String fileName = scan.next();
			
			dos = new DataOutputStream(socket.getOutputStream());
			dos.writeUTF(fileName);
			
			// 서버로부터 파일에 대한 결과를 받아온다.
			dis = new DataInputStream(socket.getInputStream());
			String resultMsg = dis.readUTF();
			
			if(resultMsg.equals("OK")) {
				
				File downDir = new File("d:/D_Other/down_files");
				
				if(!downDir.exists()) {
					downDir.mkdir();
				}
				
				System.out.println("파일 다운로드 시작...");
				
				File file = new File(downDir, fileName);
				
				fos = new FileOutputStream(file);
				
				bis = new BufferedInputStream(socket.getInputStream());
				bos = new BufferedOutputStream(fos);
				
				int data = 0;
				while((data = bis.read()) != -1) {
					bos.write(data);
				}
				
				System.out.println("파일 다운로드 완료...");
				
			} else {
				System.out.println(resultMsg);
			}
			
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				bis.close();
				bos.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		new TcpFileClient().start();
	}
	
}

 

결과 화면2 : d:/D_Other/down_files의 위치로 ala.jpg 파일 다운로드 됨

 

 

반응형