반응형
채팅 프로그램
- 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(); 를 하면 안 됨.
}
}
멀티 채팅 프로그램
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();
}
}
반응형
'자바' 카테고리의 다른 글
[Java 고급] 26장 서블릿 및 설정 (0) | 2024.02.19 |
---|---|
[Java 고급] 25장 UDP 방식의 통신, HTTP 통신 (0) | 2024.02.16 |
[Java 고급] 23장 소켓 (1) | 2024.02.15 |
[Java 고급] 22장 IP주소 정보 (0) | 2024.02.14 |
[Java 고급] 21장 W3C DOM, 유스케이스 다이어그램 (0) | 2024.02.13 |