(Server)
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import threadex.ServerThread;
public class MainClass {
public static void main(String[] args) {
Socket clientSocket = null;
try {
// 문지기 Socket
ServerSocket serverSocket = new ServerSocket(9000);
// 버전 확인, binding, listener 포함
List<Socket> list = new ArrayList<Socket>();
while (true) {
System.out.println("접속 대기중...");
clientSocket = serverSocket.accept();
list.add(clientSocket);
// 접속 client 확인
System.out.println("client IP : " + clientSocket.getInetAddress() + " Port : " + clientSocket.getPort());
new ServerThread(clientSocket, list).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- MainClass
- Server는 하나, Client는 여러 개가 될 수 있기 때문에 list의 형태로 client를 관리한다.
- accept() : client로 부터 받은 연결 요청을 수락한다.
- server는 끊임없이 돌아가며 client의 요청으로 송/수신을 반복해야 하므로 thread를 이용하여 변화를 감지한다.
- ServerThread 는 socket 객체를 변화가 생길때마다 생성해야 하므로 while문 안에 위치한다.
- server는 수신 → 송신
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.List;
import java.util.Scanner;
public class ServerThread extends Thread {
Scanner scanner = new Scanner(System.in);
Socket socket;
List<Socket> list;
public ServerThread(Socket socket, List<Socket> list) {
this.socket = socket;
this.list = list;
}
@Override
public void run() {
super.run();
try {
while (true) {
// 수신(recv)
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = reader.readLine();
System.out.println("client로부터 받은 메시지: " + str);
// 송신(send)
for (Socket s : list) {
if (socket != s) {
PrintWriter writer = new PrintWriter(s.getOutputStream());
writer.println(str);
writer.flush();
}
}
Thread.sleep(300); // 0.3sec
}
} catch (Exception e) {
System.out.println("연결 끊긴 IP: " + socket.getInetAddress());
list.remove(socket);
// 남은 접속 클라이언트 출력
for (Socket s : list) {
System.out.println("접속 되어있는 IP: " + s.getInetAddress() + " Port: " + s.getPort());
}
try {
socket.close();// ?
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
- ServerThread
- java의 내장 library의 Thread 를 상속받아 run() 함수를 이용하여 구현한다.
- client로부터 메세지를 수신받았다면 list의 자기 자신 (socket) 을 제외한 나머지 Socket (s) 에 메세지를 전달한다.
- flush() : flush 함수를 써야만 write가 실행된다. 잊지말자
- exception은 만약 client가 갑자기 종료된 경우 에러문을 출력하지 않고 list에서 socket을 삭제하고 close한다.
(Client)
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;
import threadex.ReadThread;
public class MainClass {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 1. 접속 해야할 Server IP(주소)를 설정 -> socket 설정
InetSocketAddress sockAddr = new InetSocketAddress("192.168.0.105", 9000);
// 2. Socket 생성
Socket socket = new Socket();
// 3. Connect
try {
socket.connect(sockAddr, 10000); // 10초동안 서버 못 찾으면 끊어라
InetAddress inetAddress;
if ((inetAddress = socket.getInetAddress()) != null) {
System.out.println("서버 접속 성공!");
} else {
System.out.println("서버 접속 실패~");
}
new ReadThread(socket).start();
while (true) {
// 4. Packet 송수신
System.out.print("[보낼메시지]: ");
String str = scanner.next();
// 송신(send)
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println(str);
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- MainClass
- connect() : 서버에 연결 요청
- client는 송신 시기는 Scanner을 통해 입력받으므로 알고 있다. 따라서 수신만 기다리면 되기 때문에 이를 thread를 통해 변화를 감지한다.
- client 가 변화할 때마다 socket 객체를 생성할 필요는 없기 때문에 while문 밖에 선언한다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReadThread extends Thread {
Socket socket;
public ReadThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
while (true) {
// 수신(recv)
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = reader.readLine();
System.out.println("server로부터 받은 메시지: " + str);
Thread.sleep(300);
}
} catch (Exception e) {
}
super.run();
}
}
- ReadThread
'JAVA' 카테고리의 다른 글
JAVA GUI - AWT (0) | 2022.06.13 |
---|---|
JAVA Network- TCP/IP (0) | 2022.06.13 |
JAVA 기초 - Design Pattern (0) | 2022.06.10 |
JAVA 기초 - 상속, final, static, Abstract, Interface, Collection (0) | 2022.06.09 |
JAVA 기초 - Exception, Calendar, Class (0) | 2022.06.08 |