『자바의 신 3판』 을 읽고 내용 정리 및 공부한 내용을 정리한 글입니다.
서적: 자바의 신 3판 구입처
사용자들이 바로 옆에 있는 장비와 데이터를 주고 받는 작업을 보통 네트워킹(networking)이라고 한다.
자바에서 TCP 통신을 수행하려면 소켓 클래스를 사용해 소켓 통신을 한다.
많은 생성자가 있는데, 그 중 일부만 정리했다.
생성자 | 설명 |
---|---|
Socket() | 소켓 객체만 생성 |
Socket(Proxy proxy) | 프록시 관련 설정과 함께 소켓 객체만 생성 |
Socket(SocketImpl impl) | 사용자가 지정한 SocketImpl 객체를 사용하여 소켓 객체만 생성 |
Socket(InetAddress address, int port) | 소켓 객체 생성 후 address와 port를 사용하는 서버에 연결 |
Socket(String host, int port) | 소켓 객체 생성 후 host와 port를 사용하는 서버에 연결 |
Socket(InetAddress address, int port)
이다.소켓 연결에 문제가 있을 경우 일정 시간 이후 끊어주는 것을 말한다.
Socket socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(host, port);
socket.connect(socketAddress, 30000);
ServerSocket serverSocket = new new ServerSocket(port);
serverSocket.setSoTimeout(40000);
서버에서 데이터를 받을 때 사용하는 클래스로, 클라이언트 요청이 생기면 Socket 객체를 생성해서 전달하는 메소드를 제공한다.
생성자 | 설명 |
---|---|
ServerSocket() | 서버 소켓 객체만 생성한다. |
ServerSocket(int port) | 지정된 포트를 사용하는 서버 소켓을 생성한다. |
ServerSocket(int port, int backlog) | 지정된 포트와 backlog 개수를 가지는 소켓을 생성한다. |
ServerSocket(int port, int backlog, InetAddress bindAddr) | 지정된 포트와 backlog 개수를 가지는 소켓을 생성하며, bindAddr에 있는 주소에서의 접근만을 허용한다. |
리턴 타입 | 메소드 | 설명 |
---|---|---|
Socket | accept() | 새로운 소켓 연결을 기다리고, 연결이 되면 Socket 객체를 리턴 |
void | close() | 소켓 연결을 종료 |
public void startServer() {
ServerSocket server=null;
Socket client=null;
try {
// 9999 포트로 소켓 객체 생성
server = new ServerSocket(9999);
while(true) {
// 다른 원격 호출 대기
client = server.accept();
// InputStream 객체를 받아 데이터 읽기
InputStream stream = client.getInputStream();
BufferedReader in = new BufferedReader(
new InputStreamReader(stream)
);
String data=null;
StringBuilder receivedData = new StringBuilder();
while( (data=in.readLine()) != null ) {
receivedData.append(data);
}
System.out.println("Received data:" + receivedData);
// 종료
in.close();
stream.close();
client.close();
// 넘어오는 데이터가 "EXIT" 이라면 종료
if(receivedData != null && "EXIT".equals(receivedData.toString())) {
break;
}
}
} catch (Exception e) {
...
} finally {
// server.close()
}
}
public void sendSocketData(String data) {
Socket socket=null;
try {
// 같은 장비이므로 127.0.0.1 선언, 9999 포트로 연결
socket = new Socket("127.0.0.1",9999);
Thread.sleep(1000);
// OutputStream으로 데이터 전송
OutputStream stream = socket.getOutputStream();
BufferedOutputStream out = new BufferedOutputStream(stream);
byte[] bytes = data.getBytes();
out.write(bytes);
// 종료
out.close();
} catch (Exception e) {
...
} finally {
// socket.close();
}
}
💡 양방향 통신 가능
클라이언트에서 서버로 데이터를 전송할 수도 있고, 반대로 받을 수도 있다.
UDP는 TCP와 달리 데이터가 제대로 전달되었다는 보장을 하지 않으므로, 데이터의 유실이 있어도 문제가 없을 때 사용한다.
TCP와 다르게 클래스 하나에서 보내는 역할과 받는 역할을 모두 수행 가능하다.
생성자
생성자 | 설명 |
---|---|
DatagramSocket() | 소켓 객체 생성 후 사용 가능한 포트로 대기 |
DatagramSocket(DatagramSocketImpl impl) | 사용자가 지정한 SocketImpl 객체를 사용하여 소켓 객체만 생성 |
DatagramSocket(int port) | 소켓 객체 생성 후 지정된 포트로 대기 |
DatagramSocket(int port, InetAddress address) | 소켓 객체 생성 후 address와 port를 사용하는 서버에 연결 |
DatagramSocket(SocketAddress address) | 소켓 객체 생성 후 address에 지정된 서버로 연결 |
메소드
리턴 타입 | 메소드 | 설명 |
---|---|---|
void | receive(DatagramPacket packet) | 메소드 호출 시 요청을 대기하고, 만약 데이터를 받았을 때에는 packet 객체에 데이터를 저장 |
void | send(DatagramPacket packet) | packet 객체에 있는 데이터 전송 |
void | close() | 소켓 연결을 종료 |
TCP에서는 스트림 객체를 얻어 데이터를 주고받았다면, UDP에서는 DatagramPacket 객체로 데이터를 주고받는다.
생성자
데이터를 받기 위한 생성자는 단 하나다.
생성자 | 설명 |
---|---|
DatagramPacket(Byte[] buf, int length) | length의 크기를 갖는 데이터를 받기 위한 객체 생성 |
DatagramPacket(Byte[] buf, int length, InetAddress address, int port) | 지정된 address와 port로 데이터를 전송하기 위한 객체 생성 |
DatagramPacket(Byte[] buf, int length, int length, int offset) | 버퍼의 offset이 할당되어 있는 데이터를 전송하기 위한 객체 생성 |
DatagramPacket(Byte[] buf, int offset, int length, InetAddress address, int port) | 버퍼의 offset이 할당되어 있고, 지정된 address와 port로 데이터를 전송하기 위한 객체 생성 |
DatagramPacket(Byte[] buf, int offset, int length, SocketAddress address) | 버퍼의 offset이 할당되어 있고, 지정된 소켓 address로 데이터를 전송하기 위한 객체 생성 |
DatagramPacket(Byte[] buf, int length, SocketAddress address) | 지정된 소켓 address로 데이터를 전송하기 위한 객체 생성 |
메소드
리턴 타입 | 메소드 | 설명 |
---|---|---|
byte[] | getData() | 전송받은 데이터를 리턴 |
int | getLength() | 전송받은 데이터의 길이를 리턴 |
public void startServer() {
DatagramSocket server = null;
try {
// 9999 포트로 소켓 생성
server=new DatagramSocket(9999);
// 데이터를 받기 위한 DatagramPacket 객체 생성
int bufferLength = 256;
byte[] buffer = new byte[bufferLength];
DatagramPacket packet = new DatagramPacket(buffer, bufferLength);
while(true){
// 데이터를 받기 위해 대기
server.receive(packet);
// byte[]로 넘어온 데이터를 String으로 변환 후 출력
int dataLength = packet.getLength();
String data = new String(packet.getData(), 0, dataLength);
System.out.println("Received data:" + data);
// 넘어온 문자가 "EXIT" 면 종료
if(data.equals("EXIT")) {
break;
}
}
} catch (Exception e) {
...
} finally {
// server.close();
}
}
public void sendDatagramData(String data) {
try {
// DatagramSocket 객체 생성
DatagramSocket client = new DatagramSocket();
// 데이터를 받을 서버 IP 설정
InetAddress address = InetAddress.getByName("127.0.0.1");
// 전송할 데이터를 byte[]로 변환
byte[] buffer = data.getBytes();
// 데이터를 전송하기 위한 DatagramPacket 객체 생성 및 전송
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length, address, 9999);
client.send(packet);
// 종료
client.close();
Thread.sleep(1000);
} catch(Exception e) {
e.printStackTrace();
}
}
자바 API에서 제공하는 URL 클래스로 간단한 웹 페이지 요청을 할 수 있다. 하지만, 이 클래스는 연결에 대한 상세한 설정을 할 수 없기 때문에 권장하지 않는다.
일반적으로 Apache의 Http Components를 많이 사용한다.
💡 Http Compoents 홈페이지: http://hc.apache.org/
Me: TCP 통신은 데이터를 받았는지를 확인하고, UDP는 데이터가 제대로 전달되었는지 확인하지 않는다
Me: 특정 프로그램에 접속하기 위해 사용한다.
Me: TCP 통신일 때, 서버에서 데이터를 주고 받기 위해 사용한다.
Me: 클라이언트가 연결될 때까지 대기하다가, 연결 되면 새로운 Socket 객체를 리턴한다.
Me: 데이터를 받거나 전송하기 위해 사용하는 클래스이다.
Me: UDP 통신에서 데이터를 주고받는 역할이다.
Me: UDP 통신에서 데이터를 주거나 받기 위해 사용한다.
💡 책에 있는 내용이 아닙니다.
책을 읽으며 설명이 더 필요하거나, 추가로 궁금한 점에 대해 질문 형식으로 작성 후, 답을 구해보고 있습니다.
참고한 사이트나 영상은 [출처]로 달아두었으며, 오류 지적은 언제나 환영합니다.
네트워크 상에서 데이터를 주고받기 위한 프로세스 간 통신의 엔드 포인트이다. OSI 7 계층에서 응용 계층에 속하는 프로세스들은 데이터 송수신을 위해 반드시 소켓을 거쳐 전송 계층으로 데이터를 전달해야 한다. 즉, 소켓은 전송 계층과 응용 프로그램 사이의 인터페이스 역할을 하며 떨어져 있는 두 호스트를 연결해준다.
HTTP 통신은 데이터 전달이 필요한 경우에만 요청을 보내는 상황에 유리하고, 소켓 통신은 실시간 동영상 스트리밍이나 온라인 게임 등 실시간 연결이 필요할 때 사용한다.
이건 개인적으로 낸 결론인데, 자바의 신 자료구조 설명에서 서버에 접속 중인 사용자들이, 가장 먼저 들어왔는데 순번이 밀려 뒤에 들어온 사람이 먼저 나가면 안되지 않겠냐는 이야기를 했었다.
그래서 먼저 들어온 게 먼저 나가는 큐를 사용하는 거 같다.
💡 아래 참고 사이트에서 더 자세할 설명과 예제를 볼 수 있다.
사전적인 의미는 “대리인”이라는 뜻으로, 어떠한 대상 객체에 대한 인터페이스 역할을 하는 디자인 패턴을 말한다.
즉, 클라이언트가 직접 대상 객체에 접근하는 것이 아니라 중간에 프록시라는 대리인을 거쳐 간접적으로 접근하게 하는 패턴이다.
객체지향 설계의 원칙 중 하나인 DIP(의존성 역전 원칙)을 따르며, 코드의 유연성과 확장성을 향상시키는데 기여한다.
이는 대상 클래스가 민감한 정보를 가지고 있거나, 인스턴스화 하기에 무겁거나, 원본 객체를 수정할 수 없는 상황일 때를 극복하기 위해 사용한다.
Spring Framework의 AOP와도 밀접한 관련이 있다.
클라이언트와 실제 대상 객체 사이에 위치하는 중간 객체를 프록시 객체라고 부른다.
호스트(Host)는 네트워크에 연결된 실제 장치를 나타내는 용어이며, 어드레스(Address)는 해당 장치를 식별하기 위한 값을 나타내는 용어이다.
SSL(Secure Socket Layer)은 컴퓨터 네트워크 상에서 정보를 안전하게 전송하기 위한 보안 프로토콜 중 하나이다. 데이터를 암호화하고, 데이터의 기밀성과 무결성을 보장하며, 클라이언트와 서버 간의 안전한 통신을 보장한다.
SSL는 과거에 사용되던 보안 프로토콜로, HTTPS의 기본 포트로 443을 사용한다.
SSL의 후속으로 개발된 TLS(Transport Layer Security)도 기본 포트로 443을 사용한다.
물론, 이 기본 포트는 웹 서버의 설정을 수정하거나 프록시 서버를 통해 특정 포트로 전달하는 방식 등으로 변경할 수 있다.
💡 무언가 더 알아야 하는 내용이 있을까 싶어 찾아봤지만 본문에 나온 내용과 별반 다를 바 없다.
URL 클래스는 URL을 파싱하고 간단한 웹 리소스에 대한 연결을 만드는 데 사용한다.
기본적인 URL 관리 및 접속 기능을 제공하지만, HTTP에 특화된 고급 기능은 제공하지 않는다.
Apache 에서 제공하는 HTTP 통신을 위한 라이브러리이다. 주요 구성 요소로는 HttpClient와 HttpServer가 있으며, 다양한 기능을 지원한다.
Java 소켓에 대한 연결 시간 초과 VS 읽기 시간 초과
SSL과 TLS 비교 - 통신 프로토콜 간의 차이점 - AWS
SSL인증서는 443포트만 사용해야 하나요? > 자주묻는질문 | SSL 인증서 써트코리아- DigiCert 공식 제휴사