728x90
2023.01.31 - [JAVA/Java 기초] - 네트워크 기초(IP, TCP, UDP).java
네트워크 기초(IP, TCP, UDP).java
네트워크 네트워크 : 여러 컴퓨터들을 통신 회선으로 연결한 것 LAN(Local Area Network) : 가정, 회사, 건물, 특정영역에 존재하는 컴퓨터 들을 연결 하는것, 근거리 통신 : 스위치, 게이트웨이, 모뎀,
less-go.tistory.com
이전글에서 계속됩니다.
서버의 동시 요청 처리
- 일반적으로 서버는 다수의 클라이언트와 통신합니다.
- 서버는 클라이언트들로 부터 동시에 요청을 받아서 처리하고,
- 처리결과를 개별 클라이언트로 보내줍니다.

- accept()와 recieve()를 제외한 요청 처리 코드를 별도의 스레드에서 작업합니다.

- 스레드를 처리할 때 클라이언트의 폭증으로 인한 서버의 과도한 스레드 생서응ㄹ 방지하기 위해 스레드풀을 사용하는것이 바람직합니다.

TCP EchoServer 동시 요청 처리
- 스레드풀을 이용해서 클라이언트의 요청을 동시에 처리합니다.

TCP EchoServer구현 : (스레드풀 적용, 10명)
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService; // 스레드풀 (스레드의 갯수 제한)
import java.util.concurrent.Executors;
public class EchoServer {
private static ServerSocket serverSocket = null;
private static ExecutorService excutorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("------------------------------------------");
System.out.println("서버를 종료하려면 q를 입력하고 Enter 키를 입력 하세요.");
System.out.println("------------------------------------------");
//TCP 서버 시작
startServer();
//키보드 입력
Scanner sc = new Scanner(System.in);
while(true) {
String key = sc.nextLine();
if(key.toLowerCase().equals("q")) {
break;
}
}
sc.close();
stopServer();
}
public static void startServer() {
//작업 스레드 정의
Thread thread = new Thread() {
@Override
public void run() {
try {
//ServerSocket 생성 및 Port 바인딩
serverSocket = new ServerSocket(50001);
System.out.println("[서버] 시작됨");
while(true) {
//연결수락
Socket socket = serverSocket.accept();
excutorService.execute(()-> {
try {
//연결된 클라이언트 정보 얻기
InetSocketAddress isa = (InetSocketAddress) socket.getRemoteSocketAddress();
System.out.println("[서버] " + isa.getHostName() + "의 연결 요청을 수락함");
DataInputStream dis = new DataInputStream(socket.getInputStream());
String message = dis.readUTF();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.flush();
System.out.println("[서버] 받은 데이터를 다시 보냄: " + message);
//연결 끊기
socket.close();
System.out.println("[서버] " + isa.getHostName() + "의 연결을 끊음");
}catch (IOException e) {
}
});
}
}catch(IOException e) {
System.out.println("[서버] " + e.getMessage());
}
}
};
//스레드 시작
thread.start();
}
public static void stopServer() {
try {
//ServerSocket을 닫고 port 언바인딩
serverSocket.close();
System.out.println("[서버] 종료됨");
}catch(IOException e1) {}
}
}
UDP NewsServer 동시 요청 처리
- 스레드풀을 이용해서 클라이언트의 요청을 동시에 처리

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NewsServer {
private static DatagramSocket datagramSocket = null;
private static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception{
System.out.println("-----------------------------------------");
System.out.println("서버를 종료하려면 q를 입력하고 Enter키를 입력 하세요.");
System.out.println("-----------------------------------------");
//UDP 서버 시작
startServer();
Scanner sc = new Scanner(System.in);
while(true) {
String key = sc.nextLine();
if(key.toLowerCase().equals("q")) {
break;
}
}
sc.close();
//UDP 서버 종료
stopServer();
}
public static void startServer() {
// 작업 스레드 정의
Thread thread = new Thread() {
@Override
public void run() {
try {
datagramSocket = new DatagramSocket(50001);
System.out.println("[서버] 시작됨");
while(true) {
// 클라이언트에서 보내는 데이터를 받을 DatagramPacket을 생성
DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
//클라이언트로부터 데이터를 받으면 활성화가 됩니다.
//receive : 대기상태 -> 데이터받음 -> 활성화
datagramSocket.receive(receivePacket);
executorService.execute(()-> {
try {
//클라이언트가 보낸 데이터를 스트링 형태로 변환
String newsKind = new String(receivePacket.getData(), 0, receivePacket.getLength(), "UTF-8");
//클라이언트의 IP와 port 얻기
SocketAddress socketAddress = receivePacket.getSocketAddress();
//10개의 뉴스를 클라이언트로 전송
for(int i = 0; i<=10; i++) {
String data = newsKind + ": 뉴스" + i;
byte[] bytes = data.getBytes("UTF-8");
DatagramPacket sendPacket = new DatagramPacket(bytes, 0, bytes.length, socketAddress);
datagramSocket.send(sendPacket);
}
}catch (Exception e) {
}
});
}
} catch (Exception e) {
System.out.println("[서버] " + e.getMessage());
}
}
};
//스레드 시작
thread.start();
}
public static void stopServer() {
//DatagramSocket을 닫고 Port 언바인딩
datagramSocket.close();
System.out.println("[서버] 종료됨");
}
}
728x90
'JAVA > Java 기초' 카테고리의 다른 글
| TCP 채팅 프로그램.java (0) | 2023.02.01 |
|---|---|
| JSON 데이터형식.java (0) | 2023.02.01 |
| 네트워크 기초(IP, TCP, UDP).java (0) | 2023.01.31 |
| 기본 타입 스트림.java (0) | 2023.01.31 |
| 요소 커스텀 집계.java (0) | 2023.01.30 |