자바 기반 Socket 다 중 클 라 이언 트 Client-server 채 팅 프로그램의 실현

임무 요구
간단 한 Socket 다 중 클 라 이언 트 채 팅 프로그램 을 만 듭 니 다:
  • 클 라 이언 트 프로그램 은 콘 솔 에서 문자열 을 입력 하여 서버 에 보 내 고 서버 가 돌아 온 정 보 를 표시 합 니 다
  • 4.567917.서버 엔 드 프로그램 은 클 라 이언 트 로부터 데 이 터 를 받 고 인쇄 하 는 동시에 표준 입력 에서 얻 은 정 보 를 클 라 이언 트 에 게 보 냅 니 다
  • 한 서버 를 만족 시 키 면 여러 고객 에 게 서 비 스 를 제공 할 수 있 습 니 다
  • 하위 버 전 링크
    구현 코드
    도구 클래스
    
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class SocketUtils {
    	
    	public static void writeToSocket(Socket socket, String message) throws IOException {
    		writeToOutputStream(socket.getOutputStream(), message);
    	}
    	
    	public static void writeToDataOutputStream(DataOutputStream dos, String message) throws IOException {
    		dos.writeUTF(message);
    		dos.flush();
    	}
    	
    	public static void writeToOutputStream(OutputStream os, String message) throws IOException {
    		writeToDataOutputStream(new DataOutputStream(os), message);
    	}
    
    }
    서버 엔 드 스 레 드
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Map;
    
    public class ChatServerRunnable implements Runnable {
    
    	private Socket socket;
    
    	private DataOutputStream dos;
    
    	private DataInputStream dis;
    
    	private String currentUserNickName;
    
    	public ChatServerRunnable(Socket socket) throws IOException {
    		this.socket = socket;
    		this.dos = new DataOutputStream(socket.getOutputStream());
    		this.dis = new DataInputStream(socket.getInputStream());
    	}
    
    	@Override
    	public void run() {
    		try {
    			write("       !");
    			login();
    			System.out.println(currentUserNickName + "      ");
    			write(currentUserNickName + ",     。
    【list users】
    【to all 】
    【to 】
    【exit】 "); String input = dis.readUTF(); while (!ChatServer.EXIT.equals(input)) { System.out.println(currentUserNickName + " " + input); if (input.startsWith("to ")) { sendMessage(input); } else if ("list users".equals(input)) { showOnlineUsers(); } else { write(" , !"); } input = dis.readUTF(); } } catch (IOException e) { e.printStackTrace(); } finally { ChatServer.nickNameSocketMap.remove(currentUserNickName); try { dis.close(); } catch (IOException e) { e.printStackTrace(); } try { dos.close(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } private void login() throws IOException { write(" :"); while (true) { String nickName = dis.readUTF(); System.out.println(" :" + nickName); synchronized (ChatServerRunnable.class) { if (!ChatServer.nickNameSocketMap.containsKey(nickName)) { currentUserNickName = nickName; ChatServer.nickNameSocketMap.put(nickName, socket); break; } else { write(" , :"); } } } } private void sendMessage(String input) throws IOException { int receiverEndIndex = input.indexOf(" ", 3); String receiver = input.substring(3, receiverEndIndex); String message = input.substring(receiverEndIndex + 1); if ("all".equals(receiver)) { broadcast(message); } else { sendIndividualMessage(receiver, message); } } private void sendIndividualMessage(String receiver, String orignalMessage) throws IOException { Socket receiverSocket = ChatServer.nickNameSocketMap.get(receiver); if (receiverSocket != null) { SocketUtils.writeToSocket(receiverSocket, formatMessage(" ", orignalMessage)); } else { write(" 【" + receiver + "】 "); } } private String formatMessage(String receiver, String originalMessage) { StringBuilder messageBuilder = new StringBuilder(); messageBuilder.append(currentUserNickName).append(" ").append(receiver).append(" :
    ") .append(originalMessage).append("
    :") .append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); return messageBuilder.toString(); } private void broadcast(String orignalMessage) throws IOException { for (Map.Entry<String, Socket> entry : ChatServer.nickNameSocketMap.entrySet()) { if (!currentUserNickName.equals(entry.getKey())) { SocketUtils.writeToSocket(entry.getValue(), formatMessage(" ", orignalMessage)); } } } private void showOnlineUsers() throws IOException { StringBuilder users = new StringBuilder(); users.append(" :
    "); for (String nickName : ChatServer.nickNameSocketMap.keySet()) { users.append("【").append(nickName).append("】
    "); } write(users.toString()); } private void write(String message) throws IOException { SocketUtils.writeToDataOutputStream(dos, message); } }
    클 라 이언 트 스 레 드
    
    import java.io.DataInputStream;
    import java.io.IOException;
    
    public class ClientMessageReceiver implements Runnable {
    	
    	private DataInputStream dis;
    	
    	private boolean timeToStop = false;
    	
    	public ClientMessageReceiver(DataInputStream dis) {
    		this.dis = dis;
    	}
    
    	@Override
    	public void run() {
    		while (!timeToStop) {
    			try {
    				System.out.println(dis.readUTF());
    			} catch (IOException e) {
    				if ("Connection reset".equals(e.getMessage())) {
    					System.out.println("          !");
    					break;
    				}
    				if (!timeToStop) {
    					e.printStackTrace();					
    				}
    			}
    		}
    	}
    	
    	public void stop() {
    		timeToStop = true;
    	}
    
    }
    서버 엔 드 프로그램
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.HashMap;
    import java.util.Map;
    
    public class ChatServer {
    	
    	public static final String EXIT = "exit";
    	
    	public static final int PORT = 8888;
    	
    	static Map<String, Socket> nickNameSocketMap = new HashMap<>();
    
    	public static void main(String[] args) {
    		try (ServerSocket ss = new ServerSocket(PORT)) {
    			System.out.println("          ,    " + PORT + "  ");
    			while (true) {
    				try {
    					Socket socket = ss.accept();
    					System.out.println("           ,   :" + socket);
    					new Thread(new ChatServerRunnable(socket)).start();
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    
    	}
    
    }
    클 라 이언 트 프로그램
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class ChatClient {
    	
    	private static Scanner scanner = new Scanner(System.in);
    
    	public static void main(String[] args) {
    		try (Socket socket = new Socket("127.0.0.1", 8888);
    				DataInputStream dis = new DataInputStream(socket.getInputStream());
    				DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
    			
    			ClientMessageReceiver messageReceiver = new ClientMessageReceiver(dis);
    			new Thread(messageReceiver).start();
    			String input = null;
    			do {
    				input = scanner.nextLine();
    				write(dos, input);
    			} while (!ChatServer.EXIT.equals(input));
    			messageReceiver.stop();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    
    	}
    	
    	private static void write(DataOutputStream dos, String message) throws IOException {
    		dos.writeUTF(message);
    		dos.flush();
    	}
    
    }
    운행 설명
    시작 서버:

    첫 번 째 클 라 이언 트 를 시작 하고 클 라 이언 트 닉네임 을 입력 하 십시오:

    서버 에서 이 사건 을 감청 하 였 습 니 다:

    모든 사용자 목록 을 가 져 와 서 모든 사용자 에 게"hhh"메 시 지 를 보 냅 니 다.

    서버 에서 이 이 벤트 를 받 았 습 니 다:

    새로운 클 라 이언 트 로그 인,사용자 닉네임 등록:

    서버 에서 이 이 벤트 를 받 았 습 니 다:

    사용자 1 은 사용자 2 에 게 개인 채 팅 메 시 지 를 보 냅 니 다.

    사용자 2 사용자 1 의 메 시 지 를 받 았 습 니 다:

    클 라 이언 트 2 모든 사용자 에 게 메시지 보 내기:

    고객 1.고객 2 의 단체 메 시 지 를 받 았 습 니 다.

    서버 에서 이 이벤트 들 을 감청 하 였 습 니 다:

    고객 2 탈퇴:

    클 라 이언 트 1 에 표 시 된 온라인 목록 은 1 명 입 니 다.

    클 라 이언 트 1 도 탈퇴:

    클 라 이언 트 사용자 가 종료 할 때 이 스 레 드 는 종 료 됩 니 다.
    클 라 이언 트 사용자 가 없 으 면 서버 도 정상적으로 자신의 일 을 한다.
    자바 기반 의 Socket 다 중 클 라 이언 트-server 채 팅 프로그램의 실현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 Socket 다 중 클 라 이언 트-server 채 팅 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 지원 을 바 랍 니 다!

    좋은 웹페이지 즐겨찾기