[자바]채팅 프로그램(여러 사용자 동시 접속)

2021. 8. 19. 01:12·프로그래밍/Java
반응형

TCPServer.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TCPServer implements Runnable {
	private static Socket clientSocket; // 각각의 클라이언트를 구분하기 위함
	static PrintWriter out = null;
	static ArrayList<Socket> list = new ArrayList<Socket>(); // 클라이언트 쓰레드를 담을 ArrayList 생성
	static int UserNum = 0; // 서버에서 클라이언트에게 번호를 부여하기 위한 변수

	public TCPServer(Socket clientSocket) { // 멀티 쓰레드 환경을 구축하기 위한 생성자. 각각의 개별 쓰레드를 생성
		this.clientSocket = clientSocket;
		list.add(clientSocket); // 쓰레드들을 리스트에 추가하는 부분
	}

	public static void main(String[] args) {
		ExecutorService eService = Executors.newFixedThreadPool(5);
		// 쓰레드 생성. 6번째 접속부터는 BLOCKING-참가자를 6명으로 제한

		System.out.println("#서버 시작");

		try (ServerSocket sSocket = new ServerSocket(10000)) {
			// try-with-resource문 사용 시 자동으로 자원 해제
			while (true) { // 접속하는 클라이언트들에게 무한 서비스
				System.out.println("#연결 대기 중 ......");
				clientSocket = sSocket.accept();
				// 연결 수락. client 연결정보, ip주소 담음
				TCPServer tes = new TCPServer(clientSocket);
				// 개별 쓰레드 객체 생성. 연결 수락시 접속한 클라이언트의 정보 담김
				// new Thread(tes).start();
				// 각각의 쓰레드가 식별가능한 인수를 갖게 된다, 개별적인 수행으로 효율적이지는 않다
				eService.submit(tes);
				// 더 효율적인 방법
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("#서버 종료");
		eService.shutdown();
	}

	public void run() {
		// 각각의 클라이언트들에 대한 피드백을 하는 run함수
		// 접속한 클라이언트들에 대응가능한 송수신용 버퍼와 각종 변수들이 들어있음
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			// 수신 버퍼
			// OutputStream : 서버에서 클라이언트로 메세지 보내기
			OutputStream out = clientSocket.getOutputStream();
			PrintWriter writer = new PrintWriter(out, true);
			// out = new PrintWriter(clientSocket.getOutputStream(), true); //송신 버퍼

			UserNum++;
			System.out.println("#클라이언트 : " + UserNum + "(" + Thread.currentThread() + ")" + " 연결됨!");

			String UserID = br.readLine(); // 사용자에게서 id를 입력받아 설정
			String inputLine; // 클라이언트가 보낸 값 저장

			writer.println("#[" + UserID + "]님이 접속하셨습니다.");
			System.out.println("#[" + UserID + "]님이 접속하셨습니다.");

			while ((inputLine = br.readLine()) != null) {
				// readLine(): client가 보낸 msg를 br에서 한줄씩 꺼냄
				// System.out.println("[" + UserID + "] " + inputLine);
				// 클라이언트에게서 받아온 정보를 한줄씩 출력

				for (int i = 0; i < list.size(); i++) {
					// ArrayList의 사이즈만큼 for문을 돌리면서 모든 클라이언트에게 메시지 전송
					out = list.get(i).getOutputStream();
					// ArrayList의 i번째 getOutputStream()요소를 가져와 out객체에 대입한다.
					writer = new PrintWriter(out, true);
					// 새로운 printWriter객체를 생성
					writer.println("[" + UserID + "] " + inputLine);
					// ArrayList의 i번째 요소를 클라이언트에게 송신한다.
				}
			}
			out.close();
			System.out.println("#클라이언트 : " + Thread.currentThread() + " 종료됨!");
		} catch (IOException ex) {
			ex.printStackTrace();
		}

	}
}

 

TCPClient.java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class TCPClient {

	Socket cSocket;
	BufferedReader br;
	PrintWriter out;
	Scanner scv;

	public TCPClient() { // 메시지 송신
		System.out.println("서버에 접속하는 중입니다.");
		try {
			// accept() 호출 후 쓰레드 만들어지고, Array List에 추가된다.
			InetAddress localAddress = InetAddress.getLocalHost();

			cSocket = new Socket(localAddress, 10000);// Socket cSocket = new Socket("127.0.0.1", 9000);
			// 10000번 포트와 로컬 주소를 사용하는 cSocket이라는 새로운 소켓을 생성
			SocketThread st = new SocketThread(); // 소켓 쓰레드의 새로운 객체인 st라는 쓰레드를 생성한다.
			st.start(); // st를 실행시킨다.
			// Test클래스가 Thread 클래스를 상속했다.
			// Thread 클래스의 run 메소드를 구현하면 st.start() 실행 시 st객체의 run 메소드가 수행이 된다.
			out = new PrintWriter(cSocket.getOutputStream(), true);
			scv = new Scanner(System.in);

			// 사용자 아이디 지정하는 부분
			String UserID = "";
			System.out.println("#서버에 연결됨!");
			System.out.println("#사용할 ID를 입력해주세요.");
			out.print(UserID);

			while (true) {
				String inputLine = scv.nextLine(); // 사용자에게서 서버로 보낼 값을 입력받는 변수
				out.println(inputLine); // 입력받은 키보드 값을 서버로 전송
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	class SocketThread extends Thread { // 메시지 수신
		public void run() {
			try {
				br = new BufferedReader(new InputStreamReader(cSocket.getInputStream())); // 송신 버퍼 객체 생성
				String response = null; // 송신된 메시지를 저장하기 위한 변수
				while ((response = br.readLine()) != null) { // br에 읽을 메시지가 있는 한 무한반복
					System.out.println(response); // br 객체에 저장된 문자열을 한 줄 씩 받아와서 출력
				}
			} catch (Exception e) {
			}
		}
	}

	public static void main(String[] args) {
		new TCPClient(); // 메인문에서 생성자 실행시켜주기
	}
}

 

실행화면

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'프로그래밍 > Java' 카테고리의 다른 글

[자바]소켓 서버-클라이언트 통신 실습  (0) 2021.08.19
뉴렉처 자바 JDBC 프로그래밍 강의 내용 정리 19-24강  (0) 2021.08.17
뉴렉처 자바 JDBC 프로그래밍 강의 내용 정리 9-18강  (0) 2021.08.16
뉴렉처 자바 JDBC 프로그래밍 강의 내용 정리 1-8강  (0) 2021.08.16
[자바] 배열 역순 출력  (0) 2020.11.09
[자바] 은행 프로그램(잔액 조회, 인출)(while문 활용)  (0) 2020.11.09
'프로그래밍/Java' 카테고리의 다른 글
  • [자바]소켓 서버-클라이언트 통신 실습
  • 뉴렉처 자바 JDBC 프로그래밍 강의 내용 정리 19-24강
  • 뉴렉처 자바 JDBC 프로그래밍 강의 내용 정리 9-18강
  • 뉴렉처 자바 JDBC 프로그래밍 강의 내용 정리 1-8강
청량리 물냉면
청량리 물냉면
프로그래밍 공부를 하고 있습니다. 공부 내용 정리 겸 정보 공유를 목적으로 합니다.
    반응형
  • 청량리 물냉면
    노력중인 블로그
    청량리 물냉면
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 프로그래밍
        • Programming
        • C | C++
        • Java
        • Python
      • 웹 프로그래밍
        • HTML | CSS
        • JavaScript | TypeScript
        • React
        • Vue.js
        • Next.js
        • Spring & Spring Boot
        • JSP & Servlet
        • DB
      • 웹 프로젝트
        • 웹 프로젝트
        • 🥨스낵몰
        • 👨‍👨‍👧‍👧소셜 가계부
        • 🌜꿈 일기장
        • 🔮포트폴리오 사이트
        • 🏃‍♂️팀 프로젝트: 일정관리 프로그램
        • 📈팀 프로젝트: AI기반 주식 분석 플랫폼
        • 😺Just Meow It: 고양이의 조언
      • 앱 프로그래밍
        • Flutter
        • Kotlin
      • Problem Solving
        • 백준
        • 프로그래머스
        • SWEA
      • Computer Science
        • 알고리즘
        • 컴퓨터 네트워크
        • 이산수학
      • Developer
        • 후기
        • 자료정리
        • 취업 | 취준
        • 웹개발 교육 프로그램
        • TIL
  • 블로그 메뉴

    • 홈
    • Github
  • 공지사항

    • 프로그래밍 공부 중😊
  • 인기 글

  • 태그

    Til
    파이썬
    d3
    Next.js
    리액트
    ZeroCho
    강의내용정리
    컴퓨터네트워크
    React
    클론 프로젝트
    구현
    프로그래머스
    AWS
    Jiraynor Programming
    자바
    프로젝트
    공식문서
    bfs
    포트폴리오
    알고리즘
    백준
    SWEA
    플러터
    타입스크립트
    mysql
    자바스크립트
    웹사이트
    뉴렉처
    spring boot
    블로그 제작
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
청량리 물냉면
[자바]채팅 프로그램(여러 사용자 동시 접속)
상단으로

티스토리툴바