TCP & UDP
TCP : Transmission Control Protocol
TCP↓
- 연결지향 프로토콜
: 클라이언트와 서버가 연결된 상태에서 데이터를 주고받는 프로토콜
- 클라이언트가 연결요청 -> 서버가 연결 수락 -> 통신 선로 고정 -> 고정된 통신선로를 통해 순차적으로 데이터 전달
- 정확하고 안정적으로 데이터 전달 (신뢰성)
- 흐름제어와 혼잡제어를 지원하며 데이터의 순서를 보장함
- 흐름제어 : 보내는 측과 받는 측의 데이터 처리속도 차이 조절.
TCP는 패킷을 성공적으로 전송하면 ACK(Acknowledgement)라는 신호를 보내는데, 만약 ACK 신호가 제 시간에 도착하지 않으면 Timeout 발생하여 패킷손실이 발생한 패킷에 대해 다시 전송해 줌
(1번 보냈어, 받았다못받았다 말이없어, 1번 다시 보내)
- 혼잡제어 : 네트워크 내 패킷수가 넘치게 증가하지 않도록 방지
- 데이터를 보내기 전에 반드시 연결이 형성되어야 함
- 상대적으로 UDP보다 데이터 전송 속도가 느릴 수 있음
UDP : User Datagram Protocol
UDP↓
- 비연결형 프로토콜
- 연결설정이 없으며 혼잡제어를 하지 않기 때문에 TCP보다 빠름
- 데이터전송에 대한 보장을 하지 않기 때문에 패킷손실 발생할 수 있음
TCP & UDP 비교
가장 기본적인 프로토콜
TCP
TCP 서버의 역할
1. 클라이언트가 연결요청을 해오면 연결을 수락하는 것
2. 연결된 클라이언트와 통신하는 것
- 역할별로 별도의 클래스 제공함
- 연결요청을 기다리면서 연결수락을 담당하는 ServerSocket
- 연결된 클라이언트와 통신을 담당하는 Socket
소켓(socket) ?
서로 커뮤니케이션하기 위해 사용하는 양 끝단 역할 하는 객체. 전화기에 많이 비유함
- 바인딩포트
- 클라이언트가 접속할 포트
- 고정된 포트 번호에 바인딩해서 실행
ServerSocket 클래스
연결 요청을 기다리면서 연결수락을 담당
객체생성(포트바인딩)
- 생성자에 바인딩포트를 대입
- 어떤 포트로 소켓접속을 받아들일지 설정
- ~1024까지는 쓰면 안됨
ServerSocket server = new ServerSocket(7777);
accept() 메서드
- 클라이언트의 연결요청을 수락하기 위해 accept() 메서드 실행
- 클라이언트가 요청하기 전까지 blocking => 스레드가 대기상태가 된다는 뜻
- 클라이언트가 연결 요청하면 accept() 메서드는 클라이언트와 통신할 Socket을 만들어 반환 : 연결수락
close()
- 더 이상 클라이언트 연결 수락이 필요없으면 ServerSocket.close()호출해서 포트 언바인딩 시켜야함
- 그래야 다른 프로그램에서 해당 포트를 재사용할 수 있음
Socket 클래스
연결된 클라이언트와 통신을 담당
객체생성
- 객체생성과 동시에 연결요청을 하려면
- 생성자의 매개값으로 서버의 IP주소와 바인딩 포트번호 제공하면 됨
- 외부 서버에 접속하려면 localhost(127.0.0.1) 대신 정확한 IP 입력
String serverIp = "127.0.0.1";
Socket socket = new Socket(serverIp, 7777);
close()
- 클라이언트 프로그램 종료하거나 강제적으로연결을 끊고 싶을 때
TCP 채팅프로그램예제
Socket 데이터 통신
클라이언트가 연결요청(accept())하고 서버가 연결수락(connect())했다면
양쪽의 Socket 객체로부터 각각 입력/출력 스트림을 얻을 수 있음
InputStream is= socket.getInputStream();
OutputStream os = socket.getOutputStream();
UDP
- 비연결지향형 프로토콜
- 발신자가 일방적으로 데이터를 발신하는 방식
- 편지에 비유
- 봉투(패킷)에 수신자의 주소(원격지IP와 포트)와 발신자의 주소(로컬IP와 포트)를 씀
=> 봉투(패킷) 안에 편지(전송할 데이터)를 넣고 보냄
- 발신자는 수신자가 데이터를 받았는지 못받았는지 알 수 없음
- 최근에 보낸 데이터보다 나중에 보낸 데이터가 먼저 갈수도 있고 전혀 도착하지 않을 수도 있음
DatagramSocket 클래스
발신점과 수신점에 해당하는 클래스
DatagramPacket 클래스
주고받는 패킷클래스
발신자 구현
DatagramSocket 객체 생성
DatagramSocket socket = new DatagramSocket();
Datagrampacket 객체 생성
private DatagramPacket outPacket = new DatagramPacket(전송할 바이트배열, 전송할 배열사이즈, 수신자IP, 포트번호);
socket.send(outPacket)
- 수신자에게 데이터 전달하기
- 전송할 데이터와 수신자정보를 담은 Packet을 매개값으로 send() 메서드 호출
socket.send(outPacket);
수신자 구현
DatagramSocket 객체 생성
private DatagramSocket socket = new DatagramSocket(8888);
DatagramPacket 객체 생성
DatagramPacket inPacket = new Datagrampacket(byteArr, byteArr.length);
- 첫번째 매개값 : 읽은 패킷 데이터를 저장할 바이트배열
- 두번째 매개값 : 읽을 수 있는 최대 바이트
첫번째 매개 바이트배열의 크기와 같거나 작아야 함
- 일반적으로 첫 번째 바이트 배열의 크기를 줌
receive(inPacket)
- DatagramSocket 클래스의 receive() 메서드를 호출
- receive() 메서드는 패킷을 받을 때까지 블로킹
- 패킷이 도착하면 매개값으로 주어진 DatagramPacket에 패킷 내용 저장
socket.receive(inPacket);
getData()
- receive() 메서드로 패킷을 읽었다면
- DatagramPacket 클래스의 getData() 메서드로 데이터가 저장된 바이트 배열 얻어낼 수 있음
- 받은 데이터가 인코딩된 문자열이라면 디코딩으로 문자열 얻으면 됨
String data = new String(inPacket.getData());
참고
- TCP : 이것이 자바다 p.1056
- TCP : 이것이 자바다 p.1087