자바 기반 Socket 다 중 클 라 이언 트 Client-server 채 팅 프로그램의 실현
11033 단어 JavaSocket다 중 클 라 이언 트
간단 한 Socket 다 중 클 라 이언 트 채 팅 프로그램 을 만 듭 니 다:
구현 코드
도구 클래스
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 채 팅 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 지원 을 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.