코드 그라데이션
<보충> Day32,33 통신 예제 설명추가 (1) 본문
TCP / UDP
1.
// 스캐너에서 진짜로 입력한 걸 보내는 것.
// 잊지 말아야 할 것
// Receieve 먼저 켜고 Send를 켜야한다.
public class SendUDP {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
InetAddress ia = InetAddress.getByName("192.168.20.34");
int port = 8888; //리시브 안 켜고서 send부터 켜면 안 된다.
Scanner sc = new Scanner(System.in); // 사용자에게 입력 받음
System.out.print("입력 : "); // 이걸 Receive에서 출력을 해준다.
String str = sc.next();
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.getBytes().length, ia, port);
// 보낼 때는 그냥 받는대로 보낸다(받을 때는 30바이트씩 했었다.)
// 데이터 상자에 받는 사람, 주소, 데이터 크기 등을 모두 적어놓는 것.
ds.send(dp);
}
}
/*
그런데 데이터 주고받을 때 유의해서 봐야하는 부분이 하나 있다.
500바이트를 보내면 30바이트만 받고 나머지는 흘려 보내는지
아니면 500을 전부 받기 위해서 10번을 다 도는지.
그건 구현된 방법에 따라 달라짐
상자는 일종의 운송장. 운송장을 보고 네트워크는 패킷을 제대로 처리한다.
*/
2.
public class ReceiveUDP {
// 얘는 받는 애이므로 자기가 받는 거니까 나의 위치를 굳이 특정할 필요 x
// 그래서 여기서 포트만 주면 될 듯.
public static void main(String[] args) throws IOException {
int port = 8888; // 소통할 포트 번호
int times = 10; // 10번만 주고받겠다.
DatagramSocket ds = new DatagramSocket(port);
int i = 1;
while(i<= times) { //10번 이하일 때(수행되는 동안)
byte[] buffer = new byte[30]; // 이 패킷에서 30바이트씩 읽어 오겠다.
DatagramPacket dp = new DatagramPacket(buffer, buffer.length); // 이걸 까보면 데이터가 있겠지.
ds.receive(dp); // 소켓에게 데이터를 받아오라고 요청.(여기 패킷에)
String str = new String(dp.getData());
System.out.println("수신된 데이터 : " + str);
i++;
}
}
}
/*
데이터 패킷을 만들 때는 박스에 데이터를 담아서 보내거나 담는 건데,
지금 여기서는 받는 것만 하고 있다.
데이터 패킷에 담을 수 있는 그릇을 줄 때는 byte 배열로 주는데,
(byte[] buffer = new byte[30];)
이걸 읽을 때는 String으로 변환해서 읽는다.
데이터 패킷 안에 버퍼를 주고, 이 버퍼에 담아달라고 했고,
잘 받았으면, 거기 담긴 거를 바이트를 스트링으로 바꿔서
사용자(sender)가 어떤 데이터를 보냈는지를 문자열로 변환해서 읽겠다.
그럼 왜 처음부터 String이 아닌 byte인가?
컴퓨터는 0과 1, 최대한 작은 단위룰 쑬 수록 좋다.
문자열을 보낸다고 하면 String 배열을 쓸 수 있겠지만
숫자를 보낸다거나 다른 걸 보낼 때, 굳이 String을 쓸 필요가 있나 싶은 것.
통신은 항상 byte로 하고, 받는 사람 입장에서는 채팅서버니까 문자열 변환해서 읽고 요런 식.
(받을 때의 편리성을 위해서)
그리고 DataPacket의 리시브가
일단 누가 보내야 받을 거잖아요.
.receive(dp) 여기서 멈출까요?
찾아보니까 멈춰있게 구현이 된다.
데이터를 받는다고 나갔는데 빈손으로 들어올수는 없으니까
(이걸 block 이라고 표현)
근데 진짜 프로그램이라면 갑자기 block되면 망한다.
이러한 문제를 쓰레드 통해서 해결하면 된다.
보내는 쓰레드 따로, 받기만 하는 쓰레드 따로 둬서 일처리
*/
3.
public class ClientTCP {
public static void main(String[] args) throws IOException {
String server ="172.30.1.61"; //cmd : ipconfig 로 확인
int port = 7777;
// 서버를 켜고 클라이언트를 켜니까
// 얘가 접속을 하면 서로 연결된 소켓을 하나씩 받는다(s에서도 받고 c에서도 받고)
Socket c = new Socket(server, port); // 소켓 생성
// 클라이언트 소켓은 서버에게 보내는 것.
// cf. 서버소켓은 말 그대로 내가 서버니까 나에게 들어오기만 할 것임.
InputStream is = c.getInputStream(); // 인풋스트림이니까 얘는 여기다가 읽어오겠다!
DataInputStream dis = new DataInputStream(is);
for(int i = 1; i<= 10; i++) {
int j = dis.read(); // 읽어오는 거니까 read
System.out.println("서버로부터 받은 데이터 " + j + "출력"); // 매개변수로 들어가있던 j
}
c.close(); // 소캣 닫기
}
}
/*
보통 보내는 사람이 server주소를 써서 난 여기에 보낼 거야 선언을 하는데,
지금 얘는 받는 사람임에도 불구하고 어디서 받을거야 주소를 선언하고 받고 있다.
최종 정리를 하면
TCP는 클라이언트가 서버에 요청을 해야하기 때문에
클라이언트 측에서 서버의 ip 주소를 알아야 한다.
UDP는 보내는 입장이 어디에 보낼지 받는사람이 직접 택배에 주소를 써서 보내야하니까
여기다가 직접 보낼 때 주소를 적어야 한다.(Sender에 주소 적음)
*/
4.
public class ServerTCP {
public static void main(String[] args) throws IOException {
int port = 7777; // 포트번호
int times = 10; // 반복 client 10명 들어오게 해주겠다.
ServerSocket ss = new ServerSocket(port); //서버 소켓 생성
int i = 1; // times와 비교를 위한 변수
while(i<= times) { // 반복문 times와 같아질때까지 반복
Socket s = ss.accept(); // accept함수를 통한 소켓 생성 // 여기서는 서버가 받는 역할을 수행
// 클라이언트 들어올 때까지 여기서 기다림.
// 클라이언트 접속이 되면 그때부터 아래로 내려간다.
// 왜 소켓이 리턴되냐면, 클라이언트랑 서버랑 같이 쓰는 소켓이 하나 나오기 때문.
// 그러면 서로 왔다갔다가 가능해진단 소리지
OutputStream os = s.getOutputStream(); // accept로 받아왔으니 accept 한 곳에다가 쓰겠다.
// 소켓으로 out 밖으로 보내는 스트림을 생성
DataOutputStream dos = new DataOutputStream(os);
// OutputStrema을 인자로 넣어서 DataoutputStream의 객체를 생성
for(int j = 1; j<=10;j++) { // 10번 반복
dos.write(j); // DataOutputStream을 이용해서 쓰기 실행 1~10
// 나오면 클라이언트가 받는다. 이 j가 클라이언트의 j로 출력됨.
}
s.close(); //s도 소켓이니까, 다 썼으면 커넥션 끊어야죠.
i++; // 10번 접속할 수 있게 만들어줌.
}
ss.close();
}
}
/*
TCP는 연결 지향적
일단 먼저 연결 루트를 미리 깔아놓고 데이터를 보낸다.
그래서 이름도 다르다. 데이터그램소켓보다는 서버소켓이라는 명칭을 썼고,
서버-클라이언트 개념이 도입되어 좀 더 연결의 중요성을 강조.
그런데 쓰고 출력을 한다는 건 명확한 기준이 있어야 한다는 건데.
s.getOutputStream()은 s에 쓰일 수 있는 스트림이 오게 된다는 것.
*/
728x90
'Java > Mega' 카테고리의 다른 글
<보충> Day32,33 통신 예제 설명추가 (2) (0) | 2023.05.10 |
---|---|
<보충> Day33,34 자바 GUI 이모저모 (0) | 2023.05.10 |
<보충>Day32,33 통신 / 알아두면 좋은 것들 (0) | 2023.05.10 |
자바 퀴즈 아이디어 정리 (3) (0) | 2023.05.07 |
자바 퀴즈 아이디어 정리 (2) (0) | 2023.05.07 |
Comments