자바 TCP 소켓 프로그래밍(채팅프로그램)
TCP 소켓 프로그래밍(채팅프로그램) 구현과정
흐름도
소스코드
Client
public class ChatClient {
private static final int SERVER_PORT = 6000;
public static void main(String[] args) {
Socket socket = null;
Scanner scanner = null;
String line;
try {
scanner = new Scanner(System.in);
//소켓 객체 생성
socket = new Socket();
String hostAddress = InetAddress.getLocalHost().getHostAddress();
//connect
socket.connect(new InetSocketAddress(hostAddress, SERVER_PORT));
log("채팅방에 참가했습니다.");
System.out.print("닉네임>>");
String nickname = scanner.nextLine(); //block
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);
pw.println("join:" + nickname +"\n");
//6. 쓰레드시작 :읽기
new ChatClientThread(socket).start();
//쓰기
while(true){
line = scanner.nextLine();//block
// 8. quit 프로토콜 처리
if("quit".equals(line)) {
ChatClient.log("채팅방을 나갔습니다.");
break;
}else {
// 9.메시지 처리
pw.println("message:"+line);
}
}
} catch (IOException e) {
log("error:" + e);
}finally {
try {
if(scanner != null) {
scanner.close();
}
//close
if(socket != null && socket.isClosed() == false) {
socket.close();
}
} catch (IOException e) {
log("ChatServer 소켓종료시 에러");
}
}
}
public static void log(String log) {
System.out.println("[Chat Client] " + log);
}
}
ClientThread
public class ChatClientThread extends Thread {
private Socket socket;
BufferedReader br;
public ChatClientThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
String line = null;
br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
while (true) {
// 읽고 채팅방에 써주기
line = br.readLine();
System.out.println(line);
}
} catch (IOException e) {
ChatClient.log("서버와 연결이 종료되었습니다." );
}
}
}
Server
public class ChatServer {
private static final int PORT = 6000;
static List<Writer> listWriters;
public static void main(String[] args) {
ServerSocket serverSocket = null;
List<Writer> listWriters = new ArrayList<Writer>();
try {
System.out.print(">>");
// 서버소켓 객체 생성
serverSocket = new ServerSocket();
// bind
String hostAddress = InetAddress.getLocalHost().getHostAddress();
serverSocket.bind(new InetSocketAddress(hostAddress, PORT));
log("연결 기다림 " + hostAddress + ":" + PORT);
// 요청대기
while (true) {
// accept
Socket socket = serverSocket.accept();
// read,write
new ChatServerThread(socket, listWriters).start();
}
} catch (IOException e) {
log("ChatServer 대기중에러: " + e);
} finally {
try {
// close
if (serverSocket != null && serverSocket.isClosed() == false) {
serverSocket.close();
}
} catch (IOException e) {
log("ChatServer 소켓종료시 에러");
}
}
}
public static void log(String log) {
System.out.println("[ChatServer] " + log);
}
}
ServerThread
public class ChatServerThread extends Thread {
private Socket socket;
private String nickname;
List<Writer> listWriters;
public ChatServerThread(Socket socket, List<Writer> listWriters) {
this.socket = socket;
this.listWriters = listWriters;
}
@Override
public void run() {
// 1. Remote Host Information
InetSocketAddress inetRemoteSocketAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
String remoteHostAddress = inetRemoteSocketAddress.getAddress().getHostAddress();
int remoteHostPort = inetRemoteSocketAddress.getPort();
ChatServer.log("connected by client[" + remoteHostAddress + ":" + remoteHostPort + "]");
try {
// 2. 스트림 얻기
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8), true);
// 3. 요청 처리
while (true) {
String request = br.readLine();
if (request == null) {
ChatServer.log("클라이언트로 부터 연결 끊김");
doQuit(pw);
break;
}
// 4. 프로토콜 분석
String[] tokens = request.split(":");
if ("join".equals(tokens[0])) {
doJoin( tokens[1], pw);
}else if("message".equals(tokens[0])) {
doMessage(tokens[1]);
}else if("quit".equals(tokens[0])) {
doQuit(pw);
}
}
} catch (IOException e) { // 2. 스트림 얻기에대한 익셉션
ChatServer.log("stream error: " + e);
}
}
private void doQuit(Writer writer) {
removeWriter(writer);
broadcast( this.nickname + "님이 퇴장 하였습니다.");
}
private void removeWriter(Writer writer) {
synchronized(listWriters) {
listWriters.remove(writer);
}
}
private void doMessage(String message) {
broadcast(nickname + " : " + message);
}
private void doJoin(String nickname, Writer writer) {
this.nickname = nickname;
String data = nickname + "님이 참여하였습니다.";
addWriter(writer);
broadcast(data);
((PrintWriter)writer).println("join:ok");
}
private void addWriter(Writer writer) {
synchronized(listWriters) {
listWriters.add(writer);
}
}
private void broadcast(String data) {
synchronized(listWriters) {
for(Writer writer: listWriters) {
PrintWriter printWriter = (PrintWriter)writer;
printWriter.println(data);
printWriter.flush();
}
}
}
}
Author And Source
이 문제에 관하여(자바 TCP 소켓 프로그래밍(채팅프로그램)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dhwoo8405/자바-TCP-소켓-프로그래밍채팅프로그램저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)