๐Ÿ—“๏ธ 2023. 08. 28
โฑ๏ธ 4๋ถ„

File Descriptor

Everything is a file

macOS ํ™˜๊ฒฝ์—์„œ ์ž‘์„ฑ๋œ ๊ธ€์ž…๋‹ˆ๋‹ค.

File Descriptor ์ •์˜

UNIX ๊ณ„์—ด์˜ ์šด์˜์ฒด์ œ๋Š” ์‹œ์Šคํ…œ์˜ ๋ชจ๋“  ๊ฒƒ์„ ํŒŒ์ผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.
์ด๋Š” ํŒŒ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์žฅ์น˜(device), ์†Œ์ผ“, ํŒŒ์ดํ”„ ๋“ฑ ๋ชจ๋“  ๊ฒƒ์„ ํŒŒ์ผ ํ˜•ํƒœ๋กœ ๋‹ค๋ฃฌ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.
File Descriptor๋Š” ์ด๋Ÿฌํ•œ ํŒŒ์ผ๋“ค์„ ๋‹ค๋ฃจ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ถ”์ƒํ™”๋œ ๊ฐœ๋…์ธ๋ฐ, ์‹œ์Šคํ…œ์ด ์•Œ์•„์„œ ํ• ๋‹นํ•ด์ค€ ์ •์ˆ˜ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

File Descriptor ์˜ˆ์‹œ

๋Œ€ํ‘œ์ ์ธ fd์˜ ์˜ˆ์‹œ๊ฐ€ ํ‘œ์ค€ ์ž…/์ถœ๋ ฅ๊ณผ ์—๋Ÿฌ์ด๋‹ค. ์ด 3๊ฐ€์ง€๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์‹œ์ž‘๋˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์—ด๋ฆฌ๊ณ  ์ข…๋ฃŒ๋˜๋ฉด ์ž๋™์œผ๋กœ ๋‹ซํžŒ๋‹ค.

๋ถ„๋ฅ˜File Descriptor
ํ‘œ์ค€ ์ž…๋ ฅ(stdin)0
ํ‘œ์ค€ ์ถœ๋ ฅ(stdout)1
ํ‘œ์ค€ ์—๋Ÿฌ(stderr)2

node.js์—์„  ๋‹ค์Œ ์ฝ”๋“œ๋กœ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

console.log(process.stdin.fd); // 0
console.log(process.stdout.fd); // 1
console.log(process.stderr.fd); // 2

์‰ฝ๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•œ๋‹ค๊ธฐ ๋ณด๋‹ค ํฌ์ธํ„ฐ์ฒ˜๋Ÿผ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
๋•Œ๋ฌธ์— node.js์˜ fs.readFile ํ•จ์ˆ˜์—์„œ๋„ ํŒŒ์ผ ๊ฒฝ๋กœ ๋Œ€์‹  fd ๊ฐ’์œผ๋กœ ํŒŒ์ผ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

// README.md
# Hello World

// index.js
import fs from 'node:fs';

fs.open('./README.md', 'r', (err, fd) => {
    console.log(fd) // 24;

    // fs.readFile์˜ ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š”
    // ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” string์ด๊ฑฐ๋‚˜, fd๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” number
    fs.readFile(fd, (err, data) => { 
      console.log(data.toString()); // # Hello World

      fs.close(fd);
    });

    // fd๋Š” ์ˆœ์„œ๋Œ€๋กœ ๋„˜๋ฒ„๋ง๋œ๋‹ค.
    fs.open('./new-file.md', 'w', (err, newFd) => {
      console.log(newFd); // 25
    })
});

File Descriptor์™€ Socket

์ž…์ถœ๋ ฅ ๋Œ€์ƒ์ด ๋ฐฉ๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ์ฝ˜์†”์ด๋‚˜ ํŒŒ์ผ์ด ์•„๋‹ˆ๋ผ ์ธํ„ฐ๋„ท์ด ๋˜๋ฉด
ํŒŒ์ผ๊ณผ ๋‹ฌ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ๋Œ€์ƒ์ด ๋ฉ€๋ฆฌ ๋–จ์–ด์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์†Œํ”„ํŠธ์›จ์–ด ์ฐจ์›์—์„œ ํ˜ธ์ŠคํŠธ๋“ค๊ฐ„ ์—ฐ๊ฒฐ์„ ํ•ด์ฃผ๋Š” ์žฅ์น˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
๊ทธ ์žฅ์น˜๊ฐ€ ๋ฐ”๋กœ ์†Œ์ผ“์ด๋‹ค. ๊ทธ๋ž˜์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๊ฐ™์€ ์˜๋ฏธ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์†Œ์ผ“๋„ ํŒŒ์ผ๋กœ ๊ฐ„์ฃผ๋˜๋ฏ€๋กœ ์†Œ์ผ“์„ ์ƒ์„ฑํ–ˆ์„ ๋•Œ ์—ญ์‹œ fd๊ฐ€ ํ• ๋‹น๋œ๋‹ค.
(๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ด๋ฏ€๋กœ ์†Œ์ผ“์ด ์ƒ์„ฑ๋๋‹คํ•ด์„œ ํŒŒ์ผ์ฒ˜๋Ÿผ ๋””์Šคํฌ์— ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์ €์žฅ๋˜์ง„ ์•Š๋Š”๋‹ค.)

import net from 'node:net';

const netServer = net.createServer().listen(4000, () => {
  console.log(netServer._handle.fd); // ์ƒ์„ฑ๋œ TCP ํ˜น์€ IPC ์†Œ์ผ“์˜ fd
});
import dgram from 'node:dgram';

const dgramServer = dgram
  .createSocket('udp4')
  .on('listening', function () {
    console.log(dgramServer._handle.fd); // ์ƒ์„ฑ๋œ UDP ์†Œ์ผ“์˜ fd
  })
  .bind(4001);

์ฐธ๊ณ 

๋Œ์•„๊ฐ€๊ธฐ
ยฉ 2024 VERYCOSY.