SMALL
안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
TCP 소켓 프로그래밍
- 클라이언트와 서버간의 1:1 소켓 통신
- 서버가 먼저 실행되어 클라이언트의 연결 요청을 기다려야 함
- java.net 패키지에서 제공하는 ServerSocket과 Socket 클래스가 해당
- 서버용 프로그램과 클라이언트용 프로그램을 따로 구현
싱글 스레드로 채팅 프로그램 만들기
Server
public class ChatServer {
public static final int PORT = 7777;
public static void main(String[] args) {
new ChatServer().start();
}
public void start() {
try {
//1. Socket 생성(PORT)
ServerSocket serverSocket = new ServerSocket(PORT);
InetAddress serverInetAddress = InetAddress.getLocalHost();
while(true) {
System.out.printf("[%s:%d] ChatServer 연결대기중...\n", serverInetAddress.getHostAddress(), PORT);
//2. 클라이언트 요청이 올 때까지 실행 대기
Socket socket = serverSocket.accept();
System.out.printf("[%s]로부터 연결요청...\n", socket.getInetAddress().getHostAddress());
//3. 입출력스트림 준비
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
PrintWriter pw = new PrintWriter(socket.getOutputStream()); //바이트기반도 브릿지 스트림 없이 받을 수 있음! 개행문자까지 읽어옴
Scanner sc = new Scanner(System.in);
pw.println("환영합니다😊🎉");
pw.flush();
String inMsg = null;
while((inMsg = br.readLine()) != null) {
if("exit".equals(inMsg)) {
System.out.println("> 상대가 채팅방을 나갔습니다.");
break;
}
System.out.println("클라이언트 : " + inMsg);
System.out.print("서버 : ");
String outMsg = sc.nextLine();
pw.println(outMsg);
pw.flush();
if("exit".equals(outMsg)) {
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("> 프로그램을 종료합니다.");
}
}
Client
public class ChatCilent {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 7777;
public static void main(String[] args) {
new ChatCilent().start();
}
public void start() {
try {
//1. Socket 객체 생성(IP, PORT)
Socket clientSocket = new Socket(SERVER_IP, SERVER_PORT);
System.out.printf("[%s:%d]에 접속 중...\n", SERVER_IP, SERVER_PORT);
//2. 입출력 스트림 준비
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream());
Scanner sc = new Scanner(System.in);
String inMsg = null;
while((inMsg = br.readLine()) != null) {
if("exit".equals(inMsg)) {
System.out.println("> 상대가 채팅방을 나갔습니다.");
break;
}
System.out.println("서버 : " + inMsg);
System.out.print("클라이언트 : ");
String outMsg = sc.nextLine();
pw.println(outMsg);
pw.flush();
if("exit".equals(outMsg)) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("> 프로그램을 종료합니다.");
}
}
멀티 쓰레드로 채팅 프로그램 만들기
Server
public class ChatServer {
public static final int PORT = 7777;
public static void main(String[] args) {
new ChatServer().start();
}
public void start() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while(true) {
System.out.printf("[%s:%d] 서버 대기 중...\n", InetAddress.getLocalHost().getHostAddress(), PORT);
Socket socket = serverSocket.accept();
//입력쓰레드, 출력쓰레드 각각 생성해서 시작
Thread sender = new Thread(new Sender(socket));
Thread receiver = new Thread(new Receiver(socket));
sender.start();
receiver.start();
System.out.println("채팅을 시작합니다.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
public class ChatClient {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 7777;
public static void main(String[] args) {
new ChatClient().start();
}
public void start() {
try {
Socket clientSocket = new Socket(SERVER_IP, SERVER_PORT);
//입력쓰레드, 출력쓰레드 각각 생성해서 시작
Thread sender = new Thread(new Sender(clientSocket));
Thread receiver = new Thread(new Receiver(clientSocket));
sender.start();
receiver.start();
System.out.println("채팅을 시작합니다.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sender(Thread)
public class Sender implements Runnable {
private PrintWriter pw;
private Scanner sc = new Scanner(System.in);
public Sender(Socket socket) {
try {
pw = new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
String outMsg = sc.nextLine();
pw.println(outMsg);
pw.flush();
if("exit".equals(outMsg)) {
break;
}
}
System.out.println("> 채팅을 종료합니다.");
}
}
Receiver(Thread)
public class Receiver implements Runnable {
private BufferedReader br;
private String name;
public Receiver(Socket socket) {
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
name = "[" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "]";
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
try {
String inMsg = br.readLine();
if("exit".equals(inMsg)) {
break;
}
System.out.println(name + " " + inMsg);
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("> 상대방이 채팅방을 나갔습니다.");
}
}
LIST
'Java > Java' 카테고리의 다른 글
Log4j) Log4j 사용법, 설정파일 (0) | 2022.08.04 |
---|---|
네트워크) InetAddress, URL, URLConnection (0) | 2022.04.11 |
쓰레드) 동기화(Synchronization)이란? (0) | 2022.04.04 |
쓰레드) 쓰레드 컨트롤 (sleep, join, interrupt), Daemon 쓰레드 (0) | 2022.04.03 |
쓰레드) 쓰레드란?, 멀티쓰레드, 장단점, 쓰레드 우선 순위 (0) | 2022.04.03 |