키워드

소켓, 바이트 스트림, 데이터 송수신, HTTP, 클라이언트, 서버, accept ,write, read, close

 

Socket 이란

Socket은 양 끝단에서 바이트 스트림을 통해 데이터를 주고 받는 도구로 인터페이스 역할을 한다. 

소켓은 연결을 맺기 위한 IP와 Port 그리고 어떻게 데이터를 주고 받을지를 약속한 프로토콜로 정의되고, 역할에 따라 Server Socket과 Client Socket으로 구분된다. 

 

HTTP 통신과 Socket 통신의 차이점

데이터를 주고 받으려면 HTTP를 이용한 통신도 있지않은가? 왜 socket 통신이 필요한가?

- HTTP 통신은 단방향 통신이다.

 Client의 요청이 있을 때에만, Server가 응답하여 데이터를 전송하고 곧바로 연결을 종료한다.
서버의 응답에는 응답 코드가 같이 전송되며, 응답 코드와 메시지 바디를 통해 요청한 값을 전달받는다.
( + HTTP 통신은 매번 요청과 응답 사이에 커넥션은 맺고 끊어야하는데, 그 비용이 비싸서 최근에는 Keep Alive 옵션을 통해 일정 기간 동안 Client와 Server의 커넥션을 유지하는 방식의 통신을  한다.)

- Socket 통신은 양방향 통신이다.

Client와 Server가 특정 포트를 통해서 이어져 있기 때문에 양방향 통신이 가능하다. Client의 요청에 따른 응답만을 데이터로 주는 것이 아니라, Client와 Server는 실시간으로 데이터를 주고 받을 수 있다.
실시간 동영상 스트리밍이나 온라인 게임과 같은 경우에 사용한다.

여기까지가 둘의 차이점이고 더 깊게 들어가면 이렇다.

더보기

HTTP도 결국 소켓 통신이다. 소켓은 IP와 Port 를 사용해 만든 통신의 양 끝단인데, TCP 레이어 위에 올라간 HTTP 또한 같은 방식으로 통신한다. HTTP 통신의 내부 구현에서는 소켓을 사용한다. 
하지만, 둘을 구분하는 이유는 한 쪽(Client)에서만 요청을 하고 응답을 하는 웹 통신의 특성상 HTTP가 하나의 중요한 프로토콜로 구분이 되었기 때문이다. 
즉, HTTP 통신은 소켓 통신의 일종이지만, 소켓 통신이 HTTP 통신인 것은 아니다. 

 

소켓 통신의 흐름

Server (서버)

1. Socket()  -  소켓을 생성
2. bind() - 소켓 주소 할당
3. listen()  - 클라이언트 접근 요청에 수신 대기열 생성
4. accpet() -  클라이언트와의 연결 대기
5. 데이터 송수신 후, close()로 소켓 종료

Client (클라이언트)

1. Socket() -  소켓을 생성. 이 때, 통신을 맺을 호스트(서버)의 IP와 Port 할당
2. connet() - 소켓 연결 요청
3. 데이터 송수신 후, close()로 소켓 종료

 

기본적인 소켓 통신 코드

소켓이 뭔지 알았으니 기본적인 소켓 통신 코드를 보자.

  • Server
public class SocketServer {

    private int port = 4545;
    
    public void server(){
        try {

            // 서버 소켓 생성 Port 할당
            ServerSocket serverSocket = new ServerSocket(port);

            // 클라이언트 연결 대기.
            Socket socket = serverSocket.accept();

            // 데이터 송수신 스트림 생성
            InputStream is = socket.getInputStream();
            OutputStream os = socket.getOutputStream();

            // 바이트 배열 생성 후 바이트 배열만큼 read
            byte[] buffer = new byte[1024];
            int bytesRead = is.read(buffer);

            // 만약 InputStream 에서 읽을 값이 없으면 -1 을 반환한다.
            if (bytesRead != -1) {
                // 버퍼 배열 처음부터 받은 데이터 까지로 문자열 생성
                String message = new String(buffer, 0, bytesRead);
                System.out.println("recieved Message from client socket: " + message);

                String responseMessage = "Success.";
                os.write(responseMessage.getBytes());
            }
            //소켓 종료
            socket.close();


        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

 

  • Client

public class SocketClient {

    public void client() {
    
        try {
            // host IP와 Port 할당
            Socket socket = new Socket("127.0.0.1", 4545);

            // 데이터 송수신을 위한 스트림 생성
            InputStream is = socket.getInputStream();
            OutputStream os = socket.getOutputStream();

            String message = "send message ... from client socket";

            // 데이터 송신
            os.write(message.getBytes());

            // 서버로부터의 응답 수신
            byte[] buffer = new byte[1024];
            int bytesRead = is.read(buffer);

            if (bytesRead != -1) {
                String responseMessage = new String(buffer, 0, bytesRead);
                System.out.println("response from server socket: " + responseMessage);
            }

            // 소켓 종료
            socket.close();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

 

결과

  • Server

서버 소켓 실행 결과

  • Client

클라이언트 소켓 실행 결과

 

정리

가장 앞서 작성했던 키워드 기반으로 정리해보자.
소켓은 양 끝단에서 바이트 스트림을 기반으로 데이터를 송수신 할 수 있도록 하는 도구이다. 데이터를 송수신할 수 있는 방법으로 HTTP통신도 있지만, HTTP는 클라이언트에서 서버로 요청할 때, 요청한 부분에 대한 값을 응답하는 구조로 이루어졌다. 즉, 단방향 통신이다. 소켓 통신은 아이피,포트,프로토콜로 정의되며 연결되어 있으면 양방향으로 데이터 송수신이 가능하다. 소켓은 역할에 따라 클라이언트 소켓, 서버 소켓으로 구분된다.
클라이언트 소켓은 소켓을 생성한 뒤, 서버 소켓으로 연결하여 데이터를 송수신한다.
서버 소켓은 소켓을 생성하고, 클라이언트 측의 연결을 대기하고 연결되면 데이터를 송수신한다. 

바이트 스트림을 기반으로 데이터를 송수신한다.
InputStream 은 바이트의 입력을 처리한다. 보내고자 하는 데이터를 바이트 배열을 이용해서 저장하고 전송하게 되는데..
얼만큼의 데이터를 다뤄야할지 모르는 상태라면, 넉넉하게 배열을 선언하면 다인가? 1000으로 선언한 바이트 배열중에 20만 사용되면 980은 낭비되는 데이터 아닌가? 얼만큼의 데이터가 전송될지 모르는 가변적인 데이터를 보내야할 때는?  

바이트 스트림과 보조 스트림 , 문자 기반 스트림을 활용하여 문제를 해결해야한다. 

2024.02.29 - [JAVA] - [Java] 입출력 스트림(I/O Stream) 쉽게 정리

 

[Java] 입출력 스트림(I/O Stream) 쉽게 정리

키워드 개울, 고속도로, 흐른다, 단방향, 선입선출, 연결, 통신, 바이트 스트림, 보조 스트림 , 스트링 스트림 입출력? 컴퓨터 내부 또는 외부의 장치와 프로그램 간에 데이터를 주고 받는 것. Input

burning-man.tistory.com



'JAVA' 카테고리의 다른 글

[Java] 입출력 스트림(I/O Stream) 쉽게 정리  (0) 2024.02.29

키워드

개울, 고속도로, 흐른다, 단방향, 선입선출, 연결, 통신, 바이트 스트림, 보조 스트림 , 스트링 스트림

스트림 키워드

 

입출력?

컴퓨터 내부 또는 외부의 장치와 프로그램 간에 데이터를 주고 받는 것.

Input/Output 으로 입력/출력을 이야기한다. 줄여서, I/O

 

스트림이란?

자바에서 입출력 스트림은 데이터의 흐름을 다루는데 사용된다. 
각 끝점의 연결 통로이다.

데이터의 흐름을 다룬다
-> 영어로 Stream은 흐르다 라는 뜻의 영어동사 이다. 구글에 Stream을 검색하면 개울 이미지가 나온다. 
-> 개울에는 물이 흐른다. 컴퓨터 세상에는 데이터가 흐른다.

Stream 개울

물은 흐를 때 위에서 아래로 흐른다. -> 흐름의 방향이 정해져있다. -> 스트림도 흐름의 방향이 정해져있다.

스트림의 특징

  • 스트림은 단방향이다. 한쪽 방향으로만 흐를 수 있다.
    ( 고속도로에 한번 올라타면 그대로 한방향으로 가야한다. 역주행할 수 없다.)
  • 하나의 스트림은 하나의 역할을 한다
    ( 고속도로는 목적지로 가기 위해서 주행 차선과 반대 차선 이렇게 나뉘어져있다. 즉, 입력과 출력을 위해서는 각각의 스트림이 필요하다.)
  • 스트림은 선입선출 , FIFO 구조이다.
    First In First Out, 먼저 들어온게 먼저 나간다.
  • 스트림은 여러개가 연결될 수 있다.
    -> 키보드에서 문자를 입력 받는 System.in과 바이트 단위로 읽는 형식을 문자 단위로 변환시켜주는 InputStreamReader를 연결할 수 있다. (new InputStreamReader(System.in))
  • 스트림은 지연될 수 있다.
    -> 입력 스트림이 비어 있으면, 컴퓨터는 읽을 데이터가 없으므로 기다린다.
    -> 출력 스트림이 꽉 차 있으면, 컴퓨터는 빈 공간이 생길 때 까지 기다린다.

 

스트림의 종류

1. 바이트 스트림 (InputStream, OutputStream)

스트림은 바이트 단위로 데이터를 전송하며 입출력 대상에 따라 여러가지의 입출력 스트림이 있다.
기본 클래스로 InputStream과 OutputStream이 있으며, 입출력 대상에 따라 여러 가지 자식들을 가지고 있다.

  • 파일 : FileInputStream, FileOutputStream
  • 메모리 : ByteArrayInputStream, ByteArrayOutputStream
  • 프로세스간의 통신: PipedInputStream, PipeOutputStream
  • 오디오장치: AudioInputStream, AudioOutputStream

1.1. 보조 스트림 

실제 데이터를 주고 받는 스트림은 아니기 때문에, 데이터를 입출력 할 수 있는 기능은 없지만 스트림의 기능을 향상시키거나 새로운 기능을 추가할 수 있다.
-> 아까 스트림의 특징이 기억나나? 스트림은 여러개가 연결될 수 있다. 입출력을 기능을 할 수 있는 스트림과 기능을 향상시키는 보조스트림을 "연결" 하여서 성능을 향상 시켜 사용할 수 있다.

예를 들어, text 파일을 읽기 위해 FileInputStream을 사용할 떄, 입력 성능을 향상시키기 위해 버퍼를 사용하는 보조스트림인 BufferedInputStream을 사용한다.

// 기반스트림을 바탕으로 보조스트림 연결 
BufferedInputStream bis = BufferedInputStream(new FileInputStream("test.txt"))

//보조스트림으로부터 데이터를 읽는다.
bis.read()

실제 입력기능은 바이트 스트림인 FileInputStream 이 수행하고, 보조 스트림인 BufferedInputStream은 버퍼만을 제공한다. 버퍼를 사용한 입출력과 사용하지 않은 입출력은 성능차이가 상당하기 때문에 대부분의 경우에 버퍼를 이용한 보조스트림을 사용한다.

  • 버퍼를 이용한 입출력 성능향상 : BuffredInputStream, BufferedOutputStream
  • 필터를 이용한 입출력 처리 : FilterInputStream, FilterOutputStream
  • 데이터를 객체 단위로 입출력 할 때 사용. 객체의 직렬화 때 사용 : ObjectInputStream, ObjectOutputStream

2. 문자기반 스트림 (Reader, Writer)

컴퓨터의 모든 데이터는 바이트 단위 데이터로 구성되어있다. -> 데이터의 입출력은 바이트 단위로 저장된다.
InputStream 또한 바이트 단위로 데이터를 보낸다. 입력 메소드인 read()는 1 바이트 단위로 읽어들인다.
1바이트 이상의 데이터는 나머지는 읽지않고 스트림에 남아잇다.

자바에서는 한 문자를 의미하는 char 형이 1byte가 아니라 2byte 이다. 한글은 3byte다. 
1byte만 인식하면, 정상적인 값을 전달받을 수 없게 된다. 
문자를 온전히 받기 위해서 InputStreamReader. 즉, 문자기반 스트림이 필요하다.

정리

가장 앞서 작성했던 키워드를 기반으로 정리를 해보자.
스트림은 데이터의 흐름이다. 개울의 물이 흐르는것 처럼 데이터 또한 스트림을 통해 흐른다. 또 스트림은 고속도로처럼 주행 차선과 반대 차선이 나눠져 있다. 흐름은 단방향으로만 갈 수 있기 때문에, 입력과 출력 각각 다른 스트림이 필요하다.

통신은 기본적으로 바이트 단위로 데이터를 주고 받는다. 바이트를 입출력 받기 위해서는 바이트 스트림이 필요하고, 바이트 스트림에 추가적인 성능 향상이나 기능 추가를 위해서는 보조스트림을 연결 한다. 바이트 스트림은 1 바이트 단위로 데이터를 주고 받기 때문에, 문자 데이터는 정상적으로 값을 받을 수 없다.그래서 값을 정상적으로 인식하기 위해 문자기반 스트림을 이용한다. 

 

회사에서 크론탭을 이용하여, 쉘 스크립트를 지정된 시간에 실행할 수 있도록 진행하였다. 

많은 글들을 보았고, 내게 필요했던 정보들을 기록하려한다.

 

크론탭(Crongtab)

매일 혹은 주기적으로 해야하는 작업을  실행 시키기 위해 사용한다. 

나 같은 경우는 실행 중인 프로세스를 체크하는 스크립트를 매일 7시에 실행, 

일정 기간이 지난 로그들을 삭제하는 스크립트를 매일 11시에 실행 등의 작업을 주기적으로 하기 위해 사용하였다.

 

- 기본 사용 방법

crontab -l 		# 저장된 작업 리스트 출력
crontab -e 		# 크론탭 작업 수정 
crontab -r 		# 저장된 작업 삭제
crontab -u [사용자명] [파일] 		# 해당 사용자에게 파일에 적힌 크론탭 내용 등록

# 은 주석

- 규칙

# /etc/crontab
# 분(0-59) / 시(0-23) / 일(1-31) / 월(1-12) / 요일 (0-6 : 0은 일요일 ~ 6은 토요일) [유저이름] [명령어]

     *          *           *            *         *      유저이름    명령어

# crontab -e
# 분(0-59) / 시(0-23) / 일(1-31) / 월(1-12) / 요일 (0-6 : 0은 일요일 ~ 6은 토요일) [명령어]
  
     *           *          *            *          *      명령어

 

/etc/crontab의 경우 어떤 사용자의 크론탭에서 사용할건지 사용자명을 지정해줘야한다.  - root 권한이 있는 경우

crontab -e 의 경우 해당 사용자의 크론탭을 편집할 수 있다. - root 권한이 없는 경우

 

etc/crontab

root 권한이 있을 경우, etc/crontab 파일을 편집하여 작업할 수 있다.

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

 앞에 다섯개의 별이 실행 시간에 대해 규칙을 정하는 부분이고, 사용자를 적는 부분, 실행할 명령어를 적는 부분으로 되어있다.

crontab -e

root 권한이 없는 경우, crontab -e 명령어를 통해 크론탭을 편집한다.

# delete log 
# 매일 11시 30분에 해당 sh을 실행
30 11 * * * /tmp/test/deltelog.sh > /dev/null 2>&1

# 매일 07시에 해당 sh을 실행
# restart process
0 7 * * * * /tmp/test/service.sh start > /dev/null 2>&1

 

service crond restart

크론탭을 수정하고 난 뒤에는 꼭 restart 해줘야 적용된다.

cat /var/log/cron

크론탭의 수행 이력과 변경 내용에 대한 로그는 cat /var/log/cron 명령어를 통해 확인할 수 있다. ( root 권한으로! )

 

크론탭이 정상적으로 실행되지 않을 때

크론탭이 정상적으로 실행되지 않을 때는 로그 파일을 생성해서 확인해보자

test.sh >> /tmp/testCron.log 2>&1
  • `test.sh` : 실행할 쉘 스크립트의 파일 이름
  • ` >> /tmp/testCron.log` : 쉘 스크립트의 실행 결과를 파일에 추가하는 리다이렉션
    `>>` 는 파일이 존재하면 뒤에 오는 파일에 결과를 추가하고, 파일이 없으면 새로 생성한다.
  • `2>&1` : 표준 에러를 표준 출력으로 리다이렉션 하는 부분. 
    즉, 에러메시지가 /tmp/testCron.log 파일에 기록된다.

 

크론탭 사용시 주의할점

규칙에 맞게 설정했는데도 제대로 동작하지 않는 경우가 있다. 대부분의 경우 환경변수와 절대경로가 말썽이다. 

!! 크론탭은 실행 시에 별도의 쉘을 띄운다. !!

1. 환경변수

- SHELL
작업을 실행시킬 쉘을 지정할 수 있다.  지정하지 않을 시 기본 값으로 /bin/sh 로 쉘을 시작한다.

-PATH
크론탭은 쉘을 새로 띄우기 때문에, 쉘에서 프로그램을 찾기위한 PATH를 지정해줄 필요가 있다. 
계정으로 로그인 해서 쉘을 실행시키는게 아니기 때문에, 계정에 있는 PATH 변수를 사용할 수가 없다.

- MAILTO
마일토? 메일토.. 메일 투! 크론이 수행한 결과를 메일로 보낼 수 있다. 기본 값으로는 작업을 실행한 주체에게 전송한다.

- HOME
크론탭의 home 디렉토리 경로를 설정한다. 기본적으로 크론탭을 실행한 유저의 홈디렉토리로 /etc/passwd에 설정된 경로를 따른다.

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

 

2. 절대경로 / 상대경로

크론탭은 실행시에 별도의 쉘을 띄운다. 상대경로로 명령어를 사용하면 Crong은 알 수가 없다..
항상 절대경로로 명령어를 사용해야한다

 

SIP


Session Intiation Protocol 의 약자로 “세션 설정 프로토콜” 이다.

하나 또는 그 이상의 참가자와 멀티미디어 세션의 생성, 변경 종료 에 대한 application 계층의 프로토콜이다.

SIP에서 세션은,

  • 다자간 회의
  • 음성 전화
  • 영상 전화
  • 상태 정보 배포
  • 이벤트 신청 및 통지

를 말한다.

SIP는 시그널링 프로토콜이다.

하나의 호를 생성 및 종료하기 위해선 함께 해야하는 프로토콜이 있다.

  • RTP 와 RTCP- 실제 음성이나 영상을 전달하기 위해
  • SDP - 세션 설정을 위한 세부정보 전달을 위해

 

SIP 메시지

SIp 메시지는 헤더메시지 바디로 구성된다.

SIP가 사용하는 전송 프로토콜(transport layer)은 TCP 또는 UDP 이다. 보통 UDP를 주로 사용하지만 현재는 TCP를 더 많이 사용한다.

SIP 프로토콜이 호를 생성 및 종료하기 위해서는 5가지 기능이 필요하며**, SIP 컴포넌트**에서 구현된다.

  • 세션 설정
  • 세션 관리
  • 사용자 위치
  • 사용자 이용가능성
  • 사용자 능력

 

UA

UA는 UA client 와 UA server의 기능을 수행하는 단말이다.

UAC는 세션을 시작하는 역할로 통화를 시도하는 역할이고,

UAS는 세션을 종단하는 역할로 통화를 받는 역할을 한다.

UA는 다른 UA와 직접 연결하거나, Proxy server, Redirect server들을 통해 다른 UA와 연결할 수 있다.

통화 중인 호의 상태를 실시간으로 관리한다, UA는 SIP 전화기 이거나 소프트폰이다.

 

SIP Gateway

PSTN 과 IP 네트워크를 서로 연결해주는 역할을 한다.

SIP는 어떻게 통신하는가?

SIP를 지원하는 UA가 단 2대만 있다면, 상대방의 IP주소를 등록하여서 상호 간의 연결이 가능하다.

하지만, 전화가 수백대, 수천대 있다면? 어떻게 할것인가?

→ 모든 전화기와 전화번호가 매핑된 테이블을 가지고 있다면, 가능하겠지만 현실적으로 불가능하다.

→ 전화기가 컴퓨터의 성능을 발휘해야하고, 사용자가 전화기의 IP 주소가 바뀔 때 마다 업데이트 해야한다.

→ 별도의 서버가 전화번호와 IP주소 매핑 테이블을 가지고 있고, 모든 전화기들은 IP가 바뀔 때마다 해당 서버에 자동으로 업데이트 한다.

→ 전화기는 통화 하고자 할 때, 서버에게 IP주소를 물어본다.

 

Registar server (등록 서버)

SIP 전화기는 부팅을 할 때 자신의 IP 주소 또는 SIP URI 정보를 등록 서버에 업데이트한다.

SIP REGISTER 메시지를 등록서버에 보내서 정보를 업데이트한다.

등록 서버는 저장된 정보를 바탕으로 Proxy server로 부터 요청에 응답하지만, SIP 메시지를 직접 처리하지는 않는다.

 

Proxy server (프록시 서버)

프록시 서버는 전화기(UA)로 부터의 받은 접속 요청 메시지를 추가, 변경, 삭제 할 수 있따.

전화기가 7000번으로 전화 통화를 시도하는 SIP INVITE 메시지를 SIP 프록시 서버로 전송하면,

프록시 서버는 등록서버에 7000번의 IP주소를 문의한 후에 7000번 으로 메시지를 전달한다.

 

Redirect server (리다이렉트 서버)

프록시 서버는 통화 연결을 위한 INVITE 메시지를 목적지로 직접 전달해준다.

리다이렉트 서버는 메시지를 전송한 UAC로 목저지를 3xx redirect 메시지로 전송한다.

redirct 메시지를 받은 UAC는 수신한 목적지 주소를 가지고 새로운 세션을 열어서 통신을 시도한다.

통신 사업자들과 같은 대규모 voIP 망을 지원하는 스위치는 등록서버, 프록시 서버, 리다이렉트 서버 를 모두 따로 구현하지만,

기업용 IP PBX는 한 서버에 모두 구현한다.

 


kill

리눅스 환경에서 프로세스를 종료하기 위해서는 kill 명령어를 사용한다.

종료할 프로세스를 찾기 위해 ps -ef 명령어를 통해서 PID를 먼저 찾아야한다.

ps -ef | grep 프로세스명

UID, PID, PPID 순으로 나온다.

 

Kill 명령어로 프로세스를 종료 시키는 옵션에는 -9 와 -15가 있다.

 

kill -9 <PID>

리눅스 커널이 프로세스를 강제로 종료한다. 프로세스가 자원을 제대로 해제하지 않을 때 사용한다.

프로세스를 강제로 종료하기 때문에 저장되지 않은 데이터가 날아가는 경우가 발생한다.

 

kill -15 <PID>

일반적인 종료 방법으로 프로세스가 정리 작업을 수행할 기회를 준다.

메모리상에 있는 데이터와 각종 설정/환경 파일을 안전하게 저장한 후 프로세스를 종료한다.

 

예시.

# PID가 1234인 프로세스를 강제로 종료한다
kill -9 1234

# PID가 5678인 프로세스를 종료한다.
kill -15 5678

 

 

Repository 란

Repository란 소프트웨어 패키지와 메타 데이터가 저장되는 패키지 저장소이다.

대부분의 리눅스 배포판은 자체 공식 저장소를 가지고 있다. 공식 저장소에는 시스템 운영에 필요한 핵심 패키지들과 검증된 소프트웨어 패키지들이 제공된다.

하지만 때로는 추가적인 패키지가 필요할 때가 있는데, 그럴 때는 개발자나 사용자 그룹들이 유지보수 하고 제공하는 커뮤니티 저장소를 추가하여 이용한다. 
예를 들어, EPEL 저장소는 CentOS과 RHEL과 호환되면서 더 많은 소프트웨어 패키지를 제공한다.

  • 공식 저장소 
    : 대부분의 리눅스 배포판은 자체 공식 저장소를 가지고 있다. 해당 배포판을 위해 검증된 소프트웨어 패키지가 포함되어있다. 시스템에 필요한 핵심 소프트웨어부터 다양한 응용프로그램까지 다양한 패키지가 제공된다.
  • 커뮤니티 저장소
    : 개발자나 사용자 그룹들이 유지보수하고 제공하는 저장소이다. 공식 저장소에는 포함되지 않은 소프트웨어,최신 버전의 응용프로그램, 실험적인 소프트웨어 등이 포함된다. 

 

시스템 리포지토리 정보가 들어있는 파일은 /etc/yum.reps.d 디렉토리에 있으며 repo 확장자를 가지고 있다.

yum 과 dnf 등의 패키지 관리 도구는 이 디렉토리의 설정 파일을 참조해서 동작한다.

 

yum 과 dnf

리눅스에서 패키지를 관리하고 설치하는 것은 주로 'yum'과 'dnf' 라는 패키지 관리자를 통해 이뤄진다.

이 둘은 리눅스 배포판에서 패키지를 다운로드하고 설치하는 도구인데, 'dnf'는 CentOS 8, Fedora 22 부터 사용할 수 있고 'yum'은 그 이전 버전의 시스템에서 아직 사용되고 있지만 기본적으로 'dnf'를 사용하도록 권장되고 잇다.

 

yum 기본 명령어 사용법

#패키지 설치
yum install <패키지 이름>

#설치된 패키지를 최신버전으로 업데이트
yum update <패키지 이름>

#시스템에 설치된 모든 패키지를 최신버전으로 업데이트
yum update 

#특정 패키지 정보 조회
yum info <패키지 이름>

#패키지 삭제
yum remove <패키지 이름>

#패키지 검색
yum search <키워드>

yum list | grep <키워드>

#캐시 정리
yum clean packages

 

dnf 기본 명령어 사용법

#패키지 설치
dnf install <패키지 이름>

#특정 패키지 최신 버전으로 업데이트
dnf update <패키지 이름>

#모든 패키지 업데이트
dnf update

#특정 패키지 정보 조회
dnf info <패키지 이름>

#패키지 삭제
dnf remove <패키지 이름>

#패키지 검색
dnf search <키워드>

#이미 다운로드 된 패키지 조회
dnf list installed | grep <패키지 키워드>

#의존성 확인
dnf deplist <패키지 이름>

#특정 패키지 그룹 한번에 설치 
dnf grouplist <패키지 이름>

#캐시 정리 
dnf clean packages

 

 

/etc/*relese

 

cat /etc/*release

 

/etc/*relese 파일은 리눅스 시스템에서 사용되는 여러 리눅스 배포판의 정보를 포함하고 있는 파일들의 집합이다.

주로 사용되는 파일들 중 하나는 '/etc/os-release' 로 리눅스 OS의 세부적인 정보를 포함하고 있다.

  • NAME: 리눅스 배포판의 이름
  • VERSION: 리눅스 배포판의 버전
  • ID: 리눅스 배포판의 고유 식별자
  • VERSION_ID: 리눅스 배포판의 세부 버전 ID
  • PRETTY_NAME: 보기 좋은 형태의 리눅스 배포판 이름과 버전

 

*relese

 

간단하게 OS의 버전만 보고싶다면,

cat /etc/issue*

 

-P 옵션으로 포트번호를 지정하지 않으면 기본 포트번호인 22번 포트를 이용한다.

SCP

Secure Copy Protocol 을 사용하여 파일 또는 디렉토리를 안전하게 다른 시스템으로 복사하는 명령어이다.

기본적으로 SSH 프로토콜을 사용하여 데이터를 전송하므로 데이터가 암호화 된다.

 

scp [옵션] [원본] [대상]

 

  • 옵션
    • -r: 디렉토리와 그 내용을 재귀적으로 복사한다. 하위 디렉토리들 까지 모두 복사.
    • -P: 포트를 지정한다.
    • -i: 신원 확인을 위한 특정 개인키 파일을 지정한다.
  • 원본 : 복사하고자 하는 파일이나 디렉토리의 경로. 원격 시스템의 경우, 원본 경로에 사용자 및 호스트 정보를 포함할 수 있다.
    예를 들어, user@remote_host:/path/to/source 와 같이 작성할 수 있다
  • 대상: 파일 또는 디렉토리를 복사하고자 하는 위치. 원격 시스템의 경우, 대상 경로에 사용자 및 호스트 정보를 포함할 수 있다. 
    예를 들어, user@remote_host:/path/to/destination 과 같이 작성할 수 있다.

  •  Local -> remote , remote -> Local 모두 명령어는 Local 에서 입력한다.
scp file.txt user@remote_host:/home/user

 

Local -> remote 

 

현재경로의 파일을 원격지 서버의 경로로 전송한다.

-P 옵션으로 포트번호를 지정하지 않으면 기본 포트번호인 22번 포트를 이용한다.

# 단일 파일 전송

scp [옵션] [파일명] [원격지계정]@[원격지 IP]:[파일이 복사될 경로]

ex) scp -P 8111 test.txt burningman@192.168.1.1:/home/burningman

#복수 파일 전송

scp [옵션] "[파일명1] [파일명2] [파일명3]" [원격지계정]@[원격지 IP]:[파일이 복사될 경로]

ex) scp "text1 test2 test3" burningman@192.168.1.1:/home/burningman

 

Remote -> Local

원격지 서버의 파일을 로컬 서버의 경로로 가져온다.

-P 옵션으로 포트번호를 지정하지 않으면 기본 포트번호인 22번 포트를 이용한다.

# 단일 파일 가져오기
scp [옵션] [원격지 계정]@[원격지 IP]:[파일명] [로컬에 저장될 경로]

ex) scp burningman@192.168.1.1:/home/burningman/test /home/testuser/

# 복수 파일 가져오기
scp [옵션] [원격지 계정]@[원격지 IP]:"[파일명1] [파일명2] [파일명3] [로컬에 저장될 경로]

ex) scp burningman@192.168.1.1:"/home/burningman/test1 /home/burningman/test2 /home/burningman/test3" /home/testuser/

 

디렉토리 전송

디렉터리를 복사하고 싶다면 -r 옵션을 활용하여, 

# hostIP 주소
scp -r /home/user/pakage 192.168.1.1:/home/pakage

# hostname@hostIP 
scp -r /home/user/pakage burningman@192.168.1.1:/home/pakage

 

리눅스의 계정 정보는 /etc/passwd 에 있다.

디렉토리 구조에 대해 잘 모른다면 하단의 글을 확인하자.

2023.11.30 - [리눅스] - 리눅스 디렉토리 구조_간단하게 정리 : /home, /etc, /var, /usr ...

 

전체 사용자 목록 확인

cat /etc/passwd

 

 

아이디만 확인하고 싶을 때

cut -f1 -d: /etc/passwd

 

 

 

리눅스 디렉토리 파일 구조

리눅스 디렉토리 파일 구조는 계층적이며 특정한 목적을 가진 디렉토리들의 집합이다.

각 디렉토리는 파일 및 다른 디렉토리를 포함할 수 있고, 시스템에서 필요한 정보와 프로그램들이 존재한다.

 

리눅스 디렉토리 파일 구조

 

 

리눅스 디렉토리 파일 구조

 

 

  • / (루트 디렉터리)
    - 리눅스 파일 최상위 디렉토리이다.
    - 모든 다른 디렉토리와 파일의 시작점.
  • /bin (바이너리)
    - 기본적인 명령어를 담고 있는 디렉토리이다. ( cd, mv, cp, ... )
    - 리눅스 시스템을 운영하기 위한 기본 명령어들이 여기 위치한다.

  • /etc (설정)
    - 시스템의 전반적인 환경 설정 파일들이 위치한다.
    - 네트워크 설정 파일, 소프트웨어 설정 파일, 사용자 계정 파일, 파일 시스템 정보 등의 파일이 포함된다.
    - 따라서, 시스템에 어떤 문제가 발생하거나, 시스템 전체 환경을 바꾸기 위해서는 /etc 디렉토리 내에 포함된 파일들에 대해 알아야한다.
    • /etc/sysconfig/network : 리눅스 서버의 hostname 변경, 네트워크 활성화를 위한 설정파일 .
    • /etc/resolv.conf : 시스템의 DNS 설정을 포함. DNS 서버 주소 및 도메인 검색에 관련된 정보.
    • /etc/hosts: 호스트명과 IP 주소간의 매핑 정보를 제공.
    • /etc/group: 그룹에 대한 정보를 포함하고 있는 파일.
    • /etc/passwd: 사용자 계정에 대한 정보를 저장. 각 사용자의 계정 이름, 사용자 ID, 홈 디렉토리 경로 등의 정보가 기록되어 있다.
    • /etc/ssh/sshd_config : SSH 서버의 설정파일, SSH 접속 관련 설정을 수정할 수 있다.
  • /home (홈)
    - 사용자의 홈 디렉토리(사용자 계정명과 동일)가 만들어지는 디렉토리.
    - 사용자는 /home 안에 자신의 디렉토리를 갖는다.

  • /lib (라이브러리)
    - 시스템에 필요한 라이브러리 파일들이 위치한다.
    - 실행 파일들이 필요로하는 라이브러리는 여기에 설치된다.
    - 시스템 부팅과 /bin과 /sbin 디렉토리에 있는 바이너리 파일들을 실행해주는 공유 라이브러리를 보유하고 있다.

  • /usr (유저)
    - 사용자가 설치한 프로그램이나 데이터들을 포함하는 디렉토리이다.
    - 대부분의 소프트웨어들은 여기에 설치된다.
    - 하위에는 /bin, /sbin, /local 등이 있다. 

  • /var (변수)
    - 로깅, 사용자 추적, 캐시 등의 시스템 운영 중에 발생한 가변 데이터가 저장되는 디렉토리이다.
    • /var/log : 다양한 프로그램들의 로그 파일.
    • /var/local : /usr/local 아래에 설치된 프로그램들의 데이터 보관.
    • /var/log/wtmp : 시스템의 모든 로그린,로그아웃 정보 기록.
    • /var/tmp : /tmp에 있는 임시파일들 보다는 좀 더 오래 유지될 필요가 있는 임시 파일들, 부팅 시 지워지지 않는다.
  • /tmp (임시)
    - 임시 파일들이 저장되는 디렉토리이다.
    - 시스템이 다시 시작되면 /tmp 디렉토리의 포함 항목이 삭제된다.
 

 

+ Recent posts