본문 바로가기
CLASS/JAVA

#18-1 / 서버 - UDP

by hingu 2024. 5. 27.

UDP : 내부 포트 

UDP와 TCP는 따로 놈

❗ 서버 관련 변수는 모두 private 으로 선언 하는게 좋음 : 중간에 채갈 수 있음

 

ex)

UDP

Server(UDP 5000) <-> Client(UDP 5000) -> 그다음 접속자는 UDP 5001, UDP 5002.... (가상포트)

만약 client가 UDP 5000번을 이미 사용하고 있는경우 접속이 되지 않음

- 포트 하나개로 여러개를 사용 할 수있음

- 한개의 포트를 열어서 여러개의 가상포트와 통신을 할 수 있는 구조

- 보안상 연결을 체크 할 수 있음

- 자신의 포트가 열려있는지 아닌지를 체크해서 서버로 넘겨야함(보안 good)

- 가상포트는 자동생성

- 역추적 가능

- packet 필요

 

TCP ( https://dev-eunse.tistory.com/94 )

Server(TCP 5000) <-> Client( TCP 5000) -> 그다음 접속자는 TCP 5000, TCP 5000....  

- 분류는 쉬우나 많아지면 많아질수록 속도가 떨어짐

- 역추적 불가능

- packet 불필요

 


👀

packet이란 ? 실제 데이터에서 앞,뒤 정보를 표시하는 역할 - 해당 송수신 관련 정보를 담음

 

socket : 

일반 socket : 실시간 통신 가능

web socket : 실시간 통신 불가능 (http,https) / node.js, socket.io 사용시 실시간 통신 가능 (양방향 통신 가능함)

 

👀

receive() : 가동 (client에서 보낸 메세지를 서버에서 받는 역할 , byte로 받음) <->  send() : (메세지 전송)

DatagramPacket : 송수신에 사용되는 패킷  , UDP는 packet 만들어야지만 받기,보내기 가능

=> 보낼때 문법 : DatagramPacket(메세지 byte배열,메세지 배열전체크기,전송할ip,전송할port) 로 작성

UDP 기본

[ server part ] 
//udp : 내부 포트 
public class net7 {
	public static void main(String[] args) {
		new server_udp().server_start();

	}

}

class server_udp {
	private String ip = null; //서버 ip
	private int port = 0; //서버 port
	
	//TCP와 라이브러리가 완져니 다름
	private DatagramSocket ds = null; //UDP socket
	private DatagramPacket dp = null; //메세지 송수신 패킷
	
	public void server_start() {
		this.ip = "172.30.1.83";
		this.port = 7000;
		try {
			//server ip를 확인
			InetAddress ia = InetAddress.getByName(this.ip); //ip만 로드
			this.ds = new DatagramSocket(this.port); //UDP socket 등록
			
			byte[] by = new byte[1024]; //byte단위로 전송
			
			this.dp = new DatagramPacket(by, by.length); // : 송수신에 사용되는 패킷
			System.out.println("서버오픈..");
			this.ds.receive(this.dp); //가동
			
		}catch(Exception e) {
			System.out.println("udp 포트 충돌 발생!!!");
		}finally {
			this.ds.close();
			//ia는 안닫아도 됨
		}
	}
}



[ Client part ]

package net;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//UDP client 코드
public class net8 {
	public static void main(String[] args) {
		new net8_client().client_start();
	}
}

class net8_client{
	private String ip = null;
	private int port = 0;
    
	//자신의 포트가 열려있는지 아닌지를 체크해서 서버로 넘겨야함(보안 good) 
	private int myport = 0;
	private DatagramSocket ds = null; //socket
	private DatagramPacket dp = null; //packet
	
	public void client_start() {
		this.ip = ""; //접속할 ip
		this.port=7000; //접속할 port
		
		/* 1:1 접속시 */
		this.myport = 7001; //내 port
		
		/* 다중 접속시 */
		//this.myport = (int)Math.ceil(Math.random()*1000) + 7000;
		
		try {
			InetAddress ia = InetAddress.getByName(this.ip); //서버 ip를 가져옴
			this.ds = new DatagramSocket(this.myport);
			while(true) {
				byte b[] = new byte[1024];
				this.dp = new DatagramPacket(b, b.length,ia,this.port);
				this.ds.send(this.dp); //메시지 전송
				System.out.println("메세지 전송 완료!!");
				
				byte b2[] = new byte[1024];
				this.dp = new DatagramPacket(b2, b2.length); //서버 메세지를 받는 공간 생성 
				this.ds.receive(this.dp); //서버 메세지를 byte로 받음
				System.out.println(new String(this.dp.getData())); //서버 메세지 출력
				
				/* 클라이언트 정보 체크 */
				InetAddress client_ip = this.dp.getAddress(); //상대방 접속 ip 가져옴
				int client_port = this.dp.getPort();//상대방 접속 port를 가져옴
				System.out.println(client_ip);
				System.out.println(client_port);				
			}
			
		}catch(RuntimeException re) {
			System.out.println("서버 접속 지연시간으로 접속장애 발생");
		}catch(Exception e) {
			System.out.println("서버로 접근이 불가능 합니다");
		}
	}
}

 

⚡ UDP로 채팅 주고받기

[ server ]
// 채팅 server
public class udt_server {
	public static void main(String[] args) {
		new chat_server();
	}
}

class chat_server {
	private final String ip = "172.30.1.83";
	private final int port = 9000; //final : 절~대 못바꿈
	private DatagramSocket ds = null;
	private DatagramPacket dp = null;
	private InetAddress ia = null;
	private String msg = ""; //메세지 내용
	private InputStreamReader isr = null;
	private BufferedReader br = null;
	
	public chat_server() { //즉시실행
		try {
			this.ia = InetAddress.getByName(this.ip);
			this.ds = new DatagramSocket(this.port);
			this.udp(); //은닉화
		}catch(Exception e) {
			System.out.println("port 충돌로 인하여 서버가 작동되지 않습니다");
		}
	}
	
	private void udp() {
		try {
			while(true) {
				byte server_byte[] = new byte[1024]; //메세지 크기 : 1KB
				this.dp = new DatagramPacket(server_byte, server_byte.length);
				System.out.println("--상담 시작--"); //서버 오픈 대기
				this.ds.receive(this.dp); //클라이언트에서 전송한 메세지를받음(그 전까진 대기상태)
				this.msg = new String(this.dp.getData()); //전송된 문자(byte)를 문자열로 변환
				System.out.println(this.msg);
				
				/*클라이언트에게 전송 메세지*/
				System.out.println("메세지를 입력하세요 : ");
				InetAddress ia2 = this.dp.getAddress(); //client ip
				int port2 = this.dp.getPort(); //client port
				this.isr = new InputStreamReader(System.in); //메세지 작성
				this.br = new BufferedReader(this.isr); //작성된 내용을 메모리 등록
				this.msg = this.br.readLine(); //메모리 등록된 내용을 변수로 받음
				byte client_msg[] = this.msg.getBytes(); //문자열 => byte로 변환
				
				/*클라이언트에서 전송할 패키지 제작*/
				//DatagramPacket(메세지 byte배열,메세지 배열전체크기,전송할ip,전송할port)
				this.dp = new DatagramPacket(client_msg, client_msg.length, ia2, port2);
				this.ds.send(this.dp); //클라이언트저복
			}
		}catch(Exception e) {
			System.out.println("UDP 서버 오픈 오류 발생!!");
		}
	}
}



[ client ]

//채팅 client
public class udt_client {
	public static void main(String[] args) {
		new chat_client();
	}
}

class chat_client {
	private final String ip = ""; //server ip
	private final int port = 9000; //server port
	private int myport = 0; //자신이 사용하는 port
	
	private DatagramSocket ds = null;
	private DatagramPacket dp = null;
	private InetAddress ia = null;
	private String msg = ""; //메세지 내용
	private InputStreamReader isr = null;
	private BufferedReader br = null;
	
	public chat_client() { //즉시실행
		//다중접속 위해 고정포트 x random 사용 - 한번에 여러 사람 접속
		this.myport = (int)Math.ceil(Math.random()*1000) + 9000;
		this.chatting();
	}
	
	public void chatting() {
		try {
			this.ia = InetAddress.getByName(this.ip); //서버 ip가져옴
			this.ds = new DatagramSocket(this.myport);
			while(true) {
				System.out.println("상담 내용을 입력하세요 : ");
				this.isr = new InputStreamReader(System.in); //메세지 입력(걍 scanner써도 됨)
				this.br = new BufferedReader(this.isr); //입력한 내용을 메모리에 임시저장
				this.msg = this.br.readLine(); //임시 저장된 내용을 변수에 받아서 처리
				byte by[] = this.msg.getBytes(); //메세지 String->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 msg = new String(this.dp.getData()); //byte => 문자열 변환
				System.out.println(msg); //출력 
				
			}
		}catch(Exception e) {
			System.out.println("서버 접속 오류!!");
		}
	}
}

 

'CLASS > JAVA' 카테고리의 다른 글

#19 / Thread (class 형태 , interface 형태)  (0) 2024.05.31
#18-2 / Thread를 이용한 멀티 서버  (0) 2024.05.27
#17 / remind3  (0) 2024.05.24
#16-2 / 서버 - TCP  (0) 2024.05.23
#16-1 / network 🔥  (0) 2024.05.23