⚡ TCP 멀티서버
public class multi_server {
public static void main(String[] args) {
new server_port();
}
}
//멀티 포트 설정
class server_port {
/*
-싱글포트로 한다면?
int port = 9001;
server_open so = new server_open(port); //배열의 포트번호
so.start();
*/
/*멀티포트*/
public server_port() {
int port[] = {9001,9002,9003}; //원시배열 사용 - 해당 포트를 다 열어버리겠다
int w=0;
while(w<port.length) {
server_open so = new server_open(port[w]); //배열의 포트번호
so.start(); //thread 클래스의 run 메소드 실행 - 스레드 발동
w++;
}
}
}
//멀티 포트 open (Thread 이용)
class server_open extends Thread{ //멀티 스레드
String ip = "";
int pt = 0;
ServerSocket sk = null;
Scanner sc = null;
public server_open(int p) { //즉시실행
this.ip = "172.30.1.83";
this.pt = p;
}
@Override
public void run() { //실행
try {
this.sk = new ServerSocket(this.pt); //socket을 이요하여 포트 오픈
while(true) {
Socket s = this.sk.accept(); //client가 접속을 할 수 있도록 반복문으로 대기
System.out.println(this.pt + "서버 오픈");
}
}catch(Exception e) {
System.out.println("중복된 port로 인하여 서버가 실행되지 않습니다");
}
}
}
⚡ Thread를 이용한 client
public class multi_client {
public static void main(String[] args) {
new client_port();
}
}
class client_port {
Socket sk = null;
String serverip = "";
int port = 0;
public client_port() {
this.serverip = "172.30.1.83";
this.port = 9001;
try {
this.sk = new Socket(this.serverip,this.port);//port번호 선택 - 톡 방 선택
System.out.println("서버 접속 완료!!");
Thread co = new client_open(); //Thread 메소드 호출
co.start(); //thread 클래스의 run 메소드 실행 - 스레드 발동
}catch(Exception e) {
System.out.println("서버 접속 오류 발생!!");
}
}
}
//채팅에 참여했을 때 같은 port 사용자끼리 대화시 사용되는 부분
class client_open extends Thread{
public client_open() {
}
@Override
public void run() {
}
}
🌺 채팅방 만들기
송신파트,수신파트 Thread로 분리
PrintWriter : stream -> writer 자동변환 시켜줌(byte -> String)
[server]
System.out.println(this.socket.getInetAddress()); - 상대방 접속ip 출력System.out.println(this.socket.getKeepAlive()); - socket 유무 메소드(true,false)
System.out.println(this.socket.getPort()); - 접속 port 출력
⚡ server
public class net_chat_server {
public static void main(String[] args) {
new net_chat_server().open();
}
//소켓을 유지하는 스레드
public void open() {
ServerSocket ss = null;
Socket sk = null;
try {
ss = new ServerSocket(9000);
System.out.println("[*-*-채팅 서버 오픈-*-*]");
while(true) { //socket을 유지하기 위한 무한반복문
sk = ss.accept(); //유지
chatroom ch = new chatroom(sk); //Thread
ch.start(); //Thread 작동
}
}catch(Exception e) {
System.out.println("서버 포트 충돌로 인하여 서버 가동을 중지합니다");
}finally {
if(ss != null) {
try {
ss.close();
System.out.println("서버를 강제 종료 합니다");
}catch(Exception e) {
System.out.println("서버 소켓이 완전 오류가 발생함");
System.exit(0);
}
}
}
}
}
//관리자가 직접 채팅 사용 가능(관리자 Scanner 가능)한 기능으로 제작시 별도의 Thread로 빼야함
//송수신역할을 하는 Tread 클래스
class chatroom extends Thread {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
Socket socket = null;
PrintWriter pw = null; //stream -> writer 자동변환 시켜줌(byte -> String)
String mid = "";
//서버에 접속한 모든 사용자 리스트 메모리에 저장
static List<PrintWriter> list = new ArrayList<PrintWriter>();
public void message(String msg) { //배열에 있는 모든 사용자에게 동일한 메세지 전달
for(PrintWriter pw : this.list) {
pw.println(msg); //발송
pw.flush(); //메모리 내용을 비움
}
}
@Override
public void run() {
try {
this.mid = this.br.readLine();
String hello = "[ "+ this.mid +" ] 님이 입장했습니다.";
System.out.println(hello);
this.message(hello);
while(this.br != null) { //메세지를 입력하면 작동이 되는 반복문
hello = this.br.readLine().intern();
if(hello == "나가기") {
break;
}else {
this.message(this.mid +":" + hello);
}
}
}catch(Exception e) {
System.out.println("사용자 추가 오류 발생으로 접속이 해제됩니다");
}finally {
this.message(this.mid + "님이 퇴장했습니다.");
this.list.remove(this.pw);
try {
this.socket.close();
}catch(Exception e) {
System.out.println("--채팅 서버 종료--");
}
System.out.println(this.mid + "님 퇴장ㅎ");
}
}
public chatroom(Socket s) {
this.socket = s;
try {
//접속에 대한 정보를 list배열에 추가
this.pw = new PrintWriter(this.socket.getOutputStream());
this.list.add(this.pw);
System.out.println("채팅 참여자 : 총" + this.list.size() + "입니다");
//채팅 관련 정보
this.is = this.socket.getInputStream();
this.isr = new InputStreamReader(this.is);
this.br = new BufferedReader(this.isr);
System.out.println(this.socket.getInetAddress()); //상대방 접속 ip
}catch(Exception e) {
System.out.println("소켓 통신 오류 발생!!!");
}
}
}
⚡ client
public class net_chat_client {
public static void main(String[] args) {
new net_chat_client().open();
}
public void open() {
String ip = "172.30.1.5";
int port = 9000;
try {
//딱 한번만 작동 나머지는 thread로 작동
Socket sk = new Socket(ip,port);
System.out.println("[** 채팅서버 접속 완료 **]");
Scanner sc = new Scanner(System.in);
System.out.println("생성할 id를 입력하세요 : ");
String mid = sc.nextLine();
//Tread로 값을 이관(서버에 메세지를 송수신) - 보내는 내용을 Thread로 추가
Thread th = new chat_clients(sk,mid);
th.start(); //새로운 작업공간이 열림
//접속 입장시 상대방에 대한 메세지를 출력(서버쪽 내용을 출력)
InputStream is = sk.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
//BufferedReader 사용시
//null이 아닐 경우 송수신에 대한 byte 메모리가 full이 되므로 값이 전달 안됨
BufferedReader br = new BufferedReader(isr);
//수신
while(br != null) {
String chat_msg = br.readLine();
//서버에서 보내준 내용과 동일할경우 종료
if(chat_msg.equals(mid+"님이 퇴장하셨습니다")) {
System.out.println("채팅 프로그램 종료");
System.exit(0); //강제 종료
break;
}
//자신의 화면에 서버 메세지를 출력하는 역할
System.out.println(chat_msg);
}
sc.close();
sk.close();
}catch(Exception e) {
System.out.println("소켓통신 서버 접근 오류!!");
}
}
}
//송신 역할을 하는 Thread (수신은 x)
class chat_clients extends Thread{
Socket sk = null;
String mid = null;
Scanner sc = null;
public chat_clients(Socket s, String id) {
this.sk = s;
this.mid = id;
this.sc = new Scanner(System.in);
}
@Override
public void run() {
try {
//접속 id를 전송(첫번째 메세지)
PrintStream ps = new PrintStream(this.sk.getOutputStream());
ps.println(this.mid);
ps.flush();
//사용자가 입력하는 메세지를 서버로 전송
while(true) {
System.out.println("채팅 메세지를 입력하세요");
String msg = this.sc.nextLine();
ps.println(msg);
ps.flush();
}
}catch(Exception e) {
System.out.println("서버 소켓 오류 발생으로 채팅이 중지됩니다.");
}
}
}