본문 바로가기
BackEnd/Java

[Java] 소켓 Socket

by summer_light 2021. 8. 3.

소켓 socket

소켓을 사용하는 통신을 말한다. 

소켓이란, 프로세스간 통신에 사용되는 양 끝단 영역을 말한다.
java.net 안에 소켓이 있다. tcp/udp를 사용하는 소켓프로그래밍이 대표

 

 

 


TCP와 UDP

  • TCP : '전화'
    • 데이터를 전송하기 전에 먼저 상대편과 연결한 후 데이터 전송
    • 전송 여부를 확인한다. 그러므로 실패하면 재전송한다.
  • UDP : '전보'
    • 연결하지 않고 데이터를 전송
    • 전송 여부를 확인하지 않는다. 그러므로 데이터를 순서대로 수신한다는 보장이 없다.
    • EX) ZOOM 같은 프로그램은 중간에 끊기더라도 별 문제 없이 진행된다. 

 

 

서버 클라이언트의 1:1통신

서버가 먼저 실행되어 클라이언트의 연결 요청을 기다린다.

  1. 하나의 포트에는 하나의 소켓이 연결된다.(프로토콜이 다르면 다른 포트로)
  2. 서버는 서버소켓을 사용해서 서버 컴퓨터의 특정 포트에서 클라이언트 요청을 처리
  3. 클라이언트는 접속할 서버의 IP주소와 포트정보로 소켓을 생성해서 서버에 연결을 요청
  4. 서버 소켓은 클라이언트의 요청을 받으며 서버에 새로운 소켓을 생성해서 클라이언트와 연결
  5. 클라이언트의 소켓과 서버 소켓은 1:1 통신을 한다.

 

  • socket 
    • 프로세스간 통신을 담당
    • inputSteam, OutputStream을 가지고 있으며, 이 두 스트림을 통해 프로세스간 통신이 이뤄진다.
  • server socket
    • 포트와 연결되어 외부 연결 오청을 기다리다 연결이 들어오면 socket을 생성하여 소켓과 소켓간 통신을 한다.

 

 

EX01. Socket

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SeverSocket01 {
	public static String getTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
		return sdf.format(new Date());
	}
	
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		
		try {
			serverSocket = new ServerSocket(5000);
			System.out.println(getTime() + " 접속되었습니다.");
		} catch (IOException e) {
			e.printStackTrace();
		}
		while (true) {
			System.out.println(getTime() + " 접속 대기중...");
			try {
				java.net.Socket socket = serverSocket.accept();
				System.out.println(getTime() + socket.getInetAddress() + " 로부터 요청이 들어옴.");
				//소켓의 출력 스트림 얻어오기
				OutputStream out = socket.getOutputStream();
				DataOutputStream dos = new DataOutputStream(out);
				
				//원격 소켓 보내기
				dos.writeUTF("서버로부터 온 메시지 입니다.");
				System.out.println(getTime() + " 데이터를 전송했습니다.");
				dos.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

EX02. 채팅 프로그램 (Server)

package chatting;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server01 {
	public static void main(String[] args) {
		ServerSocket serverSocket = null;

		try {
			System.out.println("서버 실행 중...");
			serverSocket = new ServerSocket(5000);
			Socket socket = serverSocket.accept();
			System.out.println("접속 성공");

			//is, isr, br의 차이? 
			InputStream is = socket.getInputStream();
			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader br = new BufferedReader(isr);

			while (true) {
				System.out.println(br.readLine());
			}

		} catch (Exception e) {

		} finally {
			try {
				if (serverSocket != null) {
					serverSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

EX03. 채팅 프로그램 (Client)

다른 컴퓨터의 서버에 접속하고 싶은 경우, "local host" 대신 그 컴퓨터의 ip주소를 적어 실행할 수 있다.

단, 그 컴퓨터의 서버가 실행중인 상태여야 한다. 

package chatting;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client01 {
	public static void main(String[] args) {
		Scanner sc = null;
		Socket so = null;
		
		try {
			sc = new Scanner(System.in);
			so = new Socket("local host", 5000);
			
			//출력작업
			OutputStream os = so.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(os);
			BufferedWriter bw = new BufferedWriter(osw);
			
			String text = "";
			
			while (true) {
				System.out.print("내용 : ");
				text = sc.next();
				bw.write(text + "\n");//  \n을 붙여야 서버로 날아갑니다.
				bw.flush();//강제 전송
			}
			
		} catch (Exception e) {
			
		}finally {
			try {
				if(so != null) {so.close();}
				if(sc != null) {sc.close();}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

댓글