![[기술정리]소켓 통신](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog%3Ftitle%3D%255B%25EA%25B8%25B0%25EC%2588%25A0%25EC%25A0%2595%25EB%25A6%25AC%255D%25EC%2586%258C%25EC%25BC%2593%2520%25ED%2586%25B5%25EC%258B%25A0%26logoUrl%3Dhttps%253A%252F%252Finblog.ai%252Finblog_logo.png%26blogTitle%3D%25EC%2586%25A1%25EC%258A%25B9%25ED%2598%2584%25EC%259D%2598%2520%25EB%25B8%2594%25EB%25A1%259C%25EA%25B7%25B8&w=2048&q=75)
정의
네트워크를 통해 데이터를 주고받는 방식
서버와 클라이언트 간의 실시간 데이터 교환
OSI 7 계층 중 전송 계층과 응용 프로그램 사이의 인터페이스 역할
소켓
- 네트워크에서 프로세스 간 통신을 지원하는 소프트웨어 구조
- 네트워크에서 데이터를 송수신하기 위해 ip주소와 포트 번호로 소켓 설정
소켓 통신의 주요 프로토콜
TCP(Transmission Control Protocol)
- 연결 지향형 프로토콜 : 데이터를 보내기 전에 반드시 연결
- 데이터의 신뢰성 보장 : 패킷이 손실되거나 순서가 뒤바뀌는 경우 재전송
UDP(User Datagram Protocol)
- 비연결형 프로토콜 : 연결 설정 없이 데이터 전송
- 데이터의 신뢰성 보장 X : 빠른 전송이 목적
소켓 통신의 구성
서버(Server)
- 클라이언트의 요청을 받아들이고 처리하는 역할
- 동작
- 소켓 생성(socket())
- 포트 바인딩
- 연결 대기(listen())
- 요청 수락(accept())
클라이언트(Client)
- 서버와 통신을 시작하고 요청을 보내는 역할
- 동작
- 소켓 생성(socket())
- 서버에 연결(connect())
소켓 통신의 흐름
- 서버 소켓 생성 : 서버는 소켓을 생성하고 대기
- 클라이언트 소켓 생성 : 클라이언트는 서버로 연결 시도
- 연결 수락 : 서버는 클라이언트의 연결 요청을 수락
- 데이터 송수신 : 서버와 클라이언트는 데이터를 교환
- 연결 종료
예제
서버(Server)
public class MyServer {
public static void main(String[] args) {
try {
//1. 리스너 생성 및 대기
ServerSocket serverSocket = new ServerSocket(20000); //서버소켓 포트번호를 지정 생성
Socket socket = serverSocket.accept();
//2. 반이중 연결(버퍼 달기)
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
//3. 요청 받고, 응답하기
while(true) {
String line = br.readLine();
String msg = parser(line);
pw.println(msg);
Thread.sleep(10);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private static String parser(String br){
String msg = "404";
String[] s = br.split(":");
if(s[0].equals("buyer")){
if(s[1].equals("1"))
msg="사과";
else if(s[1].equals("2"))
msg="라면";
}
if(s[0].equals("seller")){
if(s[1].equals("1"))
msg="당근";
else if(s[1].equals("2"))
msg="우유";
}
return msg;
}
}
- ServerSocket을 사용하여 포트 20000을 지정, 연결 요청을 대기
- BufferReader을 활용하여 클라이언트 요청 메세지를 읽음
- PrintWriter을 활용하여 응답 메세지 보냄
- String parser 메서드를 활용하여 지정된 메세지가 오면 지정된 응답을 반환
- while을 통해 연결을 계속 유지(데몬으로 만들면 계속 유지가능)
클라이언트(Client)
public class MyClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost",20000);
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Scanner scan = new Scanner(System.in);
while(true){
String request = scan.nextLine();
pw.println(request);
String line = br.readLine();
System.out.println(line);
}
}
}
- 소켓 객체를 생성하여 포트번호 20000에 연결
- Scanner을 통해 사용자 입력을 받아 서버에 요청을 전송
- 서버로 지정된 요청을 하면 서버에서 지정된 응답을 받음
- while을 통해 연결을 계속 유지(데몬으로 만들면 계속 유지가능)
다중 클라이언트를 지원
- 스레드를 늘려(스레드풀 사용가능) 다중 클라이언트에 응답 가능하게 할 수 있음
Share article