1. 기본
서버
package net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//UDP - Server
public class udp_server {
public static void main(String[] args) {
new data_server();
}
}
class data_server {
int port = 10000;
DatagramSocket ds = null; // UDP PORT를 오픈하는 역할
DatagramPacket dp =null; // UDP 내부 데이터 통신 사이즈
InetAddress ia = null;
InputStreamReader isr = null;
BufferedReader br = null;
public data_server() {
try {
this.ds = new DatagramSocket(this.port);
this.udp();
}catch (Exception e) {
System.out.println("UDP 포트 충돌로 인하여 서버가 작동되지 않습니다.");
}
}
//Packet : 네트워크를 통해서 데이터를 전송할 때 사용하는 단위
//DatagramPacket(byte배열, 배열전체크기) : 받는 형태
//DatagramPacket(byte배열, 배열전체크기, Client IP, Client Port) : 보내는 형태
//receive(받는 내용), send(보내는 내용)
private void udp() {
try {
while(true) { //UDP통신을 지속적으로 서버를 오픈
byte server_byte[] = new byte[1024];
//UDP 패킷 크기 만큼 지속적으로 통신 대기 상태로 오픈
this.dp = new DatagramPacket(server_byte, server_byte.length);
System.out.println("상담 시작");
this.ds.receive(this.dp); //클라이언트에서 전송한 메세지를 받는 역할
String msg = new String(this.dp.getData());
System.out.println(msg);
//Client에게 전송 메세지
System.out.println("메세지를 입력하세요 : ");
this.ia = this.dp.getAddress();
System.out.println(this.dp.getAddress()); //클라이언트의 ip 출력
int client_port = this.dp.getPort();
System.out.println( this.dp.getPort()); //클라이언트의 port 출력
this.isr = new InputStreamReader(System.in); //작성된 내용을 입력받는 객체
this.br = new BufferedReader(this.isr); //입력된 내용을 메모리에 등록
byte client_msg[] = this.br.readLine().getBytes(); //문자를 byte로 변환
//Client로 전송
this.dp = new DatagramPacket(client_msg, client_msg.length, this.ia, client_port);
this.ds.send(this.dp); //만들어진 패킷을 send로 전송
}
}catch (Exception e) {
System.out.println("UDP 서버 오류발생");
}
}
}
클라이언트
package net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//UDP - Client
public class udp_client {
public static void main(String[] args) {
new data_client();
}
}
class data_client{
String ip = "172.30.1.85";
int port = 10000; //서버의 port
int myport = 0; //자신이 사용하는 port
DatagramSocket ds = null; //UDP 접속하는 역할
DatagramPacket dp = null; //UDP 데이터 송수신 필요한 크기
InetAddress ia = null; //자신의 IP 정보 및 PORT를 확인
InputStreamReader isr = null;
BufferedReader br = null;
public data_client() {
try {
//다중 접속을 할 수 있도록 자신의 UDP 포트가 자동으로 생성되도록 함
this.myport = (int)Math.ceil(Math.random()*1000) + 9000;
this.ia = InetAddress.getByName(this.ip);
this.ds = new DatagramSocket(this.myport); //서버에 자신의 PORT 정보를 전송
this.udp_cn();
}catch (Exception e) {
System.out.println("서버 접속 오류");
}
}
private void udp_cn() {
try {
while(true) {
System.out.println("메세지를 입력하세요 : ");
this.isr = new InputStreamReader(System.in); //scanner처럼 메세지를 입력받을 수 있음
this.br = new BufferedReader(this.isr); //사용자가 입력한 값을 메모리에 저장
String msg = this.br.readLine(); //메모리에 있는 값을 변수에 저장
byte by[] = msg.getBytes(); //문자를 byte로 변환
//전송할 내용을 Packet으로 생성
this.dp = new DatagramPacket(by, by.length, this.ia, this.port);
this.ds.send(this.dp); //전송
System.out.println("올바르게 서버에 전달되었습니다.");
//서버 메세지 출력 역할
byte server[] = new byte[1024];
this.dp = new DatagramPacket(server, server.length);
this.ds.receive(this.dp);
String server_msg = new String(this.dp.getData()); //byte->String
System.out.println(server_msg);
}
}catch (Exception e) {
System.out.println("정상적으로 UDP 포트가 활성화되지 않아 접속이 차단됩니다.");
}
}
}
2. Thread를 이용한 통신
서버
package net;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
// UDP 멀티스레드 서버
public class udp_server_thread {
public static void main(String[] args) {
new udpServer().start();
}
}
class udpServer {
int port = 10000;
DatagramSocket socket = null;
public void start() {
try {
socket = new DatagramSocket(port);
System.out.println("[UDP 서버 시작] 포트: " + port);
while (true) {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// 클라이언트 메시지를 처리하는 스레드 실행
new ServerThread(socket, packet).start();
}
} catch (Exception e) {
System.out.println("[서버 오류] " + e.getMessage());
}
}
}
//클라이언트 메시지를 처리하는 스레드
class ServerThread extends Thread {
DatagramSocket socket = null;
DatagramPacket packet = null;
Scanner scanner = new Scanner(System.in); // 서버 입력을 위한 Scanner 추가
public ServerThread(DatagramSocket socket, DatagramPacket packet) {
this.socket = socket;
this.packet = packet;
}
@Override
public void run() {
try {
String receivedMessage = new String(packet.getData(), 0, packet.getLength());
System.out.println("[클라이언트] " + receivedMessage);
InetAddress clientAddress = packet.getAddress();
int clientPort = packet.getPort();
while (true) {
System.out.print("[서버] 메시지 입력: ");
String serverMessage = scanner.nextLine(); // 서버에서 직접 입력 받기
byte[] serverData = serverMessage.getBytes();
DatagramPacket serverPacket = new DatagramPacket(serverData, serverData.length, clientAddress,
clientPort);
socket.send(serverPacket);
System.out.println();
System.out.println("[서버] 클라이언트(" + clientAddress + ":" + clientPort + ")에게 메시지 전송: " + serverMessage);
}
} catch (Exception e) {
System.out.println("[스레드 오류] " + e.getMessage());
}
}
}
클라이언트
package net;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
// UDP 멀티스레드 클라이언트
public class udp_client_thread {
public static void main(String[] args) {
new Client().start();
}
}
class Client {
String ip = "172.30.1.??";
int port = 10000;
DatagramSocket socket = null;
InetAddress serverAddress = null;
public void start() {
try {
socket = new DatagramSocket();
serverAddress = InetAddress.getByName(ip);
System.out.println("[UDP 클라이언트 시작]");
// 서버로 메시지 전송하는 스레드
new ClientSendThread(socket, serverAddress, port).start();
// 서버 메시지를 수신하는 스레드
new ClientReceiveThread(socket).start();
} catch (Exception e) {
System.out.println("[클라이언트 오류] " + e.getMessage());
}
}
}
// 서버로 메시지를 전송하는 스레드
class ClientSendThread extends Thread {
DatagramSocket socket = null;
InetAddress serverAddress = null;
int serverPort = 0;
Scanner scanner = null;
public ClientSendThread(DatagramSocket socket, InetAddress serverAddress, int serverPort) {
this.socket = socket;
this.serverAddress = serverAddress;
this.serverPort = serverPort;
this.scanner = new Scanner(System.in);
}
@Override
public void run() {
try {
while (true) {
System.out.print("메시지 입력: ");
String message = scanner.nextLine();
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, serverPort);
socket.send(packet);
}
} catch (Exception e) {
System.out.println("[송신 오류] " + e.getMessage());
}
}
}
//서버로부터 메시지를 수신하는 스레드
class ClientReceiveThread extends Thread {
DatagramSocket socket = null;
public ClientReceiveThread(DatagramSocket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
while (true) {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String receivedMessage = new String(packet.getData(), 0, packet.getLength());
// 기존 입력을 유지하면서 서버 응답을 보기
System.out.println("\n[서버] " + receivedMessage);
System.out.print("메시지 입력: ");
}
} catch (Exception e) {
System.out.println("[수신 오류] " + e.getMessage());
}
}
}
- 응용문제로 내주셔서 챗GPT를 이용해서 만들었는데 클라이언트쪽은 괜찮지만 서버쪽 조금 더 수정 필요
- 쓰앵님의 힌트
- Server => Client => 메세지 => receive => 일시정지
- 협업
-
- Server => Client (IP, PORT) => 동일한 UDP PORT(X)
- Client => Server (IP,PORT) => 동일한 UDP PORT(X)
- Server => Client (IP, PORT) => 동일한 UDP PORT(X)
-
- 작업
- Server => receive => Client 반는 무한반복문
- Server => send => 무한반복문
- Client => receive => Server 받는 메세지
- Client => send => 무한반복문
- UDP 가는포트 오는포트 따로따로
- 서버 10000 10001
- 클라 9999 9998
주저리주저리
Gti 두가지 용도
1. 협업
2. 엔진 이용해서 공유 프로세서 => Git API => Git Controller //자바 다운받을때 있는 Git파일
포트번호
WEB SERVER : 80, 443
FTP : 21
SENDMAIL : 25
POP3 : 110
IMAP3 : 143