728x90
socket
- 컴퓨터 사이에 네트워킹을 위한 통신 채널
- 클라이언트 프로세스는 소켓을 통해 서버 프로세스와 데이터를 주고받을 수 있음
- 전화와 같이 신뢰할 수 있는 양방향 통신을 제공
- 프로세스 간의 통신에 사용되는 양쪽 끝단(endpoint)을 의미
- 소켓은 TCP/IP 레이어(4계층)에서 작동하고, 웹 소켓은 HTTP 레이어(7계층)에서 작동함
- 인터넷 프로토콜에 기반, 대부분의 네트워크 소켓은 인터넷 소켓임
과정
- 시스템을 구축할 때는 서버 프로세스를 위한 server socket 객체를 만듦
- 서버 서비스가 원활하게 진행되면 클라이언트 프로세스를 만듦
- 시스템 구축을 완료하면 고유한 IP 주소와 포트 번호를 가진 서버와
여기에 접속한 클라이언트는 소켓을 통한 양방향 통신이 가능해짐
2022.10.31 - [프로그래밍 언어/Java] - [Java] 정규 표현식, Network
TCP (Transmission Control Protocol) 연결지향 | UDP (User Datagram Program) 비연결형 |
신뢰도 ▲ | 신뢰도 ▼ |
연결 작업 선행 | 연결 작업 필요 없음 |
가상회선, 스트림 소켓 | |
실시간으로 데이터를 주고 받음 | |
주소 정보를 bind 함수로 묶어서 지속적인 데이터 송수신 | 소켓에 데이터를 보낼 때마다 주소 정보를 같이 할당 |
채팅, 인터넷 등에 사용 | TV, 스트리밍 |
계속 연결 상태를 유지해야 하므로 리소스 소모가 큼 | 수신 여부는 상관하지 않음 |
Socket, ServerSocket | DatagramSocket, DatagramPacket, MulticlastSocket |
TCP 소켓
2023.11.01 - [Study/Network] - [네트워크] HTTPS & SSL TLS, 혼합 콘텐츠
- TLS 핸드쉐이크는 TCP 소켓 프로그래밍에서 보안 소켓 연결을 초기화하는 과정 중 하나 (accept 전에 완료)
- TLS (Transport Layer Security)는 인터넷에서 데이터를 안전하게 전송하기 위한 프로토콜 중 하나이며, SSL (Secure Sockets Layer)의 후속 버전
- TLS 핸드쉐이크는 클라이언트와 서버 간의 보안 통신을 설정하기 위한 프로세스
통신 과정
- 서버소켓은 연결요청이 올 때마다 새로운 소켓을 생성하여 상대편 소켓과 통신할 수 있도록 연결
- 실제적인 데이터 통신은 서버소켓과 관계없이 소켓 간에 이루어짐
- 여러 개의 소켓이 하나의 포트를 공유해서 사용할 수 있지만, 서버소켓은 포트를 독점(바인딩 포트)
한 포트를 둘 이상의 서버소켓과 연결이 가능하면 클라이언트는 어떤 것과 연결되어야 하는지 알 수 없으므로
Socket & ServerSocket 클래
- Socket: 프로세스간의 통신을 담당
InputStream과 OutputStream을 가짐 - ServerSocket: 포트와 연결되어 기다리다 외부의 연결요청이 들어오면 Socket을 생성해서 소켓과 소켓간의 통신이 이루어지도록 함
한 포트에 하나의 ServerSocket만 연결 (프로토콜이 다르면 같은 포트 공유 가능)
예제
더보기
TcpIpServer
package chapter16;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
public class TcpIpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
//1. 서버소켓을 생성하여 7777번 포트와 결합(bind)
serverSocket = new ServerSocket(7777);
System.out.println(getTime() + " 서버가 준비되었습니다.");
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
try {
System.out.println(getTime() + " 연결요청을 기다립니다.");
//2. 서버소켓은 클라이언트의 연결요청이 올 때까지 실행을 멈추고 계속 기다림
//2-1. 클라이언트의 연결요청이 오면 클아이언트 소켓과 통신할 새로운 소켓을 생성
Socket socket = serverSocket.accept();
System.out.println(getTime() + socket.getInetAddress() + "로부터 연결요청이 들어왔습니다.");
//3. 소켓의 출력스트림을 얻음
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
//4. 원격 소켓(remote socket)에 데이터를 보냄
dos.writeUTF("[Notice] Test Message1 from Server.");
System.out.println(getTime() + " 데이터를 전송했습니다.");
//5. 스트림과 소켓을 닫아줌
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}//end while
}
//현재 시간을 문자열로 반환하는 함수
static String getTime() {
SimpleDateFormat f = new SimpleDateFormat("[hh:mm:ss]");
return f.format(new Date());
}
}
- accept() 메소드는 클라이언트가 연결 요청을 하기 전까지 블로킹(스레드가 대기 상태)되므로 UI를 생성하는 스레드나, 이벤트를처리하는 스레드에서 accpet() 메소드를 호출하지 않도록 해야함
- 클라이언트 프로그램이 서버에 연결을 요청하면, 서버소켓은 새로운 소켓을 생성하여 클라이언트 프로그램 소켓(원격소켓)과 연결
- 새로 생성된 소켓은 [Notice] Test Message1 from Server. 라는 데이터를 원격 소켓에 전송하고 연결을 종료
- 그리고 서버소켓은 다시 클라이언트 프로그램의 요청을 기다림
- 클라이언트 프로그램의 요청을 지속적으로 처리하기 위해 무한반복문 사용 (ctrl+C로 강제 종료 해야 함)
TcpIpClient
package chapter16;
import java.io.*;
import java.net.*;
public class TcpIpClient {
public static void main(String[] args) {
try {
String serverIp = "127.0.0.1";
System.out.println("서버에 연결중입니다. 서버 IP: " + serverIp);
//1. 소켓을 생성하여 서버에 연결을 요청
Socket socket = new Socket(serverIp, 7777);
//2. 연결되면 소켓의 입력스트림을 얻음
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
//소켓으로부터 받은 데이터를 출력
System.out.println("서버로부터 받은 메세지: " + dis.readUTF());
System.out.println("연결을 종료합니다.");
//스트림과 소켓을 닫음
dis.close();
socket.close();
System.out.println("연결이 종료되었습니다.");
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 먼저 서버 포트를 열고 클라이언트 서버 구동
스레드 병렬 처리
- 서버를 실행하는 main 스레드가 직접 입출력 작업을 담당하게 되면 입출력이 완료될 때까지 다른 작업을 할 수 없음
- 그렇기 때문에 accept(), connect(), read(), write()는 별도의 작업 스레드를 생성하여 병렬적으로 처리하는게 좋음
- 클라이언트의 폭증으로 인해 서버의 과도한 스레드 생성을 방지하려면 스레드풀을 사용하는 것이 바람직함
내용 추가
UDP 소켓
- DatagramSocket과 DatagramPacket(데이터 담음)을 사용
- 비연결형이므로 ServerSocket(TCP에서는 Socket, ServerSocket 사용)이 필요하지 않음
예제
더보기
UdpClient
package chapter16;
import java.io.IOException;
import java.net.*;
public class UdpClient {
public void start() throws IOException, UnknownHostException {
DatagramSocket datagramSocket = new DatagramSocket();
InetAddress serverAddress = InetAddress.getByName("127.0.0.1");
//데이터가 저장될 공간으로 byte배열 생성
byte[] msg = new byte[100];
DatagramPacket outPacket = new DatagramPacket(msg, 1, serverAddress, 7777);
DatagramPacket inPacket = new DatagramPacket(msg, msg.length);
datagramSocket.send(outPacket);
datagramSocket.receive(outPacket);
System.out.println("current server time : " + new String(inPacket.getData()));
datagramSocket.close();
} //start()
public static void main(String[] args) {
try {
new UdpClient().start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
UdpServer
package chapter16;
import java.io.IOException;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class UdpServer {
public void start() throws IOException, UnknownHostException {
DatagramSocket socket = new DatagramSocket(7777);
DatagramPacket inPacket, outPacket;
byte[] inMsg = new byte[10];
byte[] outMsg;
while(true) {
//데이터를 수신하기 위한 패킷을 생성
inPacket = new DatagramPacket(inMsg, inMsg.length);
socket.receive(inPacket); //패킷을 통해 데이터를 수신함
//수신한 패킷으로부터 client의 IP주소와 Port를 얻음
InetAddress address = inPacket.getAddress();
int port = inPacket.getPort();
//서버의 현재 시간을 시분초 형태로 반환
SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
String time = sdf.format(new Date());
outMsg = time.getBytes(); //time을 byte배열로 반환
//패킷을 생성해서 client에게 전송(send)
outPacket = new DatagramPacket(outMsg, outMsg.length, address, port);
socket.send(outPacket);
}
}//start()
public static void main(String[] args) {
try {
new UdpServer().start(); //UDP서버 실행
} catch (Exception e) {
e.printStackTrace();
}
}
}
웹소켓
- http(웹)에서 실시간 통신 할 수 없는 문제를 해결하기 위해 나온 기술
웹에서 TCP 소켓을 사용할 수 있지만 메시지를 보내는 것이 개발측면에서 더 적합하기 때문에 발전 됨 - 소켓은 TCP/IP 레이어(4계층)에서 작동하고, 웹 소켓은 HTTP 레이어(7계층)에서 작동함
- 평문 메시지 전송 방식으로 SSL/TLS 보안 계층으로 암호화되어야 데이터 탈취 방지할 수 있음
- HTML5에서 소개된 기술, 양방향 통신을 하고, IP와 포트를 통한 통신
- TCP 소켓 통신은 바이트 스트림을 통해 데이터 전송, 웹 소켓은 메시지 형식의 데이터를 다룸
웹 소켓은 TCP 소켓과 구분되는 것이 아니라 TCP 소켓의 추상화된 형태
728x90
'Study > Network' 카테고리의 다른 글
[네트워크] HTTPS & SSL TLS, 혼합 콘텐츠 (0) | 2023.11.01 |
---|---|
[네트워크] 로드 밸런싱, 공인 IP & 사설 IP (0) | 2023.09.01 |