2020년 9월 11일 금요일

(자바소켓프로그래밍, 콘솔 기반 JAVA채팅 프로그램 동영상)Socket, ServerSocket을 이용한 콘솔기반의 Chatting Program

 


(자바소켓프로그래밍, 콘솔 기반 JAVA채팅 프로그램 동영상)Socket, ServerSocket을 이용한 콘솔기반의 Chatting Program

 

이전 강좌에서 작성한 멀티쓰레드 채팅 예제를 저금 수정하여 콘솔 기반의 채팅 예제를 만들어 보겠습니다. 

 

서버

클라이언트가 접속을 할 때  accept를 하면 클라이언트 상대용 Socket이 만들어 지는데 이를 자바의  ArrayList 에 저장해주고 글을 쓸 때 현재 상대하고 있는 하나의 클라이언트에만 쓰는 것이 아니라 ArrayList에 보관중인 모든 Socket을 꺼내 글을 씁니다.

 

클라이언트

수시로 날아오는 메시지 처리를 위해 글을 읽는 부분을 쓰레드로 빼서 처리합니다.

이렇게 하지 않으면 글을 쓰고 있을 때 상대방이 던지는 메시지를  리얼타임으로 받지 못하고 글을 다 쓴 후 받게 된다.

 

0de90730f2f78cde6662151133faa091_1599832
 


package chat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

class ConsoleChatServer extends Thread {
protected Socket sock;
private static ArrayList<Socket> clients = new ArrayList<Socket>(5);

// ------------------------------------
// Constructor
// ------------------------------------
ConsoleChatServer(Socket sock) {
this.sock = sock;
}

// ------------------------------------
// ArrayList에서 클라이언트 소켓 제거
// 접속 후 나가버리는 경우 클릉 쓸 때 오류가 발생
// ------------------------------------
public void remove(Socket socket) {
for (Socket s : ConsoleChatServer.clients) {
if (socket == s) {
ConsoleChatServer.clients.remove(socket);
break;
}
}
}

// ------------------------------------
// Thread 실행 메소드
// ------------------------------------
public void run() {
InputStream fromClient = null;
OutputStream toClient = null;

try {
System.out.println(sock + ": 연결됨");

fromClient = sock.getInputStream();

byte[] buf = new byte[1024];
int count;
while ((count = fromClient.read(buf)) != -1) {
for (Socket s : ConsoleChatServer.clients) {
if (sock != s) {
toClient = s.getOutputStream();
toClient.write(buf, 0, count);
toClient.flush();
}
}
System.out.write(buf, 0, count);
}
} catch (IOException ex) {
System.out.println(sock + ": 에러(" + ex + ")");
} finally {
try {
if (sock != null) {
sock.close();
// 접속 후 나가버린 클라이언트인 경우 ArrayList에서 제거
remove(sock);
}
fromClient = null;
toClient = null;
} catch (IOException ex) {
}
}
}

// ------------------------------------
// 채팅 서버 메인
// ------------------------------------
public static void main(String[] args) throws IOException {
ServerSocket serverSock = new ServerSocket(9999); // 9999번 포트에 서버생성
System.out.println(serverSock + ": 서버소켓생성");
while (true) {
Socket client = serverSock.accept();
// 접속한 클라이언트 상대용 Socket을 ArrayList에 저장
clients.add(client);
//---------------------------- Thread Start
// 쓰레드는 run 메소드에서 accept로 만들어진 Socket을 이용하여 
// InputStream, OutputStream을 이용하여 글을 읽거나 쓴다.
// -----------------------------------------------
ConsoleChatServer myServer = new ConsoleChatServer(client);
myServer.start();
}
}
}


package chat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

//----------------------------------
// 서버에서 보내오는 값을 받기 위한 쓰레드
//----------------------------------
class ServerHandler extends Thread {
Socket sock = null;

public ServerHandler(Socket sock) {
this.sock = sock;
}

public void run() {
InputStream fromServer = null;
try {
fromServer = sock.getInputStream();

byte[] buf = new byte[1024];
int count;

while ((count = fromServer.read(buf)) != -1)
System.out.write(buf, 0, count);

} catch (IOException ex) {
System.out.println("연결 종료 (" + ex + ")");
} finally {
try {
if (fromServer != null)
fromServer.close();
if (sock != null)
sock.close();
} catch (IOException ex) {
}
}
}
}

//------------------------------
// 클라이언트 메인
//------------------------------
public class ConsoleChatClient {
public static void main(String[] args) throws IOException {
Socket sock = null;
try {
sock = new Socket("localhost", 9999);
System.out.println(sock + ": 연결됨");
OutputStream toServer = sock.getOutputStream();

// ---- 서버에서 보내오는 값을 받기위한 쓰레드
ServerHandler chandler = new ServerHandler(sock);
chandler.start();

byte[] buf = new byte[1024];
int count;
// ---- 콘솔에서 읽은 값을 서버에 보냄
// 키보드 입력을 바이트 단위로 읽어 buf 라는 바이트배열에 기록 후 읽은 바이트수를 리턴
        // 읽을것이 없는 경우 read 메소드는 대기하고 Ctrl + C등 눌러 종료하면 -1이 리턴한다.
        // 스트림의 끝인 경우 -1을 리턴한다.
while ((count = System.in.read(buf)) != -1) {
toServer.write(buf, 0, count);
toServer.flush();
}
} catch (IOException ex) {
System.out.println("연결 종료 (" + ex + ")");
} finally {
try {
if (sock != null)
sock.close();
} catch (IOException ex) {
}
}
}
}



 

#자바동영상, #JAVA동영상, #자바채팅, #JAVA채팅,  #자바채팅프로그램, #채팅소스, #자바채팅소스, #자바멀티쓰레드, #자바채팅예제, #채팅소스다운, #JAVA채팅소스, #자바채팅동영상, #자바채팅영상, #자바강의, #자바강좌, #자바교육, 

댓글 없음:

댓글 쓰기

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...