티스토리 뷰

알아야 할 것들: 서버 / 클라이언트 / socket 프로그래밍

 

외우자: TCP/IP에서 자신 가리키는 주소 : 127.0.0.1 (localhost)

 

https://example.com/login?user=kim

프로토콜://host domain name:port 번호/resource path?쿼리

 

용어

  • url 클래스, 포트, ip, protocol
  • TCP / UDP
  • socket
  • Socket 프로그래밍
  • InputStream, OutputStream

 

TCP/IP/DNS 프로토콜(약속, 규약)

TCP : 4계층 transport layer 프로토콜

IP : 3계층 network layer 프로토콜, 패킷 교환 네트워크에서 A에서 B로, B에서 A로 보낼 때 지켜야하는 규약들 정해놓은 것

DNS : application layer 프로토콜, 문자열로 된 도메인 이름으로 아이피 주소 변환

 

네트워크 핵심 용어

host : 네트워크에 연결된 장치 또는 서버 이름(end system)

dns : 도메인 이름을 ip 주소로 변환하는 시스템

ip 주소 : 장치 식별 숫자 주소. 고정/유동

port : 프로세스에 할당한 번호 ex) http : 80, database 3306

URL : 프로토콜://도메인이름/경로/쿼리 ex) https://example.com/login?user=kim

Protocol : 통신 규칙, 데이터 전송 방식 ex) http, ftp, tcp

 

IP 주소와 port 번호

IP 는 어느 컴퓨터인지, host 주소 담고 있고, port번호는 그 host의 어떤 프로그램인지 알려줌

 

IPv4 : 32비트 -> running out 다 써버림

IPv6 : 128비트 -> 못 외우니 DNS 쓰자

공인 public IP : 전체 인터넷에서 고유 식별

사설 private IP : 내부 네트워크용

Port 번호 : 하나의 IP 주소 내에서 여러 프로그램 구분하는 번호

- 범위 : 0~2^16-1, 

- wellknown 포트들 : 2^10-1, ex) http: 80

 

TCP와 UDP

TCP : 연결지향, connection-oriented, 전화하는 방식, “나 너랑 연결해도 돼?”, 통신 전에 1:1 연결을 먼저 맺는다.

UDP : 연결없음, connectionless, “나 보냈다! 받든지 말든지~~~"

TCP와 UDP의 차이

  TCP UDP
  신뢰성 필요할 때 간단 데이터 빠르게 전송 시
연결방식 connection oriented connectionless
속도 느림 빠름
오류감지 있음. 재전송, 순서 보장 있음. 재전송x, 순서보장x
주요 영역 채팅, 파일 전송 등 실시간 스트리밍
JAVA 클래스 URL URLConnection Socket ServerSocket DatagramPacket DatagramSocket MulticastSocket

 

 

IP & PORT 이용 통신

SERVER는 대표 포트 하나 열어놓고 ALWAYS ON, 계속 기다린다.

CLIENT가 항상 먼저 SERVER에게로 SERVICE 요청하고 그에 맞는 PORT 열림(1:1 매핑)

 

서버와 클라이언트 구조(In TCP??)

서버 :

  • 연결 요청 기다림
  • 고정된(well known) ip 주소와 포트 번호 갖고, 문 열어놓고 손님 기다림
  • ServerSocket 클래스

클라이언트 :

  • 서버에 먼저 말 걺. 요청하는 쪽
  • 서버의 주소(ip, 포트번호) 알고 찾아가서 문 두드리는 손님
  • Socket 클래스

Socket :

  • ip주소+port번호 합쳐진 형태, 특정 컴퓨터의 특정 프로그램 식별

ex) 127.0.0.1 : 8080 이면 127.0.0.1 주소에 있는 컴퓨터의 tomcat 프로그램

  • 소켓과 소켓 데이터 교환으로 통신

 

소켓 프로그래밍

서버 클래스 : ServerSocket

클라이언트 클래스 : Socket

기본 시나리오 :

  1. 서버는 서버 소켓 생성(Door용 소켓(Client야 기다릴테니 knock knock해~~)), 클라이언트의 연결 요청 기다림(listen)
    • 접속포트 50023이면
    • `ServerSocket serverSocket = new ServerSocket(50023);`//서버소켓 생성
  2. 클라이언트 -> 서버 : 연결 요청
    • Socket s = new Socket("서버 ip 주소", 서버 포트 번호:50023);//ip 주소의 50023포트로 연결 요청 보낸다.
    • 클라이언트 측에서 소켓 생성하자마자 자바는 내부적으로 3-way handshake를 해서 서버와 연결 시도
    • 연결 성공 시 socket 객체 s 생성 성공, 이후 getInputStream()과 getOutputStream()을 통해 데이터 주고받음
    • 연결 실패 시 예외 발생 IOException -> try-catch로 처리
  3. 서버 연결 요청 수락(accept)
    • 새로운 클라이언트 응대 소켓 만들어 클라이언트와 통신
    • 다시 다른 클라이언트 연결 기다림...
    • Socket socket = serverSocket.accept(); //오 클라이언트가 요청 보냈네? 연결하자! 요청 받아들임(accept)(여기서 accept()는 클라이언트가 요청 보낼 때까지 멈추고 기다리는 동작한다.)
  4. 네트워크 입출력 스트림 생성
    1. Socket 객체 getInputStream(), getOutputStream() 메소드 이용
    2. Scanner와 PrintWriter 클래스 사용 가능

 

스트림(Stream) : 데이터 흐르는 통로

- 서버와 클라이언트 간 소켓 연결 성공 시, 데이터 주고받는 통로(stream) 열린다.

- InputStream : 데이터 읽는(입력받는) 통로

- OutputStream : 데이터 쓰는(출력하는) 통로 

 

실습 Lab1 : 간단한 1:1 채팅 - 클라이언트와 서버가 서로 한번씩 번갈아 가면서 문자열 전송

1. 클라이언트 코드

import java.io.*;
import java.net.*;
import java.util.*;

public class ClientEx {
	public static void main(String[] args) throws IOException {
		Scanner in = null;
		PrintWriter out = null;
		Socket socket = null;
		Scanner scanner = new Scanner(System.in);//키보드에서 읽는 scanner 객체 생성
		
		try {
			socket = new Socket("127.0.0.1", 50023);//서버 주소, 서버 포트 번호 쓰고 서버야~ 연결 요청할게
			
			in = new Scanner(socket.getInputStream());//만들어진 stream에서 입력받는 scanner 객체 생성
			out = new PrintWriter(socket.getOutputStream(), true);//만들어진 stream으로 출력하는 printWriter 객체 생성
			
			while (true) {
				System.out.println("====클라이언트====");
				System.out.println("보내기>>");
				String outputMessage = scanner.nextLine();//키보드에서 한 행 읽기
				if (outputMessage.equalsIgnoreCase("bye")) {//입력한게 bye면 
					out.println(outputMessage);//만들어둔 stream으로 outputMessage 출력
					break;//while문 빠져나간다. 종료
				}
				out.println(outputMessage);//만들어둔 stream으로 outputMessage 출력
				String inputMessage = in.nextLine();//서버가 보낸 메시지 클라이언트가 읽는다.
				System.out.println("서버: "+inputMessage);
			}
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
		
		scanner.close();
		socket.close();
	}
}

 

2. 서버 코드

import java.io.*;
import java.net.*;
import java.util.*;

public class ServerEx {
	public static void main(String[] args) throws IOException {
		Scanner in = null;
		PrintWriter out = null;
		ServerSocket listener = null;
		Socket socket = null;
        //"키보드"에서 읽을 scanner 객체 생성
		Scanner scanner = new Scanner(System.in);
		
		try {
			//서버 소켓 생성
            //serversocket 포트번호 50023 열어놓고 기다림...(listen 중)
			listener = new ServerSocket(50023);
			System.out.println("=====서버=====");
			System.out.println("연결을 기다리고 있습니다....");
			//클라이언트로부터 연결 요청 대기
            //클라이언트가 요청하면 이 코드 실행. 요청했다구? 오키 수락할게 연결하자!
			socket = listener.accept();
			System.out.println("연결되었습니다.");
			
			in = new Scanner(socket.getInputStream());//"만들어진 stream"에서 입력받는 scanner 객체 생성
			//소켓 통해 상대방에게 데이터 보내는 출력 스트림, printWriter로 감싸 문자열 전송 쉽게 함
			//out : 클라이언트에게 보낼 전송 객체
            //"만들어진 stream"으로 출력하는 printwriter 객체 생성
			out = new PrintWriter(socket.getOutputStream(), true);
			
			while(true) {
				String inputMessage = in.nextLine();//클라이언트로부터 입력받은 거 읽기
				if(inputMessage.equalsIgnoreCase("bye")) {//클라이언트가 입력한 게 bye면 종료 break;
					System.out.println("클라이언트에서 bye로 연결을 종료하였음");
					break;//연결 종료
				}
				System.out.println("클라이언트: "+inputMessage);
				System.out.print("보내기>>");
				String outputMessage = scanner.nextLine();//키보드에서 읽은 거 outputMessage에 저장
				out.println(outputMessage);//만들어진 stream으로 출력(서버->클라이언트로 보내는 전송 코드)
			}
		} catch(IOException e) {
			System.out.println(e.getMessage());
		}
		
		scanner.close();
		socket.close();
		listener.close();
	}
}

 

실행 결과

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/03   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함