구성
Server
- ChatServer
- ClientManagerThread
Client
- ChatClient
- ReceiveThread
- SendThread
그림판 신공을 이용하여 개요를 그려봤다..
과정을 예를 들어서 설명하자면..
어떤 클라이언트에서 send thread를 통해 데이터를 입력했다고 하자. 뭐 대충 1번 클라이언트가 그랬다고 치자.
그러면 1번 클라이언트 측 출력 소켓에 데이터가 가게 된다.
서버측은 1번 클라이언트에 할당되어있는 소켓에서 입력을 받게 된다.
입력을 받게되면, 서버는 다른 클라이언트 소켓에 데이터를 보낸다.
그러면 각 클라이언트 수신 소켓에서 입력을 받게 된다.
각 클라이언트 receive thread가 입력을 받고 입력받은 것을 각 클라이언트 콘솔에 표현한다.
이렇게 되면 1번 클라이언트가 서버에 메시지를 보낸것이 다른 클라이언트에 모두 표시된다.
윽.. 이게 뭔 말이야
그냥 소스코드를 보면서 이해하자..
소스코드
ChatServer
package server;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class ChatServer{
public static ArrayList<PrintWriter> m_OutputList;
public static void main(String[] args) {
m_OutputList = new ArrayList<PrintWriter>();
try {
ServerSocket s_socket = new ServerSocket(8888);
while(true){
Socket c_socket = s_socket.accept();
ClientManagerThread c_thread = new ClientManagerThread();
m_OutputList.add(new PrintWriter(c_socket.getOutputStream()));
c_thread.start();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
ClientManagerThread
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientManagerThread extends Thread{
private Socket m_socket;
private String m_ID;
@Override
public void run() {
super.run();
try {
BufferedReader tmpbuffer = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
//외부에서 소켓으로 오는 입력값을 다루는 Inputstreamreader와 그걸 다루는 bufferedreader
String text;
//입력값 저장하는 변수
while(true) {
text = tmpbuffer.readLine(); //입력값을 변수에 저장한다.
if(text == null) { //입력값이 없을 경우
System.out.println(m_ID + "이 나갔습니다."); // 해당 클라이언트매니저에 표시
for(int i = 0; i<ChatServer.m_OutputList.size(); ++i) { //다른 클라이언트매니저에도 표시할 수 있게 서버에 있는 소켓 출력 리스트에 접근하여 출력한다.
ChatServer.m_OutputList.get(i).println(m_ID + "이 나갔습니다");
ChatServer.m_OutputList.get(i).flush();
}
break;
}
String[] split = text.split("highkrs12345"); //클라이언트에서 접속하면 IDhighkrs12345라고 보내는데 그걸 쪼갠다
if(split.length == 2 && split[0].equals("ID")) { // 입력값이 IDhighkrs12345라고 보낸게 맞는경우
m_ID = split[1];
System.out.println(m_ID + "이 입장하였습니다.");
for(int i = 0; i<ChatServer.m_OutputList.size(); ++i) {
ChatServer.m_OutputList.get(i).println(m_ID + "이 입장하였습니다.");
ChatServer.m_OutputList.get(i).flush();
}
continue;
}
for(int i = 0; i<ChatServer.m_OutputList.size(); ++i) //클라이언트가 그냥 아무값을 입력했을 경우
{
ChatServer.m_OutputList.get(i).println(m_ID + ">" + text);
ChatServer.m_OutputList.get(i).flush();
}
}
ChatServer.m_OutputList.remove(new PrintWriter(m_socket.getOutputStream()));
m_socket.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
ChatClient
package client;
import java.io.IOException;
import java.net.Socket;
import java.rmi.UnknownHostException;
public class ChatClient {
public static String userID;
public static void main(String[] args) {
try {
Socket c_socket = new Socket("192.168.0.2",8888);
ReceiveThread rec_thread = new ReceiveThread();
rec_thread.setSocket(c_socket);
SendThread send_thread = new SendThread();
send_thread.setSocket(c_socket);
send_thread.start();
rec_thread.start();
}catch(UnknownHostException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
}
}
ReceiveThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReceiveThread extends Thread{
private Socket m_socket;
@Override
public void run() {
super.run();
try {
BufferedReader tmpbuf = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
String receiveString;
String[] split;
while(true) {
receiveString = tmpbuf.readLine();
split = receiveString.split(">");
if(split.length >= 2 && split[0].equals(ChatClient.userID))
{
continue;
}
System.out.println(receiveString);
}
} catch(IOException e) {
}
}
public void setSocket(Socket _socket) {
m_socket = _socket;
}
}
SendThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SendThread extends Thread{
private Socket m_socket;
@Override
public void run() {
super.run();
try {
BufferedReader tmpbuf = new BufferedReader(new InputStreamReader(System.in));
PrintWriter sendWriter = new PrintWriter(m_socket.getOutputStream());
String sendString;
System.out.println("사용할 ID를 입력하세요");
ChatClient.userID = tmpbuf.readLine();
sendWriter.println("IDhighkrs12345" + ChatClient.userID);
sendWriter.flush();
while(true) {
sendString = tmpbuf.readLine();
if(sendString == "exit") {
break;
}
sendWriter.println(sendString);
sendWriter.flush();
}
sendWriter.close();
tmpbuf.close();
m_socket.close();
}catch(IOException e) {
e.printStackTrace();
}
}
public void setSocket(Socket _socket) {
m_socket = _socket;
}
}
[Java 강의93] 자바 Socket 통신으로 채팅 프로그램 만들기2 : 네이버 블로그 (naver.com)
오늘도 화이팅~
'컴퓨터공학 > Java' 카테고리의 다른 글
CS> 자바에서 Stack 과 Heap의 메모리 구조 차이점은?? (0) | 2021.07.02 |
---|---|
CS> autoboxing 과 unboxing은 무엇인가? (0) | 2021.07.02 |
CS> JVM JRE JDK 이것은 다 무엇?? (0) | 2021.07.01 |
CS> JVM은 무엇이고 왜 자바를 Platform Independent 언어라고 할까? (0) | 2021.07.01 |
Java 새롭게 알게 된 내용 정리 (0) | 2021.03.10 |