แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš Bare-C I/O แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแž–แžทแžŸแŸแžŸแž–แŸแž‰แž›แŸแž‰

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš Bare-C I/O แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแž–แžทแžŸแŸแžŸแž–แŸแž‰แž›แŸแž‰

แžŸแŸแž…แž€แŸ’แžแžธแžŽแŸ‚แž“แžถแŸ†

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O (แžแŸ’แžŸแŸ‚แžแŸ‚แž˜แžฝแž™ แžšแž„แŸ’แžœแžทแž›แž‡แžปแŸ†แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ) แž‚แžบแž‡แžถแž‚แŸ†แžšแžผแžŸแž˜แŸ’แžšแžถแž”แŸ‹แžŸแžšแžŸแŸแžšแž€แž˜แŸ’แž˜แžœแžทแž’แžธแžŠแŸ‚แž›แž˜แžถแž“แž”แž“แŸ’แž‘แžปแž€แžแŸ’แž–แžŸแŸ‹ แž”แŸ’แžšแžพแž€แŸ’แž“แžปแž„แžŠแŸ†แžŽแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž–แŸแž‰แž“แžทแž™แž˜แž‡แžถแž…แŸ’แžšแžพแž“แŸ–

แž“แŸ…แž€แŸ’แž“แžปแž„แžขแžแŸ’แžแž”แž‘แž“แŸแŸ‡ แž™แžพแž„แž“แžนแž„แž–แžทแž“แžทแžแŸ’แž™แž˜แžพแž›แž•แŸ’แž“แŸ‚แž€แžแžถแž„แž€แŸ’แž“แžปแž„ แž“แžทแž„แžแžถแž„แž€แŸ’แžšแŸ…แž“แŸƒแžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž“แžทแž„แžšแž”แŸ€แž”แžŠแŸ‚แž›แžœแžถแžŠแŸ†แžŽแžพแžšแž€แžถแžš แžŸแžšแžŸแŸแžšแž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแž“แŸแž€แŸ’แž“แžปแž„แž€แžผแžŠแžแžทแž…แž‡แžถแž„ 200 แž”แž“แŸ’แž‘แžถแžแŸ‹ แž“แžทแž„แž”แž„แŸ’แž€แžพแžแžŠแŸ†แžŽแžพแžšแž€แžถแžšแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ HTTP แžŸแžถแž˜แž‰แŸ’แž‰แž‡แžถแž„ 40 แž›แžถแž“แžŸแŸ†แžŽแžพ/แž“แžถแž‘แžธแŸ”

แž”แžปแž–แŸ’แžœแž€แžแžถ

  • แžขแžแŸ’แžแž”แž‘แž“แŸแŸ‡แžแŸ’แžšแžผแžœแž”แžถแž“แžŸแžšแžŸแŸแžšแžŠแžพแž˜แŸ’แž”แžธแž‡แžฝแž™แžฑแŸ’แž™แž™แž›แŸ‹แžขแŸ†แž–แžธแž˜แžปแžแž„แžถแžšแžšแž”แžŸแŸ‹แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž แžพแž™แžŠแžผแž…แŸ’แž“แŸแŸ‡แž™แž›แŸ‹แžขแŸ†แž–แžธแž แžถแž“แžทแž—แŸแž™แž“แŸ…แž–แŸแž›แž”แŸ’แžšแžพแžœแžถแŸ”
  • แž…แŸ†แžŽแŸแŸ‡แžŠแžนแž„แžขแŸ†แž–แžธแž˜แžผแž›แžŠแŸ’แž‹แžถแž“แž‚แžบแžแŸ’แžšแžผแžœแž”แžถแž“แž‘แžถแž˜แž‘แžถแžšแžŠแžพแž˜แŸ’แž”แžธแž™แž›แŸ‹แž–แžธแžขแžแŸ’แžแž”แž‘แŸ” แž—แžถแžŸแžถ C แž“แžทแž„แž”แž‘แž–แžทแžŸแŸ„แž’แž“แŸแžแŸ’แž›แŸ‡แŸ—แž€แŸ’แž“แžปแž„แž€แžถแžšแžขแž—แžทแžœแžŒแŸ’แžแž“แŸแž€แž˜แŸ’แž˜แžœแžทแž’แžธแž”แžŽแŸ’แžแžถแž‰แŸ”
  • แž€แžผแžŠแž‘แžถแŸ†แž„แžขแžŸแŸ‹แžแŸ’แžšแžผแžœแž”แžถแž“แžŸแžšแžŸแŸแžšแž‡แžถแž—แžถแžŸแžถ C แž™แŸ‰แžถแž„แžแžนแž„แžšแžนแž„แž™แŸ„แž„แž‘แŸ…แžแžถแž˜ (แž”แŸ’แžšแž™แŸแžแŸ’แž“แŸ– PDF แžœแŸ‚แž„) แžŸแŸ’แžแž„แŸ‹แžŠแžถแžš C11 แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž›แžธแž“แžปแž… แž“แžทแž„แž˜แžถแž“แž“แŸ…แž›แžพ GitHub.

แž แŸแžแžปแžขแŸ’แžœแžธแž…แžถแŸ†แž”แžถแž…แŸ‹แž˜แŸ‰แŸ’แž›แŸแŸ‡?

แž‡แžถแž˜แžฝแž™แž“แžนแž„แž€แžถแžšแž€แžพแž“แžกแžพแž„แž“แŸƒแž”แŸ’แžšแž‡แžถแž”แŸ’แžšแžทแž™แž—แžถแž–แž“แŸƒแžขแŸŠแžทแž“แž’แžบแžŽแžทแž แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแž”แžŽแŸ’แžแžถแž‰แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แžแŸ’แžšแžผแžœแž€แžถแžšแžŠแžพแž˜แŸ’แž”แžธแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž˜แžฝแž™แž…แŸ†แž“แžฝแž“แž’แŸ†แž€แŸ’แž“แžปแž„แž–แŸแž›แžŠแŸ†แžŽแžถแž›แž‚แŸ’แž“แžถ แžŠแžผแž…แŸ’แž“แŸแŸ‡แžœแžทแž’แžธแžŸแžถแžŸแŸ’แžšแŸ’แžแž–แžธแžšแžแŸ’แžšแžผแžœแž”แžถแž“แžŸแžถแž€แž›แŸ’แž”แž„แŸ– แž€แžถแžšแž‘แž”แŸ‹แžŸแŸ’แž€แžถแžแŸ‹ I/O แž“แŸ…แž›แžพ OS แž˜แžฝแž™แž…แŸ†แž“แžฝแž“แž’แŸ† แž“แžทแž„แž€แžถแžšแž˜แžทแž“แž‘แž”แŸ‹แžŸแŸ’แž€แžถแžแŸ‹ I/O แžšแžฝแž˜แž”แž‰แŸ’แž…แžผแž›แž‚แŸ’แž“แžถแž‡แžถแž˜แžฝแž™ แž”แŸ’แžšแž–แŸแž“แŸ’แž’แž‡แžผแž“แžŠแŸ†แžŽแžนแž„แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ แž แŸ…แž•แž„แžŠแŸ‚แžšแžแžถ "แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’" (epol/kqueue/IOCP/ แž›) แŸ”

แžœแžทแž’แžธแžŸแžถแžŸแŸ’แžšแŸ’แžแžŠแŸ†แž”แžผแž„แž–แžถแž€แŸ‹แž–แŸแž“แŸ’แž’แž“แžนแž„แž€แžถแžšแž”แž„แŸ’แž€แžพแžแžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™ OS แžแŸ’แž˜แžธแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž…แžผแž›แž“แžธแž˜แžฝแž™แŸ—แŸ” แž‚แžปแžŽแžœแžทแž”แžแŸ’แžแžทแžšแž”แžŸแŸ‹แžœแžถแž‚แžบแž€แžถแžšแž’แŸ’แžœแžพแž˜แžถแžแŸ’แžšแžŠแŸ’แž‹แžถแž“แž˜แžทแž“แž›แŸ’แžข: แž”แŸ’แžšแž–แŸแž“แŸ’แž’แž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžšแž“แžนแž„แžแŸ’แžšแžผแžœแžขแž“แžปแžœแžแŸ’แžแž‡แžถแž…แŸ’แžšแžพแž“แŸ” แž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž”แžšแžทแž”แž‘ ะธ แž€แžถแžšแž แŸ…แžแžถแž˜แž”แŸ’แžšแž–แŸแž“แŸ’แž’. แž–แžฝแž€แžœแžถแž‡แžถแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžšแžแŸ’แž›แŸƒ แž แžพแž™แžขแžถแž…แž“แžถแŸ†แžฑแŸ’แž™แžแŸ’แžœแŸ‡ RAM แžฅแžแž‚แžทแžแžแŸ’แž›แŸƒ แž‡แžถแž˜แžฝแž™แž“แžนแž„แž…แŸ†แž“แžฝแž“แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžŠแŸแž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸแŸ”

แž€แŸ†แžŽแŸ‚แžŠแŸ‚แž›แž”แžถแž“แž€แŸ‚แž”แŸ’แžšแŸ‚แž”แžถแž“แž”แž“แŸ’แž›แžทแž… แž…แŸ†แž“แžฝแž“แžแŸแžšแž“แŸƒแžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™ (thread pool) แžŠแŸ„แž™แž แŸแžแžปแž“แŸแŸ‡แž€แžถแžšแž–แžถแžšแž”แŸ’แžšแž–แŸแž“แŸ’แž’แž–แžธแž€แžถแžšแž›แžปแž”แž…แŸ„แž›แž€แžถแžšแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžท แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž“แŸ…แž–แŸแž›แž‡แžถแž˜แžฝแž™แž‚แŸ’แž“แžถแž“แŸแŸ‡ แž”แž„แŸ’แž แžถแž‰แž–แžธแž”แž‰แŸ’แž แžถแžแŸ’แž˜แžธแž˜แžฝแž™แŸ– แž”แŸ’แžšแžŸแžทแž“แž”แžพแž”แžŽแŸ’แžแžปแŸ†แžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แžแŸ’แžšแžผแžœแž”แžถแž“แžšแžถแžšแžถแŸ†แž„แžŠแŸ„แž™แž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžšแžขแžถแž“แž™แžผแžš แž“แŸ„แŸ‡แžšแž“แŸ’แž’แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแžŠแŸ‚แž›แžขแžถแž…แž‘แž‘แžฝแž›แž‘แžทแž“แŸ’แž“แž“แŸแž™แžšแžฝแž…แž แžพแž™แž“แžนแž„แž˜แžทแž“แžขแžถแž…แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž”แžถแž“แž‘แŸแŸ” แž’แŸ’แžœแžพโ€‹แžขแž‰แŸ’แž…แžนแž„แŸ”

แžœแžทแž’แžธแžŸแžถแžŸแŸ’แžšแŸ’แžแž‘แžธแž–แžธแžšแž”แŸ’แžšแžพ แž”แŸ’แžšแž–แŸแž“แŸ’แž’แž‡แžผแž“แžŠแŸ†แžŽแžนแž„แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ (แžงแž”แž€แžšแžŽแŸแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’) แžŠแŸ‚แž›แž•แŸ’แžแž›แŸ‹แžŠแŸ„แž™ OS แŸ” แžขแžแŸ’แžแž”แž‘แž“แŸแŸ‡แž–แžทแž—แžถแž€แŸ’แžŸแžถแžขแŸ†แž–แžธแž”แŸ’แžšแž—แŸแž‘แžงแž”แž€แžšแžŽแŸแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’แž‘แžผแž‘แŸ…แž”แŸ†แž•แžปแž แžŠแŸ„แž™แž•แŸ’แžขแŸ‚แž€แž›แžพแž€แžถแžšแž‡แžผแž“แžŠแŸ†แžŽแžนแž„ (แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ แž€แžถแžšแž‡แžผแž“แžŠแŸ†แžŽแžนแž„) แžขแŸ†แž–แžธแž€แžถแžšแžแŸ’แžšแŸ€แž˜แžแŸ’แž›แžฝแž“แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžš I/O แž‡แžถแž‡แžถแž„แž“แŸ…แž›แžพ แž€แžถแžšแž‡แžผแž“แžŠแŸ†แžŽแžนแž„แžขแŸ†แž–แžธแž€แžถแžšแž”แž‰แŸ’แž…แž”แŸ‹แžšแž”แžŸแŸ‹แž–แžฝแž€แž‚แŸแŸ”. แžงแž‘แžถแž แžšแžŽแŸแžŸแžถแž˜แž‰แŸ’แž‰แž“แŸƒแž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžšแž”แžŸแŸ‹แžœแžถแžขแžถแž…แžแŸ’แžšแžผแžœแž”แžถแž“แžแŸ†แžŽแžถแž„แžŠแŸ„แž™แžŠแŸ’แž™แžถแž€แŸ’แžšแžถแž˜แž”แŸ’แž›แžปแž€แžแžถแž„แž€แŸ’แžšแŸ„แž˜แŸ–

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš Bare-C I/O แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแž–แžทแžŸแŸแžŸแž–แŸแž‰แž›แŸแž‰

แž—แžถแž–แžแžปแžŸแž‚แŸ’แž“แžถแžšแžœแžถแž„แžœแžทแž’แžธแžŸแžถแžŸแŸ’แžšแŸ’แžแž‘แžถแŸ†แž„แž“แŸแŸ‡แž˜แžถแž“แžŠแžผแž…แžแžถแž„แž€แŸ’แžšแŸ„แž˜แŸ–

  • แžšแžถแžšแžถแŸ†แž„แž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžš I/O แž•แŸ’แžขแžถแž€ แž›แŸ†แž แžผแžšแžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹ แžšแž แžผแžแžŠแž›แŸ‹แžšแž แžผแžแžŠแž›แŸ‹ OS แžแŸ’แžšแžนแž˜แžแŸ’แžšแžผแžœแŸ” defragments แž…แžผแž› แž€แž‰แŸ’แž…แž”แŸ‹ IP แž‘แŸ…โ€‹แžŸแŸ’แž‘แŸ’แžšแžธแž˜โ€‹แž”แŸƒ (TCPแž‘แž‘แžฝแž›แž‘แžทแž“แŸ’แž“แž“แŸแž™) แžฌแžœแžถแž“แžนแž„แž˜แžทแž“แž˜แžถแž“แž€แž“แŸ’แž›แŸ‚แž„แž‘แŸ†แž“แŸแžšแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแžถแž“แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแžแžทแž”แžŽแŸ’แžŠแŸ„แŸ‡แžขแžถแžŸแž“แŸ’แž“แž“แŸƒแž€แžถแžšแžŸแžšแžŸแŸแžšแž•แŸ’แž‘แŸƒแž€แŸ’แž“แžปแž„แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž•แŸ’แž‰แžพแž‡แžถแž”แž“แŸ’แžแž”แž“แŸ’แž‘แžถแž”แŸ‹แžแžถแž˜แžšแž™แŸˆ NIC (แž”แž‰แŸ’แž‡แžผแž“แž‘แžทแž“แŸ’แž“แž“แŸแž™) แŸ”
  • แžงแž”แž€แžšแžŽแŸแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’ แž แžฝแžŸแž–แŸแž› แž‡แžผแž“แžŠแŸ†แžŽแžนแž„แžŠแž›แŸ‹แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžแžถ OS แžšแžฝแž…แž‘แŸ…แž แžพแž™ แž€แž‰แŸ’แž…แž”แŸ‹ IP แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แžถแž“ defragmented (TCP, แž€แžถแžšแž‘แž‘แžฝแž›แž‘แžทแž“แŸ’แž“แž“แŸแž™) แžฌแž‘แŸ†แž แŸ†แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแžถแž“แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแžแžทแž”แžŽแŸ’แžŠแŸ„แŸ‡แžขแžถแžŸแž“แŸ’แž“แžแžถแž„แž€แŸ’แž“แžปแž„ แžšแžฝแž…แž‘แŸ…แž แžพแž™ แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“ (แž”แž‰แŸ’แž‡แžผแž“แž‘แžทแž“แŸ’แž“แž“แŸแž™) แŸ”

แžŸแžšแžปแž”แž˜แž€ แž€แžถแžšแžšแž€แŸ’แžŸแžถแž‘แžปแž€แž“แžผแžœ OS แžŸแž˜แŸ’แžšแžถแž”แŸ‹ I/O แž“แžธแž˜แžฝแž™แŸ— แž‚แžบแž‡แžถแž€แžถแžšแžแŸ’แž‡แŸ‡แžแŸ’แž‡แžถแž™แžแžถแž˜แž–แž›แž€แžปแŸ†แž–แŸ’แž™แžผแž‘แŸแžš แž–แžธแž–แŸ’แžšแŸ„แŸ‡แžแžถแž˜แž–แžทแž แžแŸ’แžŸแŸ‚แžŸแŸ’แžšแž›แžถแž™แž˜แžทแž“แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŠแŸ‚แž›แž˜แžถแž“แž”แŸ’แžšแž™แŸ„แž‡แž“แŸแž‘แŸ (แž แŸแžแžปแž“แŸแŸ‡แž–แžถแž€แŸ’แž™ "แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแŸ†แžแžถแž“") แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž”แž‰แŸ’แž แžถแž“แŸแŸ‡ แžŠแŸ‚แž›แžขแž“แžปแž‰แŸ’แž‰แžถแžแžฑแŸ’แž™แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž’แž“แž’แžถแž“ CPU แž€แžถแž“แŸ‹แžแŸ‚แžŸแž“แŸ’แžŸแŸ†แžŸแŸ†แž…แŸƒแŸ”

แž˜แŸ‰แžผแžŠแŸ‚แž›แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แžŠแžพแžšแžแžฝแž‡แžถแžŸแŸ’แžšแž‘แžถแž”แŸ‹แž˜แžฝแž™แžšแžœแžถแž„แžงแž”แž€แžšแžŽแŸแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’ แž“แžทแž„แž›แŸแžแž€แžผแžŠแžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แŸ” แž‚แŸ„แž›แž€แžถแžšแžŽแŸแž“แŸƒแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžšแžšแž”แžŸแŸ‹แžœแžถแžแŸ’แžšแžผแžœแž”แžถแž“แž–แžทแž–แžŽแŸŒแž“แžถแžŠแŸ„แž™แžŠแŸ’แž™แžถแž€แŸ’แžšแžถแž˜แž”แŸ’แž›แžปแž€แžแžถแž„แž€แŸ’แžšแŸ„แž˜แŸ–

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš Bare-C I/O แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแž–แžทแžŸแŸแžŸแž–แŸแž‰แž›แŸแž‰

  • แžแŸ’แž‰แžปแŸ†แžŸแžผแž˜แžšแŸ†แž›แžนแž€แžขแŸ’แž“แž€แžแžถแž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแž˜แžฝแž™แž‚แžบแž‡แžถแž€แžถแžšแž‡แžผแž“แžŠแŸ†แžŽแžนแž„แžŠแŸ‚แž›แžšแž“แŸ’แž’แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แž˜แžฝแž™แžขแžถแž…แžขแž“แžปแžœแžแŸ’แžแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžš I/O แžŠแŸ‚แž›แž˜แžทแž“แžšแžถแžšแžถแŸ†แž„แŸ”
  • แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแž‚แžบแž‡แžถแž˜แžปแžแž„แžถแžšแž˜แžฝแž™แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แžถแž“แž แŸ…แžŠแŸ„แž™แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž“แŸ…แž–แŸแž›แžŠแŸ‚แž›แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแžแŸ’แžšแžผแžœแž”แžถแž“แž‘แž‘แžฝแž› แžŠแŸ‚แž›แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แž’แŸ’แžœแžพแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžš I/O แžŠแŸ‚แž›แž˜แžทแž“แžšแžถแžšแžถแŸ†แž„แŸ”

แžœแžถแž‡แžถแžšแžฟแž„แžŸแŸ†แžแžถแž“แŸ‹แž€แŸ’แž“แžปแž„แž€แžถแžšแž€แžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹แžแžถ แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž‚แžบแžแžถแž˜แž“แžทแž™แž˜แž“แŸแž™ single-threaded แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž‚แŸ’แž˜แžถแž“แžขแŸ’แžœแžธแžŠแŸ‚แž›แžšแžถแžšแžถแŸ†แž„แž‚แŸ„แž›แž‚แŸ†แž“แžทแžแž“แŸแŸ‡แž–แžธแž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แž”แžšแžทแž™แžถแž€แžถแžŸแž–แž แžปแžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™แž€แŸ’แž“แžปแž„แžŸแž˜แžถแž˜แžถแžแŸ’แžšแž“แŸƒ 1 thread: แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš 1 แžŠแŸ„แž™แž แŸแžแžปแž“แŸแŸ‡แžขแžถแž…แž€แŸ‚แž…แŸ’แž“แŸƒแžŸแŸ’แž“แžผแž›แžŸแŸŠแžธแž—แžธแž™แžผแž‘แžถแŸ†แž„แžขแžŸแŸ‹แŸ”

ะ ะตะฐะปะธะทะฐั†ะธั

แž™แžพแž„แž“แžนแž„แžŠแžถแž€แŸ‹แž…แŸ†แžŽแžปแž…แž”แŸ’แžšแž‘แžถแž€แŸ‹แžŸแžถแž’แžถแžšแžŽแŸˆแž“แŸ…แž€แŸ’แž“แžปแž„แžฏแž€แžŸแžถแžšแž˜แžฝแž™แŸ” reactor.h, แž“แžทแž„แž€แžถแžšแžขแž“แžปแžœแžแŸ’แž - แž€แŸ’แž“แžปแž„ reactor.c. reactor.h แž“แžนแž„แž˜แžถแž“แžŸแŸแž…แž€แŸ’แžแžธแž”แŸ’แžšแž€แžถแžŸแžŠแžผแž…แžแžถแž„แž€แŸ’แžšแŸ„แž˜แŸˆ

แž”แž„แŸ’แž แžถแž‰แž€แžถแžšแž”แŸ’แžšแž€แžถแžŸแž“แŸ…แž€แŸ’แž“แžปแž„ reactor.h

typedef struct reactor Reactor;

/*
 * ะฃะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ ั„ัƒะฝะบั†ะธัŽ, ะบะพั‚ะพั€ะฐั ะฑัƒะดะตั‚ ะฒั‹ะทั‹ะฒะฐั‚ัŒัั I/O ั€ะตะฐะบั‚ะพั€ะพะผ ะฟั€ะธ ะฟะพัั‚ัƒะฟะปะตะฝะธะธ
 * ัะพะฑั‹ั‚ะธั ะพั‚ ัะธัั‚ะตะผะฝะพะณะพ ัะตะปะตะบั‚ะพั€ะฐ.
 */
typedef void (*Callback)(void *arg, int fd, uint32_t events);

/*
 * ะ’ะพะทะฒั€ะฐั‰ะฐะตั‚ `NULL` ะฒ ัะปัƒั‡ะฐะต ะพัˆะธะฑะบะธ, ะฝะต-`NULL` ัƒะบะฐะทะฐั‚ะตะปัŒ ะฝะฐ `Reactor` ะฒ
 * ะฟั€ะพั‚ะธะฒะฝะพะผ ัะปัƒั‡ะฐะต.
 */
Reactor *reactor_new(void);

/*
 * ะžัะฒะพะฑะพะถะดะฐะตั‚ ัะธัั‚ะตะผะฝั‹ะน ัะตะปะตะบั‚ะพั€, ะฒัะต ะทะฐั€ะตะณะธัั‚ั€ะธั€ะพะฒะฐะฝะฝั‹ะต ัะพะบะตั‚ั‹ ะฒ ะดะฐะฝะฝั‹ะน ะผะพะผะตะฝั‚
 * ะฒั€ะตะผะตะฝะธ ะธ ัะฐะผ I/O ั€ะตะฐะบั‚ะพั€.
 *
 * ะกะปะตะดัƒัŽั‰ะธะต ั„ัƒะฝะบั†ะธะธ ะฒะพะทะฒั€ะฐั‰ะฐัŽั‚ -1 ะฒ ัะปัƒั‡ะฐะต ะพัˆะธะฑะบะธ, 0 ะฒ ัะปัƒั‡ะฐะต ัƒัะฟะตั…ะฐ.
 */
int reactor_destroy(Reactor *reactor);

int reactor_register(const Reactor *reactor, int fd, uint32_t interest,
                     Callback callback, void *callback_arg);
int reactor_deregister(const Reactor *reactor, int fd);
int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest,
                       Callback callback, void *callback_arg);

/*
 * ะ—ะฐะฟัƒัะบะฐะตั‚ ั†ะธะบะป ัะพะฑั‹ั‚ะธะน ั ั‚ะฐะนะผ-ะฐัƒั‚ะพะผ `timeout`.
 *
 * ะญั‚ะฐ ั„ัƒะฝะบั†ะธั ะฟะตั€ะตะดะฐัั‚ ัƒะฟั€ะฐะฒะปะตะฝะธะต ะฒั‹ะทั‹ะฒะฐัŽั‰ะตะผัƒ ะบะพะดัƒ ะตัะปะธ ะพั‚ะฒะตะดั‘ะฝะฝะพะต ะฒั€ะตะผั ะฒั‹ัˆะปะพ
 * ะธะปะธ/ะธ ะฟั€ะธ ะพั‚ััƒั‚ัั‚ะฒะธะธ ะทะฐั€ะตะณะธัั‚ั€ะธั€ะพะฒะฐะฝะฝั‹ั… ัะพะบะตั‚ะพะฒ.
 */
int reactor_run(const Reactor *reactor, time_t timeout);

แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’ I/O reactor แž˜แžถแž“ แžขแŸ’แž“แž€แž–แžทแž–แžŽแŸŒแž“แžถแžฏแž€แžŸแžถแžš แžขแŸ’แž“แž€แž‡แŸ’แžšแžพแžŸแžšแžพแžŸ epol ะธ แžแžถแžšแžถแž„ hash GHashTableแžŠแŸ‚แž›แž‚แžผแžŸแž•แŸ‚แž“แž‘แžธแžšแž“แŸ’แž’แž“แžธแž˜แžฝแž™แŸ—แž‘แŸ… CallbackData (แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ แž“แžทแž„แžขแžถแž‚แžปแž™แž˜แŸ‰แž„แŸ‹แžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžœแžถ)แŸ”

แž”แž„แŸ’แž แžถแž‰ Reactor แž“แžทแž„ CallbackData

struct reactor {
    int epoll_fd;
    GHashTable *table; // (int, CallbackData)
};

typedef struct {
    Callback callback;
    void *arg;
} CallbackData;

แžŸแžผแž˜แž…แŸ†แžŽแžถแŸ†แžแžถแž™แžพแž„แž”แžถแž“แž”แžพแž€แžŸแž˜แžแŸ’แžแž—แžถแž–แž€แŸ’แž“แžปแž„แž€แžถแžšแžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™ แž”แŸ’แžšแž—แŸแž‘แž˜แžทแž“แž–แŸแž‰แž›แŸแž‰ แž“แŸแŸ‡แž”แžพแž™แŸ„แž„แžแžถแž˜แžŸแž“แŸ’แž‘แžŸแŸ’แžŸแž“แŸแŸ” IN reactor.h แž™แžพแž„แž”แŸ’แžšแž€แžถแžŸแžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’ reactorแž“แžทแž„แž€แŸ’แž“แžปแž„แŸ” reactor.c แž™แžพแž„แž€แŸ†แžŽแžแŸ‹แžœแžถ แžŠแŸ„แž™แž แŸแžแžปแž“แŸแŸ‡แž€แžถแžšแž–แžถแžšแžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž–แžธแž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแžœแžถแž›แžšแž”แžŸแŸ‹แžœแžถแŸ” แž“แŸแŸ‡แž‚แžบแž‡แžถแž‚แŸ†แžšแžผแž˜แžฝแž™แž€แŸ’แž“แžปแž„แž…แŸ†แžŽแŸ„แž˜แž‚แŸ†แžšแžผ แž›แžถแž€แŸ‹แž‘แžทแž“แŸ’แž“แž“แŸแž™แžŠแŸ‚แž›แžŸแž˜แž™แŸ‰แžถแž„แžแŸ’แž›แžธแž‘แŸ…แž€แŸ’แž“แžปแž„ C semantics แŸ”

แžขแž“แžปแž‚แž˜แž“แŸ reactor_register, reactor_deregister ะธ reactor_reregister แž’แŸ’แžœแžพแž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž—แžถแž–แž”แž‰แŸ’แž‡แžธแžšแž“แŸ’แž’แžŠแŸ‚แž›แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸ แž“แžทแž„แžขแŸ’แž“แž€แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž‚แŸ’แž“แžถแž“แŸ…แž€แŸ’แž“แžปแž„แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’ แž“แžทแž„แžแžถแžšแžถแž„แžŸแž‰แŸ’แž‰แžถแŸ”

แž”แž„แŸ’แž แžถแž‰แž˜แžปแžแž„แžถแžšแž…แžปแŸ‡แžˆแŸ’แž˜แŸ„แŸ‡

#define REACTOR_CTL(reactor, op, fd, interest)                                 
    if (epoll_ctl(reactor->epoll_fd, op, fd,                                   
                  &(struct epoll_event){.events = interest,                    
                                        .data = {.fd = fd}}) == -1) {          
        perror("epoll_ctl");                                                   
        return -1;                                                             
    }

int reactor_register(const Reactor *reactor, int fd, uint32_t interest,
                     Callback callback, void *callback_arg) {
    REACTOR_CTL(reactor, EPOLL_CTL_ADD, fd, interest)
    g_hash_table_insert(reactor->table, int_in_heap(fd),
                        callback_data_new(callback, callback_arg));
    return 0;
}

int reactor_deregister(const Reactor *reactor, int fd) {
    REACTOR_CTL(reactor, EPOLL_CTL_DEL, fd, 0)
    g_hash_table_remove(reactor->table, &fd);
    return 0;
}

int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest,
                       Callback callback, void *callback_arg) {
    REACTOR_CTL(reactor, EPOLL_CTL_MOD, fd, interest)
    g_hash_table_insert(reactor->table, int_in_heap(fd),
                        callback_data_new(callback, callback_arg));
    return 0;
}

แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž”แžถแž“แžŸแŸ’แž‘แžถแž€แŸ‹แž…แžถแž”แŸ‹แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแž‡แžถแž˜แžฝแž™แžขแŸ’แž“แž€แž–แžทแž–แžŽแŸŒแž“แžถ fdแžœแžถแž แŸ…แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž‚แŸ’แž“แžถ แžŠแŸ‚แž›แžœแžถแž†แŸ’แž›แž„แž€แžถแžแŸ‹ fd, แžšแž”แžถแŸ†แž„แž”แŸŠแžธแž แž”แžถแž“โ€‹แž”แž„แŸ’แž€แžพแžโ€‹แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ แž“แžทแž„โ€‹แžขแŸ’แž“แž€โ€‹แž”แŸ’แžšแžพโ€‹แž…แž„แŸ’แžขแžปแž›โ€‹แž‘แŸ… void.

แž”แž„แŸ’แž แžถแž‰แž˜แžปแžแž„แžถแžš reactor_run()

int reactor_run(const Reactor *reactor, time_t timeout) {
    int result;
    struct epoll_event *events;
    if ((events = calloc(MAX_EVENTS, sizeof(*events))) == NULL)
        abort();

    time_t start = time(NULL);

    while (true) {
        time_t passed = time(NULL) - start;
        int nfds =
            epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, timeout - passed);

        switch (nfds) {
        // ะžัˆะธะฑะบะฐ
        case -1:
            perror("epoll_wait");
            result = -1;
            goto cleanup;
        // ะ’ั€ะตะผั ะฒั‹ัˆะปะพ
        case 0:
            result = 0;
            goto cleanup;
        // ะฃัะฟะตัˆะฝะฐั ะพะฟะตั€ะฐั†ะธั
        default:
            // ะ’ั‹ะทะฒะฐั‚ัŒ ะพะฑั€ะฐะฑะพั‚ั‡ะธะบะพะฒ ัะพะฑั‹ั‚ะธะน
            for (int i = 0; i < nfds; i++) {
                int fd = events[i].data.fd;

                CallbackData *callback =
                    g_hash_table_lookup(reactor->table, &fd);
                callback->callback(callback->arg, fd, events[i].events);
            }
        }
    }

cleanup:
    free(events);
    return result;
}

แžŠแžพแž˜แŸ’แž”แžธแžŸแž„แŸ’แžแŸแž” แžแŸ’แžŸแŸ‚แžŸแž„แŸ’แžœแžถแž€แŸ‹แž“แŸƒแž€แžถแžšแž แŸ…แž˜แžปแžแž„แžถแžšแž“แŸ…แž€แŸ’แž“แžปแž„แž€แžผแžŠแžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž“แžนแž„แž˜แžถแž“แž‘แž˜แŸ’แžšแž„แŸ‹แžŠแžผแž…แžแžถแž„แž€แŸ’แžšแŸ„แž˜แŸ–

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš Bare-C I/O แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแž–แžทแžŸแŸแžŸแž–แŸแž‰แž›แŸแž‰

แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžŠแŸ‚แž›แž˜แžถแž“แžแŸ’แžŸแŸ‚แžแŸ‚แž˜แžฝแž™

แžŠแžพแž˜แŸ’แž”แžธแžŸแžถแž€แž›แŸ’แž”แž„แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž“แŸ…แž€แŸ’แžšแŸ„แž˜แž”แž“แŸ’แž‘แžปแž€แžแŸ’แž–แžŸแŸ‹ แž™แžพแž„แž“แžนแž„แžŸแžšแžŸแŸแžšแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแž‚แŸแž แž‘แŸ†แž–แŸแžš HTTP แžŸแžถแž˜แž‰แŸ’แž‰แžŠแŸ‚แž›แž†แŸ’แž›แžพแž™แžแž”แž‘แŸ…แž“แžนแž„แžŸแŸ†แžŽแžพแžŽแžถแž˜แžฝแž™แž‡แžถแž˜แžฝแž™แž“แžนแž„แžšแžผแž”แž—แžถแž–แŸ”

แžŸแŸแž…แž€แŸ’แžแžธแž™แŸ„แž„แžšแž แŸแžŸแž…แŸ†แž–แŸ„แŸ‡แž–แžทแž’แžธแž€แžถแžš HTTP

แžšแž”แžŸแŸ‹ HTTP - แž“แŸแŸ‡แž‚แžบแž‡แžถแž–แžทแž’แžธแž€แžถแžš แž€แž˜แŸ’แžšแžทแžแž€แž˜แŸ’แž˜แžœแžทแž’แžธแžแŸ’แžšแžผแžœแž”แžถแž“แž”แŸ’แžšแžพแž‡แžถแž…แž˜แŸ’แž”แž„แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžขแž“แŸ’แžแžšแž€แž˜แŸ’แž˜แžšแžœแžถแž„แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ แž“แžทแž„แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแžปแž€แžšแž€แŸ”

HTTP แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“แž™แŸ‰แžถแž„แž„แžถแž™แžŸแŸ’แžšแžฝแž› แžŠแžนแž€แž‡แž‰แŸ’แž‡แžผแž“ แž–แžทแž’แžธแž€แžถแžš TCPแž•แŸ’แž‰แžพ แž“แžทแž„แž‘แž‘แžฝแž›แžŸแžถแžšแž€แŸ’แž“แžปแž„แž‘แž˜แŸ’แžšแž„แŸ‹แžŠแŸ‚แž›แž”แžถแž“แž”แž‰แŸ’แž‡แžถแž€แŸ‹ แž€แžถแžšแž”แž‰แŸ’แž‡แžถแž€แŸ‹.

แž‘แž˜แŸ’แžšแž„แŸ‹แžŸแŸ’แž“แžพแžŸแžปแŸ†

<ะšะžะœะะะ”ะ> <URI> <ะ’ะ•ะ ะกะ˜ะฏ HTTP>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 1>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 2>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš N>CRLF CRLF
<ะ”ะะะะซะ•>

  • CRLF แž‚แžบแž‡แžถแž›แŸ†แžŠแžถแž”แŸ‹แž“แŸƒแžแžฝแžขแž€แŸ’แžŸแžšแž–แžธแžšแŸ– r ะธ nแžŠแŸ„แž™แž”แŸ†แž”แŸ‚แž€แž”แž“แŸ’แž‘แžถแžแŸ‹แž‘แžธแž˜แžฝแž™แž“แŸƒแžŸแŸ†แžŽแžพ แž”แž‹แž˜แž€แžแžถ แž“แžทแž„แž‘แžทแž“แŸ’แž“แž“แŸแž™แŸ”
  • <ะšะžะœะะะ”ะ> - แž˜แžฝแž™โ€‹แž“แŸƒ CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE. แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแžปแž€แžšแž€แž“แžนแž„แž•แŸ’แž‰แžพแž–แžถแž€แŸ’แž™แž”แž‰แŸ’แž‡แžถแž‘แŸ…แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžšแž”แžŸแŸ‹แž™แžพแž„แŸ” GETแž˜แžถแž“แž“แŸแž™แžแžถ "แž•แŸ’แž‰แžพแž˜แž€แžแŸ’แž‰แžปแŸ†แž“แžผแžœแž˜แžถแžแžทแž€แžถแž“แŸƒแžฏแž€แžŸแžถแžšแŸ”"
  • <URI> - แžงแž”แž€แžšแžŽแŸแž€แŸ†แžŽแžแŸ‹แžขแžแŸ’แžแžŸแž‰แŸ’แž‰แžถแžŽแž’แž“แž’แžถแž“แžฏแž€แžŸแžŽแŸ’แž‹แžถแž“. แžงแž‘แžถแž แžšแžŽแŸแž”แŸ’แžšแžŸแžทแž“แž”แžพ URI = /index.htmlแž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แžขแžแžทแžแžทแž‡แž“แžŸแŸ’แž“แžพแžŸแžปแŸ†แž‘แŸ†แž–แŸแžšแž˜แŸแž“แŸƒแž‚แŸแž แž‘แŸ†แž–แŸแžšแŸ”
  • <ะ’ะ•ะ ะกะ˜ะฏ HTTP> - แž€แŸ†แžŽแŸ‚แž“แŸƒแž–แžทแž’แžธแž€แžถแžš HTTP แž€แŸ’แž“แžปแž„แž‘แž˜แŸ’แžšแž„แŸ‹ HTTP/X.Y. แž€แŸ†แžŽแŸ‚แžŠแŸ‚แž›แž”แŸ’แžšแžพแž…แŸ’แžšแžพแž“แž”แŸ†แž•แžปแžแž“แžถแž–แŸแž›แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž“แŸแŸ‡แž‚แžบ HTTP/1.1.
  • <ะ—ะะ“ะžะ›ะžะ’ะžะš N> แž‚แžบแž‡แžถแž‚แžผแžแž˜แŸ’แž›แŸƒแž‚แž“แŸ’แž›แžนแŸ‡แž€แŸ’แž“แžปแž„แž‘แž˜แŸ’แžšแž„แŸ‹ <ะšะ›ะฎะง>: <ะ—ะะะงะ•ะะ˜ะ•>แž•แŸ’แž‰แžพแž‘แŸ…แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžœแžทแž—แžถแž‚แž”แž“แŸ’แžแŸ‚แž˜แŸ”
  • <ะ”ะะะะซะ•> - แž‘แžทแž“แŸ’แž“แž“แŸแž™แžแž˜แŸ’แžšแžผแžœแžŠแŸ„แž™แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ แžŠแžพแž˜แŸ’แž”แžธแžขแž“แžปแžœแžแŸ’แžแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžšแŸ” แž‡แžถแžšแžฟแž™แŸ—แžœแžถแžŸแžถแž˜แž‰แŸ’แž‰แžŽแžถแžŸแŸ‹แŸ” JSON แžฌแž‘แž˜แŸ’แžšแž„แŸ‹แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแŸ”

แž‘แž˜แŸ’แžšแž„แŸ‹แž†แŸ’แž›แžพแž™แžแž”

<ะ’ะ•ะ ะกะ˜ะฏ HTTP> <ะšะžะ” ะกะขะะขะฃะกะ> <ะžะŸะ˜ะกะะะ˜ะ• ะกะขะะขะฃะกะ>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 1>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš 2>CRLF
<ะ—ะะ“ะžะ›ะžะ’ะžะš N>CRLF CRLF
<ะ”ะะะะซะ•>

  • <ะšะžะ” ะกะขะะขะฃะกะ> แž‚แžบแž‡แžถแž›แŸแžแžŠแŸ‚แž›แžแŸ†แžŽแžถแž„แžฑแŸ’แž™แž›แž‘แŸ’แž’แž•แž›แž“แŸƒแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžšแŸ” แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžšแž”แžŸแŸ‹แž™แžพแž„แž“แžนแž„แžแŸ’แžšแžกแž”แŸ‹แžŸแŸ’แžแžถแž“แž—แžถแž– 200 แž‡แžถแž“แžทแž…แŸ’แž… (แž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžถแžšแž‡แŸ„แž‚แž‡แŸแž™)แŸ”
  • <ะžะŸะ˜ะกะะะ˜ะ• ะกะขะะขะฃะกะ> - แžแŸ’แžŸแŸ‚แžขแž€แŸ’แžŸแžšแžแŸ†แžŽแžถแž„แž“แŸƒแž€แžผแžŠแžŸแŸ’แžแžถแž“แž—แžถแž–แŸ” แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž›แŸแžแž€แžผแžŠแžŸแŸ’แžแžถแž“แž—แžถแž– 200 แž“แŸแŸ‡แž‚แžบ OK.
  • <ะ—ะะ“ะžะ›ะžะ’ะžะš N> - แž”แž‹แž˜แž€แžแžถแž“แŸƒแž‘แž˜แŸ’แžšแž„แŸ‹แžŠแžผแž…แž‚แŸ’แž“แžถแž“แžนแž„แž€แžถแžšแžŸแŸ’แž“แžพแžŸแžปแŸ†แŸ” แž™แžพแž„แž“แžนแž„แž”แŸ’แžšแž‚แž›แŸ‹แž…แŸ†แžŽแž„แž‡แžพแž„แžกแžพแž„แžœแžทแž‰ Content-Length (แž‘แŸ†แž แŸ†แžฏแž€แžŸแžถแžš) แž“แžทแž„ Content-Type: text/html (แž”แŸ’แžšแž—แŸแž‘แž‘แžทแž“แŸ’แž“แž“แŸแž™แžแŸ’แžšแžกแž”แŸ‹แž˜แž€แžœแžทแž‰) แŸ”
  • <ะ”ะะะะซะ•> - แž‘แžทแž“แŸ’แž“แž“แŸแž™แžŠแŸ‚แž›แž”แžถแž“แžŸแŸ’แž“แžพแžŸแžปแŸ†แžŠแŸ„แž™แžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แŸ” แž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแžšแž”แžŸแŸ‹แž™แžพแž„แž“แŸแŸ‡แž‚แžบแž‡แžถแž•แŸ’แž›แžผแžœแž‘แŸ…แž€แžถแž“แŸ‹แžšแžผแž”แž—แžถแž–แž“แŸ…แž€แŸ’แž“แžปแž„ แžšแž”แžŸแŸ‹ HTML.

แžฏแž€แžŸแžถแžš http_server.c (แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžŠแŸ‚แž›แž˜แžถแž“แžแŸ’แžŸแŸ‚แžแŸ‚แž˜แžฝแž™) แžšแžฝแž˜แž”แž‰แŸ’แž…แžผแž›แžฏแž€แžŸแžถแžš common.hแžŠแŸ‚แž›แž˜แžถแž“แž‚แŸ†แžšแžผแž˜แžปแžแž„แžถแžšแžแžถแž„แž€แŸ’แžšแŸ„แž˜แŸ–

แž”แž„แŸ’แž แžถแž‰แž˜แžปแžแž„แžถแžšแž‚แŸ†แžšแžผแž€แŸ’แž“แžปแž„ common.h

/*
 * ะžะฑั€ะฐะฑะพั‚ั‡ะธะบ ัะพะฑั‹ั‚ะธะน, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทะพะฒะตั‚ัั ะฟะพัะปะต ั‚ะพะณะพ, ะบะฐะบ ัะพะบะตั‚ ะฑัƒะดะตั‚
 * ะณะพั‚ะพะฒ ะฟั€ะธะฝัั‚ัŒ ะฝะพะฒะพะต ัะพะตะดะธะฝะตะฝะธะต.
 */
static void on_accept(void *arg, int fd, uint32_t events);

/*
 * ะžะฑั€ะฐะฑะพั‚ั‡ะธะบ ัะพะฑั‹ั‚ะธะน, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทะพะฒะตั‚ัั ะฟะพัะปะต ั‚ะพะณะพ, ะบะฐะบ ัะพะบะตั‚ ะฑัƒะดะตั‚
 * ะณะพั‚ะพะฒ ะพั‚ะฟั€ะฐะฒะธั‚ัŒ HTTP ะพั‚ะฒะตั‚.
 */
static void on_send(void *arg, int fd, uint32_t events);

/*
 * ะžะฑั€ะฐะฑะพั‚ั‡ะธะบ ัะพะฑั‹ั‚ะธะน, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทะพะฒะตั‚ัั ะฟะพัะปะต ั‚ะพะณะพ, ะบะฐะบ ัะพะบะตั‚ ะฑัƒะดะตั‚
 * ะณะพั‚ะพะฒ ะฟั€ะธะฝัั‚ัŒ ั‡ะฐัั‚ัŒ HTTP ะทะฐะฟั€ะพัะฐ.
 */
static void on_recv(void *arg, int fd, uint32_t events);

/*
 * ะŸะตั€ะตะฒะพะดะธั‚ ะฒั…ะพะดัั‰ะตะต ัะพะตะดะธะฝะตะฝะธะต ะฒ ะฝะตะฑะปะพะบะธั€ัƒัŽั‰ะธะน ั€ะตะถะธะผ.
 */
static void set_nonblocking(int fd);

/*
 * ะŸะตั‡ะฐั‚ะฐะตั‚ ะฟะตั€ะตะดะฐะฝะฝั‹ะต ะฐั€ะณัƒะผะตะฝั‚ั‹ ะฒ stderr ะธ ะฒั‹ั…ะพะดะธั‚ ะธะท ะฟั€ะพั†ะตััะฐ ั
 * ะบะพะดะพะผ `EXIT_FAILURE`.
 */
static noreturn void fail(const char *format, ...);

/*
 * ะ’ะพะทะฒั€ะฐั‰ะฐะตั‚ ั„ะฐะนะปะพะฒั‹ะน ะดะตัะบั€ะธะฟั‚ะพั€ ัะพะบะตั‚ะฐ, ัะฟะพัะพะฑะฝะพะณะพ ะฟั€ะธะฝะธะผะฐั‚ัŒ ะฝะพะฒั‹ะต
 * TCP ัะพะตะดะธะฝะตะฝะธั.
 */
static int new_server(bool reuse_port);

แž˜แŸ‰แžถแž€แŸ’แžšแžผแž˜แžปแžแž„แžถแžšแž€แŸแžแŸ’แžšแžผแžœแž”แžถแž“แž–แžทแž–แžŽแŸŒแž“แžถแž•แž„แžŠแŸ‚แžšแŸ” SAFE_CALL() แž แžพแž™แž˜แžปแžแž„แžถแžšแžแŸ’แžšแžผแžœแž”แžถแž“แž€แŸ†แžŽแžแŸ‹ fail(). แž˜แŸ‰แžถแž€แŸ’แžšแžผแž”แŸ’แžšแŸ€แž”แž’แŸ€แž”แžแž˜แŸ’แž›แŸƒแž“แŸƒแž€แž“แŸ’แžŸแŸ„แž˜แž‡แžถแž˜แžฝแž™แž“แžนแž„แž€แŸ†แž แžปแžŸ แž แžพแž™แž”แŸ’แžšแžŸแžทแž“แž”แžพแž›แž€แŸ’แžแžแžŽแŸ’แžŒแž‚แžบแž–แžทแž แž แŸ…แž˜แžปแžแž„แžถแžš fail():

#define SAFE_CALL(call, error)                                                 
    do {                                                                       
        if ((call) == error) {                                                   
            fail("%s", #call);                                                 
        }                                                                      
    } while (false)

แž˜แžปแžแž„แžถแžš fail() แž”แŸ„แŸ‡แž–แžปแž˜แŸ’แž–แžขแžถแž‚แžปแž™แž˜แŸ‰แž„แŸ‹แžŠแŸ‚แž›แž”แžถแž“แž†แŸ’แž›แž„แž€แžถแžแŸ‹แž‘แŸ…แžŸแŸ’แžแžถแž“แžธแž™ (แžŠแžผแž…แž‡แžถ printf()) แž แžพแž™แž”แž‰แŸ’แž…แž”แŸ‹แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžŠแŸ„แž™แž›แŸแžแž€แžผแžŠ EXIT_FAILURE:

static noreturn void fail(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    fprintf(stderr, ": %sn", strerror(errno));
    exit(EXIT_FAILURE);
}

แž˜แžปแžแž„แžถแžš new_server() แžแŸ’แžšแžกแž”แŸ‹แžฏแž€แžŸแžถแžšแž–แžทแž–แžŽแŸŒแž“แžถแž“แŸƒแžšแž“แŸ’แž’ "แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ" แžŠแŸ‚แž›แž”แž„แŸ’แž€แžพแžแžกแžพแž„แžŠแŸ„แž™แž€แžถแžšแž แŸ…แžแžถแž˜แž”แŸ’แžšแž–แŸแž“แŸ’แž’ socket(), bind() ะธ listen() แž“แžทแž„โ€‹แž˜แžถแž“โ€‹แžŸแž˜แžแŸ’แžแž—แžถแž–โ€‹แž‘แž‘แžฝแž›โ€‹แž™แž€โ€‹แž€แžถแžšโ€‹แžแž—แŸ’แž‡แžถแž”แŸ‹โ€‹แž…แžผแž›โ€‹แž€แŸ’แž“แžปแž„โ€‹แž‘แž˜แŸ’แžšแž„แŸ‹โ€‹แž˜แžทแž“โ€‹แž”แžทแž‘แŸ”

แž”แž„แŸ’แž แžถแž‰แž˜แžปแžแž„แžถแžš new_server()

static int new_server(bool reuse_port) {
    int fd;
    SAFE_CALL((fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)),
              -1);

    if (reuse_port) {
        SAFE_CALL(
            setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &(int){1}, sizeof(int)),
            -1);
    }

    struct sockaddr_in addr = {.sin_family = AF_INET,
                               .sin_port = htons(SERVER_PORT),
                               .sin_addr = {.s_addr = inet_addr(SERVER_IPV4)},
                               .sin_zero = {0}};

    SAFE_CALL(bind(fd, (struct sockaddr *)&addr, sizeof(addr)), -1);
    SAFE_CALL(listen(fd, SERVER_BACKLOG), -1);
    return fd;
}

  • แž…แŸ†แžŽแžถแŸ†แžแžถแžšแž“แŸ’แž’แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž€แžพแžแžŠแŸ†แž”แžผแž„แž€แŸ’แž“แžปแž„แžšแž”แŸ€แž”แž˜แžทแž“แž‘แž”แŸ‹แžŸแŸ’แž€แžถแžแŸ‹แžŠแŸ„แž™แž”แŸ’แžšแžพแž‘แž„แŸ‹ SOCK_NONBLOCKแžŠแžผแž…แŸ’แž“แŸแŸ‡แž“แŸ…แž€แŸ’แž“แžปแž„แž˜แžปแžแž„แžถแžš on_accept() (แžขแžถแž“แž”แž“แŸ’แžแŸ‚แž˜) แž€แžถแžšแž แŸ…แžแžถแž˜แž”แŸ’แžšแž–แŸแž“แŸ’แž’ accept() แž˜แžทแž“แž”แžถแž“แž”แž‰แŸ’แžˆแž”แŸ‹แž€แžถแžšแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™แž‘แŸแŸ”
  • แž”แŸ’แžšแžŸแžทแž“แž”แžพแž˜แžถแž“ reuse_port แžŸแŸ’แž˜แžพ trueแž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แž˜แžปแžแž„แžถแžšแž“แŸแŸ‡แž“แžนแž„แž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แžšแž“แŸ’แž’แž‡แžถแž˜แžฝแž™แž“แžนแž„แž‡แž˜แŸ’แžšแžพแžŸ SO_REUSEPORT แž†แŸ’แž›แž„แž€แžถแžแŸ‹แŸ” setsockopt()แžŠแžพแž˜แŸ’แž”แžธแž”แŸ’แžšแžพแž…แŸ’แžšแž€แžŠแžผแž…แž‚แŸ’แž“แžถแž“แŸ…แž€แŸ’แž“แžปแž„แž”แžšแžทแž™แžถแž€แžถแžŸแž–แž แžปแžแŸ’แžŸแŸ‚ (แžŸแžผแž˜แž˜แžพแž›แž•แŸ’แž“แŸ‚แž€ "แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแž–แž แžปแžแŸ’แžŸแŸ‚") แŸ”

แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ on_accept() แž แŸ…แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธ OS แž”แž„แŸ’แž€แžพแžแž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแž˜แžฝแž™แŸ” EPOLLINแž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแž“แŸแŸ‡แž˜แžถแž“แž“แŸแž™แžแžถแž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžแŸ’แž˜แžธแžขแžถแž…แž‘แž‘แžฝแž›แž™แž€แž”แžถแž“แŸ” on_accept() แž‘แž‘แžฝแž›โ€‹แž™แž€โ€‹แž€แžถแžšโ€‹แžแž—แŸ’แž‡แžถแž”แŸ‹โ€‹แžแŸ’แž˜แžธ แž”แŸ’แžŠแžผแžšโ€‹แžœแžถโ€‹แž‘แŸ…โ€‹แžšแž”แŸ€แž”โ€‹แž˜แžทแž“โ€‹แž‘แž”แŸ‹แžŸแŸ’แž€แžถแžแŸ‹ แž แžพแž™โ€‹แž…แžปแŸ‡แžˆแŸ’แž˜แŸ„แŸ‡โ€‹แž‡แžถแž˜แžฝแž™โ€‹แž€แž˜แŸ’แž˜แžœแžทแž’แžธโ€‹แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™โ€‹แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ on_recv() แž“แŸ…แž€แŸ’แž“แžปแž„แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แŸ”

แž”แž„แŸ’แž แžถแž‰แž˜แžปแžแž„แžถแžš on_accept()

static void on_accept(void *arg, int fd, uint32_t events) {
    int incoming_conn;
    SAFE_CALL((incoming_conn = accept(fd, NULL, NULL)), -1);
    set_nonblocking(incoming_conn);
    SAFE_CALL(reactor_register(reactor, incoming_conn, EPOLLIN, on_recv,
                               request_buffer_new()),
              -1);
}

แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ on_recv() แž แŸ…แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธ OS แž”แž„แŸ’แž€แžพแžแž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแž˜แžฝแž™แŸ” EPOLLINแž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแž“แŸแŸ‡แž˜แžถแž“แž“แŸแž™แžแžถแž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž”แžถแž“แž…แžปแŸ‡แžˆแŸ’แž˜แŸ„แŸ‡ on_accept()แžšแžฝแž…แžšแžถแž›แŸ‹แž€แŸ’แž“แžปแž„แž€แžถแžšแž‘แž‘แžฝแž›แž‘แžทแž“แŸ’แž“แž“แŸแž™แŸ”

on_recv() แžขแžถแž“แž‘แžทแž“แŸ’แž“แž“แŸแž™แž–แžธแž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžšแž แžผแžแžŠแž›แŸ‹แžŸแŸ†แžŽแžพ HTTP แžแŸ’แžšแžผแžœแž”แžถแž“แž‘แž‘แžฝแž›แž‘แžถแŸ†แž„แžŸแŸ’แžšแžปแž„ แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แžœแžถแž…แžปแŸ‡แžˆแŸ’แž˜แŸ„แŸ‡แžขแŸ’แž“แž€แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™ on_send() แžŠแžพแž˜แŸ’แž”แžธแž•แŸ’แž‰แžพแž€แžถแžšแž†แŸ’แž›แžพแž™แžแž” HTTP แŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž—แŸ’แž‰แŸ€แžœแž•แŸ’แžแžถแž…แŸ‹แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹ แžšแž“แŸ’แž’แžแŸ’แžšแžผแžœแž”แžถแž“แž›แžปแž”แžˆแŸ’แž˜แŸ„แŸ‡ แž“แžทแž„แž”แžทแž‘แžŠแŸ„แž™แž”แŸ’แžšแžพ close().

แž”แž„แŸ’แž แžถแž‰แž˜แžปแžแž„แžถแžš on_recv()

static void on_recv(void *arg, int fd, uint32_t events) {
    RequestBuffer *buffer = arg;

    // ะŸั€ะธะฝะธะผะฐะตะผ ะฒั…ะพะดะฝั‹ะต ะดะฐะฝะฝั‹ะต ะดะพ ั‚ะตั… ะฟะพั€, ั‡ั‚ะพ recv ะฒะพะทะฒั€ะฐั‚ะธั‚ 0 ะธะปะธ ะพัˆะธะฑะบัƒ
    ssize_t nread;
    while ((nread = recv(fd, buffer->data + buffer->size,
                         REQUEST_BUFFER_CAPACITY - buffer->size, 0)) > 0)
        buffer->size += nread;

    // ะšะปะธะตะฝั‚ ะพะฑะพั€ะฒะฐะป ัะพะตะดะธะฝะตะฝะธะต
    if (nread == 0) {
        SAFE_CALL(reactor_deregister(reactor, fd), -1);
        SAFE_CALL(close(fd), -1);
        request_buffer_destroy(buffer);
        return;
    }

    // read ะฒะตั€ะฝัƒะป ะพัˆะธะฑะบัƒ, ะพั‚ะปะธั‡ะฝัƒัŽ ะพั‚ ะพัˆะธะฑะบะธ, ะฟั€ะธ ะบะพั‚ะพั€ะพะน ะฒั‹ะทะพะฒ ะทะฐะฑะปะพะบะธั€ัƒะตั‚
    // ะฟะพั‚ะพะบ
    if (errno != EAGAIN && errno != EWOULDBLOCK) {
        request_buffer_destroy(buffer);
        fail("read");
    }

    // ะŸะพะปัƒั‡ะตะฝ ะฟะพะปะฝั‹ะน HTTP ะทะฐะฟั€ะพั ะพั‚ ะบะปะธะตะฝั‚ะฐ. ะขะตะฟะตั€ัŒ ั€ะตะณะธัั‚ั€ะธั€ัƒะตะผ ะพะฑั€ะฐะฑะพั‚ั‡ะธะบะฐ
    // ัะพะฑั‹ั‚ะธะน ะดะปั ะพั‚ะฟั€ะฐะฒะบะธ ะดะฐะฝะฝั‹ั…
    if (request_buffer_is_complete(buffer)) {
        request_buffer_clear(buffer);
        SAFE_CALL(reactor_reregister(reactor, fd, EPOLLOUT, on_send, buffer),
                  -1);
    }
}

แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸ on_send() แž แŸ…แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธ OS แž”แž„แŸ’แž€แžพแžแž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแž˜แžฝแž™แŸ” EPOLLOUTแž˜แžถแž“แž“แŸแž™แžแžถแž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž”แžถแž“แž…แžปแŸ‡แžˆแŸ’แž˜แŸ„แŸ‡ on_recv()แžšแžฝแž…แžšแžถแž›แŸ‹แž€แŸ’แž“แžปแž„แž€แžถแžšแž•แŸ’แž‰แžพแž‘แžทแž“แŸ’แž“แž“แŸแž™แŸ” แž˜แžปแžแž„แžถแžšแž“แŸแŸ‡แž•แŸ’แž‰แžพแž€แžถแžšแž†แŸ’แž›แžพแž™แžแž” HTTP แžŠแŸ‚แž›แž˜แžถแž“แžšแžผแž”แž—แžถแž– HTML แž‘แŸ…แž€แžถแž“แŸ‹แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž—แŸ’แž‰แŸ€แžœ แž แžพแž™แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž€แž˜แŸ’แž˜แžœแžทแž’แžธแžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแžแŸ’แžšแžกแž”แŸ‹แž‘แŸ…แžœแžทแž‰แŸ” on_recv().

แž”แž„แŸ’แž แžถแž‰แž˜แžปแžแž„แžถแžš on_send()

static void on_send(void *arg, int fd, uint32_t events) {
    const char *content = "<img "
                          "src="https://habrastorage.org/webt/oh/wl/23/"
                          "ohwl23va3b-dioerobq_mbx4xaw.jpeg">";
    char response[1024];
    sprintf(response,
            "HTTP/1.1 200 OK" CRLF "Content-Length: %zd" CRLF "Content-Type: "
            "text/html" DOUBLE_CRLF "%s",
            strlen(content), content);

    SAFE_CALL(send(fd, response, strlen(response), 0), -1);
    SAFE_CALL(reactor_reregister(reactor, fd, EPOLLIN, on_recv, arg), -1);
}

แž แžพแž™แž…แžปแž„แž€แŸ’แžšแŸ„แž™แž“แŸ…แž€แŸ’แž“แžปแž„แžฏแž€แžŸแžถแžš http_server.c, แž“แŸ…แž€แŸ’แž“แžปแž„แž˜แžปแžแž„แžถแžš main() แž™แžพแž„แž”แž„แŸ’แž€แžพแžแžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แžŠแŸ„แž™แž”แŸ’แžšแžพ reactor_new()แž”แž„แŸ’แž€แžพแžแžšแž“แŸ’แž’แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ แž แžพแž™แž…แžปแŸ‡แžˆแŸ’แž˜แŸ„แŸ‡แžœแžถ แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžšแžŠแŸ„แž™แž”แŸ’แžšแžพ reactor_run() แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž˜แžฝแž™แž“แžถแž‘แžธแž–แžทแžแž”แŸ’แžšแžถแž€แžŠ แž แžพแž™แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แž™แžพแž„แž”แž‰แŸ’แž…แŸแž‰แž’แž“แž’แžถแž“ แž“แžทแž„แž…แŸแž‰แž–แžธแž€แž˜แŸ’แž˜แžœแžทแž’แžธแŸ”

แž”แž„แŸ’แž แžถแž‰ http_server.c

#include "reactor.h"

static Reactor *reactor;

#include "common.h"

int main(void) {
    SAFE_CALL((reactor = reactor_new()), NULL);
    SAFE_CALL(
        reactor_register(reactor, new_server(false), EPOLLIN, on_accept, NULL),
        -1);
    SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1);
    SAFE_CALL(reactor_destroy(reactor), -1);
}

แžŸแžผแž˜แž–แžทแž“แžทแžแŸ’แž™แž˜แžพแž›แžแžถแžขแŸ’แžœแžธแŸ—แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŠแžผแž…แž€แžถแžšแžšแŸ†แž–แžนแž„แž‘แžปแž€แŸ” แž€แžถแžšแž…แž„แž€แŸ’แžšแž„ (chmod a+x compile.sh && ./compile.sh แž“แŸ…แž€แŸ’แž“แžปแž„แž‚แž˜แŸ’แžšแŸ„แž„ root) แž แžพแž™แž”แžพแž€แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžŠแŸ‚แž›แžŸแžšแžŸแŸแžšแžŠแŸ„แž™แžแŸ’แž›แžฝแž“แžฏแž„แž”แžพแž€ http://127.0.0.1:18470 แž“แŸ…แž€แŸ’แž“แžปแž„ browser แž แžพแž™แž˜แžพแž›แžขแŸ’แžœแžธแžŠแŸ‚แž›แž™แžพแž„แžšแŸ†แž–แžนแž„แž‘แžปแž€แŸ–

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš Bare-C I/O แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแž–แžทแžŸแŸแžŸแž–แŸแž‰แž›แŸแž‰

แž€แžถแžšแžœแžถแžŸแŸ‹แžœแŸ‚แž„แž€แžถแžšแžขแž“แžปแžœแžแŸ’แž

แž”แž„แŸ’แž แžถแž‰แž›แž€แŸ’แžแžŽแŸˆแž”แž…แŸ’แž…แŸแž€แž‘แŸแžŸแžšแžแž™แž“แŸ’แžแžšแž”แžŸแŸ‹แžแŸ’แž‰แžปแŸ†

$ screenfetch
 MMMMMMMMMMMMMMMMMMMMMMMMMmds+.        OS: Mint 19.1 tessa
 MMm----::-://////////////oymNMd+`     Kernel: x86_64 Linux 4.15.0-20-generic
 MMd      /++                -sNMd:    Uptime: 2h 34m
 MMNso/`  dMM    `.::-. .-::.` .hMN:   Packages: 2217
 ddddMMh  dMM   :hNMNMNhNMNMNh: `NMm   Shell: bash 4.4.20
     NMm  dMM  .NMN/-+MMM+-/NMN` dMM   Resolution: 1920x1080
     NMm  dMM  -MMm  `MMM   dMM. dMM   DE: Cinnamon 4.0.10
     NMm  dMM  -MMm  `MMM   dMM. dMM   WM: Muffin
     NMm  dMM  .mmd  `mmm   yMM. dMM   WM Theme: Mint-Y-Dark (Mint-Y)
     NMm  dMM`  ..`   ...   ydm. dMM   GTK Theme: Mint-Y [GTK2/3]
     hMM- +MMd/-------...-:sdds  dMM   Icon Theme: Mint-Y
     -NMm- :hNMNNNmdddddddddy/`  dMM   Font: Noto Sans 9
      -dMNs-``-::::-------.``    dMM   CPU: Intel Core i7-6700 @ 8x 4GHz [52.0ยฐC]
       `/dMNmy+/:-------------:/yMMM   GPU: NV136
          ./ydNMMMMMMMMMMMMMMMMMMMMM   RAM: 2544MiB / 7926MiB
             .MMMMMMMMMMMMMMMMMMM

แž…แžผแžšแžœแžถแžŸแŸ‹แžŸแŸ’แž‘แž„แŸ‹แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž“แŸƒแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžŠแŸ‚แž›แž˜แžถแž“แžแŸ’แžŸแŸ‚แžแŸ‚แž˜แžฝแž™แŸ” แžแŸ„แŸ‡แž”แžพแž€แžŸแŸ’แžแžถแž“แžธแž™แž–แžธแžšแŸ– แž€แŸ’แž“แžปแž„แž˜แžฝแž™แž™แžพแž„แž“แžนแž„แžŠแŸ†แžŽแžพแžšแž€แžถแžš ./http_serverแž“แŸ…โ€‹แž€แŸ’แž“แžปแž„โ€‹แž•แŸ’แžŸแŸแž„โ€‹แž‚แŸ’แž“แžถ - แžŸแŸ’แž“แžถแž˜. แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแž˜แžฝแž™แž“แžถแž‘แžธ แžŸแŸ’แžแžทแžแžทแžแžถแž„แž€แŸ’แžšแŸ„แž˜แž“แžนแž„แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž แžถแž‰แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ’แžแžถแž“แžธแž™แž‘แžธแž–แžธแžšแŸ–

$ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
  8 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   493.52us   76.70us  17.31ms   89.57%
    Req/Sec    24.37k     1.81k   29.34k    68.13%
  11657769 requests in 1.00m, 1.60GB read
Requests/sec: 193974.70
Transfer/sec:     27.19MB

แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžŠแŸ‚แž›แž˜แžถแž“แžแŸ’แžŸแŸ‚แžแŸ‚แž˜แžฝแž™แžšแž”แžŸแŸ‹แž™แžพแž„แžขแžถแž…แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŸแŸ†แžŽแžพแž‡แžถแž„ 11 แž›แžถแž“แž€แŸ’แž“แžปแž„แž˜แžฝแž™แž“แžถแž‘แžธแžŠแŸ‚แž›แž˜แžถแž“แž”แŸ’แžšแž—แž–แž˜แž€แž–แžธ 100 แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แŸ” แž˜แžทแž“โ€‹แž˜แŸ‚แž“โ€‹แž‡แžถโ€‹แž›แž‘แŸ’แž’แž•แž›โ€‹แžขแžถแž€แŸ’แžšแž€แŸ‹โ€‹แž‘แŸ แž”แŸ‰แžปแž“แŸ’แžแŸ‚โ€‹แžแžพโ€‹แžœแžถโ€‹แžขแžถแž…โ€‹แž€แŸ‚แž›แž˜แŸ’แžขโ€‹แž”แžถแž“โ€‹แž‘แŸ?

แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแž–แž แžปแžแŸ’แžŸแŸ‚

แžŠแžผแž…แžŠแŸ‚แž›แž”แžถแž“แžšแŸ€แž”แžšแžถแž”แŸ‹แžแžถแž„แž›แžพ แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แžขแžถแž…แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž€แžพแžแž‡แžถแžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™แžŠแžถแž…แŸ‹แžŠแŸ„แž™แžกแŸ‚แž€ แžŠแŸ„แž™แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžŸแŸ’แž“แžผแž›แžŸแŸŠแžธแž—แžธแž™แžผแž‘แžถแŸ†แž„แžขแžŸแŸ‹แŸ” แž…แžผแžšแž™แžพแž„แžขแž“แžปแžœแžแŸ’แžแžœแžทแž’แžธแžŸแžถแžŸแŸ’แžšแŸ’แžแž“แŸแŸ‡แŸ–

แž”แž„แŸ’แž แžถแž‰ http_server_multithreaded.c

#include "reactor.h"

static Reactor *reactor;
#pragma omp threadprivate(reactor)

#include "common.h"

int main(void) {
#pragma omp parallel
    {
        SAFE_CALL((reactor = reactor_new()), NULL);
        SAFE_CALL(reactor_register(reactor, new_server(true), EPOLLIN,
                                   on_accept, NULL),
                  -1);
        SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1);
        SAFE_CALL(reactor_destroy(reactor), -1);
    }
}

แžฅแžกแžผแžœแž“แŸแŸ‡แž‡แžถแžšแŸ€แž„แžšแžถแž›แŸ‹แžแŸ’แžŸแŸ‚ แž‡แžถโ€‹แž˜แŸ’แž…แžถแžŸแŸ‹โ€‹แžšแž”แžŸแŸ‹โ€‹แžแŸ’แž›แžฝแž“ แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžšแŸ–

static Reactor *reactor;
#pragma omp threadprivate(reactor)

แžŸแžผแž˜แž…แŸ†แžŽแžถแŸ†แžแžถแžขแžถแž‚แžปแž™แž˜แŸ‰แž„แŸ‹แž˜แžปแžแž„แžถแžš new_server() แžขแŸ’แž“แž€แžแžŸแŸŠแžผแž˜แžแžท true. แž“แŸแŸ‡แž˜แžถแž“แž“แŸแž™แžแžถแž™แžพแž„แž•แŸ’แžแž›แŸ‹แž‡แž˜แŸ’แžšแžพแžŸแž‘แŸ…แžšแž“แŸ’แž’แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ SO_REUSEPORTแžŠแžพแž˜แŸ’แž”แžธแž”แŸ’แžšแžพแžœแžถแž“แŸ…แž€แŸ’แž“แžปแž„แž”แžšแžทแž™แžถแž€แžถแžŸแž–แž แžปแžแŸ’แžŸแŸ‚แŸ” แžขแŸ’แž“แž€แžขแžถแž…แžขแžถแž“แž–แŸแžแŸŒแž˜แžถแž“แž›แž˜แŸ’แžขแžทแžแž”แž“แŸ’แžแŸ‚แž˜ แž“แŸ…แž‘แžธแž“แŸแŸ‡.

แž€แžถแžšแžšแžแŸ‹แž›แžพแž€แž‘แžธแž–แžธแžš

แžฅแžกแžผแžœโ€‹แž“แŸแŸ‡โ€‹แž™แžพแž„โ€‹แžœแžถแžŸแŸ‹โ€‹แžŸแŸ’แž‘แž„แŸ‹โ€‹แžŠแŸ†แžŽแžพแžšแž€แžถแžšโ€‹แžšแž”แžŸแŸ‹โ€‹แž˜แŸ‰แžถแžŸแŸŠแžธแž“โ€‹แž˜แŸโ€‹แžŠแŸ‚แž›โ€‹แž˜แžถแž“โ€‹แžแŸ’แžŸแŸ‚โ€‹แž…แŸ’แžšแžพแž“แŸ–

$ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
  8 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.14ms    2.53ms  40.73ms   89.98%
    Req/Sec    79.98k    18.07k  154.64k    78.65%
  38208400 requests in 1.00m, 5.23GB read
Requests/sec: 635876.41
Transfer/sec:     89.14MB

แž…แŸ†แž“แžฝแž“แžŸแŸ†แžŽแžพแžŠแŸ‚แž›แž”แžถแž“แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž€แŸ’แž“แžปแž„แžšแž™แŸˆแž–แŸแž› 1 แž“แžถแž‘แžธแž”แžถแž“แž€แžพแž“แžกแžพแž„ ~ 3.28 แžŠแž„! แž”แŸ‰แžปแž“แŸ’แžแŸ‚โ€‹แž™แžพแž„โ€‹แž˜แžถแž“โ€‹แž…แŸ†แž“แžฝแž“โ€‹แžแžทแž…โ€‹แž‡แžถแž„ แŸข แž›แžถแž“โ€‹แž“แžถแž€แŸ‹โ€‹แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ แžŠแžผแž…แŸ’แž“แŸแŸ‡โ€‹แž™แžพแž„โ€‹แž–แŸ’แž™แžถแž™แžถแž˜โ€‹แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™โ€‹แž”แž‰แŸ’แž แžถโ€‹แž“แŸ„แŸ‡แŸ”

แž‡แžถแžŠแŸ†แž”แžผแž„แžŸแžผแž˜แž€แŸ’แžšแžกแŸแž€แž˜แžพแž›แžŸแŸ’แžแžทแžแžทแžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แžพแž แž›แŸ’แžข:

$ sudo perf stat -B -e task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,branches,branch-misses,cache-misses ./http_server_multithreaded

 Performance counter stats for './http_server_multithreaded':

     242446,314933      task-clock (msec)         #    4,000 CPUs utilized          
         1โ€ฏ813โ€ฏ074      context-switches          #    0,007 M/sec                  
             4โ€ฏ689      cpu-migrations            #    0,019 K/sec                  
               254      page-faults               #    0,001 K/sec                  
   895โ€ฏ324โ€ฏ830โ€ฏ170      cycles                    #    3,693 GHz                    
   621โ€ฏ378โ€ฏ066โ€ฏ808      instructions              #    0,69  insn per cycle         
   119โ€ฏ926โ€ฏ709โ€ฏ370      branches                  #  494,653 M/sec                  
     3โ€ฏ227โ€ฏ095โ€ฏ669      branch-misses             #    2,69% of all branches        
           808โ€ฏ664      cache-misses                                                

      60,604330670 seconds time elapsed

แž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹ CPU Affinity, แž€แžถแžšแž…แž„แž€แŸ’แžšแž„แž‡แžถแž˜แžฝแž™ -march=native, แž—แžธแžขแžšแž€แžถแžšแž€แžพแž“แžกแžพแž„แž“แŸƒแž…แŸ†แž“แžฝแž“แž‘แžŸแŸ’แžŸแž“แžถ แžƒแŸ’แž›แžถแŸ†แž„โ€‹แžŸแž˜แŸ’แž„แžถแžแŸ‹, แž€แžพแž“แžกแžพแž„ MAX_EVENTS แž“แžทแž„แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹ EPOLLET แž˜แžทแž“แž”แžถแž“แž•แŸ’แžแž›แŸ‹แž“แžผแžœแž€แžถแžšแž€แžพแž“แžกแžพแž„แž‚แžฝแžšแžฑแŸ’แž™แž€แžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแŸ” แž”แŸ‰แžปแž“แŸ’แžแŸ‚แžแžพแž˜แžถแž“แžขแŸ’แžœแžธแž€แžพแžแžกแžพแž„แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž”แž„แŸ’แž€แžพแž“แž…แŸ†แž“แžฝแž“แž“แŸƒแž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž€แŸ’แž“แžปแž„แž–แŸแž›แžŠแŸ†แžŽแžถแž›แž‚แŸ’แž“แžถ?

แžŸแŸ’แžแžทแžแžทแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžŠแŸ†แžŽแžถแž›แž‚แŸ’แž“แžถ 352แŸ–

$ wrk -c352 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
  8 threads and 352 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.12ms    3.79ms  68.23ms   87.49%
    Req/Sec    83.78k    12.69k  169.81k    83.59%
  40006142 requests in 1.00m, 5.48GB read
Requests/sec: 665789.26
Transfer/sec:     93.34MB

แž›แž‘แŸ’แž’แž•แž›แžŠแŸ‚แž›แž…แž„แŸ‹แž”แžถแž“แžแŸ’แžšแžผแžœแž”แžถแž“แž‘แž‘แžฝแž› แž แžพแž™แž‡แžถแž˜แžฝแž™แžœแžถแž€แŸ’แžšแžถแž แŸ’แžœแž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸแž”แž„แŸ’แž แžถแž‰แž–แžธแž€แžถแžšแž–แžนแž„แž•แŸ’แžขแŸ‚แž€แž“แŸƒแž…แŸ†แž“แžฝแž“แžŸแŸ†แžŽแžพแžŠแŸ‚แž›แž”แžถแž“แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž€แŸ’แž“แžปแž„แžšแž™แŸˆแž–แŸแž› 1 แž“แžถแž‘แžธแž›แžพแž…แŸ†แž“แžฝแž“แž“แŸƒแž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แŸ–

แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš Bare-C I/O แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแž–แžทแžŸแŸแžŸแž–แŸแž‰แž›แŸแž‰

แž™แžพแž„แžƒแžพแž‰แžแžถแž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแž€แžถแžšแž—แŸ’แž‡แžถแž”แŸ‹แž–แžธแžšแž”แžธแžšแž™แž…แŸ†แž“แžฝแž“แž“แŸƒแžŸแŸ†แžŽแžพแžŠแŸ‚แž›แž”แžถแž“แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแž‘แžถแŸ†แž„แž–แžธแžšแž’แŸ’แž›แžถแž€แŸ‹แž…แžปแŸ‡แž™แŸ‰แžถแž„แžแŸ’แž›แžถแŸ†แž„ (แž“แŸ…แž€แŸ’แž“แžปแž„แž€แŸ†แžŽแŸ‚แž–แž แžปแžแŸ’แžŸแŸ‚แž“แŸแŸ‡แž‚แžบแž‚แžฝแžšแžฑแŸ’แž™แž€แžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹แž‡แžถแž„)แŸ” แžแžพแžœแžถแž‘แžถแž€แŸ‹แž‘แž„แž“แžนแž„แž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแž‡แž„แŸ‹แž›แžธแž“แžปแž… TCP/IP แžŠแŸ‚แžšแžฌแž‘แŸ? แž˜แžถแž“แžขแžถแžšแž˜แŸ’แž˜แžŽแŸแžŸแŸแžšแžธแž€แŸ’แž“แžปแž„แž€แžถแžšแžŸแžšแžŸแŸแžšแž€แžถแžšแžŸแž“แŸ’แž˜แžแŸ‹แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แžขแŸ†แž–แžธแžฅแžšแžทแž™แžถแž”แžแž“แŸแŸ‡แž“แŸƒแž€แŸ’แžšแžถแž แŸ’แžœ แž“แžทแž„แž€แžถแžšแž”แž„แŸ’แž€แžพแž“แž”แŸ’แžšแžŸแžทแž‘แŸ’แž’แž—แžถแž–แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž‡แž˜แŸ’แžšแžพแžŸแžแŸ’แžŸแŸ‚แž…แŸ’แžšแžพแž“ แž“แžทแž„แžแŸ’แžŸแŸ‚แžแŸ‚แž˜แžฝแž™แž“แŸ…แž€แŸ’แž“แžปแž„แž˜แžแžทแž™แŸ„แž”แž›แŸ‹แŸ”

แžแžพแž’แŸ’แžœแžพแžŠแžผแž…แž˜แŸ’แžแŸแž… แž”แžถแž“แž€แžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹ แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸแž…แž€แŸ’แžแžธแžขแž’แžทแž”แŸ’แž”แžถแž™ แž€แžถแžšแž’แŸ’แžœแžพแžแŸแžŸแŸ’แžแžŠแŸ†แžŽแžพแžšแž€แžถแžšแž“แŸแŸ‡แž˜แžทแž“แž”แž„แŸ’แž แžถแž‰แž–แžธแžฅแžšแžทแž™แžถแž”แžแžšแž”แžŸแŸ‹แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž“แŸ…แž€แŸ’แžšแŸ„แž˜แž”แž“แŸ’แž‘แžปแž€แž–แžทแžแž”แŸ’แžšแžถแž€แžŠแž‘แŸ แž–แŸ’แžšแŸ„แŸ‡แžŸแŸ’แž‘แžพแžšแžแŸ‚แž‚แŸ’แžšแž”แŸ‹แž–แŸแž›แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแž’แŸ’แžœแžพแžขแž“แŸ’แžแžšแž€แž˜แŸ’แž˜แž‡แžถแž˜แžฝแž™แž˜แžผแž›แžŠแŸ’แž‹แžถแž“แž‘แžทแž“แŸ’แž“แž“แŸแž™ แž€แŸ†แžŽแžแŸ‹แž แŸแžแžปแž›แž‘แŸ’แž’แž•แž› แž”แŸ’แžšแžพแž‚แŸ’แžšแžธแž”แž‚แŸ’แžšแžธแž”แž‡แžถแž˜แžฝแž™ TLS แž”แžถแž“ แž› แž‡แžถแž›แž‘แŸ’แž’แž•แž›แžŠแŸ‚แž›แž”แž“แŸ’แž‘แžปแž€แž€แŸ’แž›แžถแž™แž‘แŸ…แž‡แžถแž˜แžทแž“แžŸแŸ’แž˜แžพแž‚แŸ’แž“แžถ (แžแžถแž˜แžœแž“แŸ’แž)แŸ” แž€แžถแžšแž’แŸ’แžœแžพแžแŸแžŸแŸ’แžแžšแžฝแž˜แž‚แŸ’แž“แžถแž‡แžถแž˜แžฝแž™แžŸแž˜แžถแžŸแž’แžถแžแžปแž—แžถแž‚แžธแž‘แžธแž”แžธแž“แžนแž„แžแŸ’แžšแžผแžœแž”แžถแž“แžขแž“แžปแžœแžแŸ’แžแž“แŸ…แž€แŸ’แž“แžปแž„แžขแžแŸ’แžแž”แž‘แžขแŸ†แž–แžธ I/O proactor แŸ”

แž‚แžปแžŽแžœแžทแž”แžแŸ’แžแžทแž“แŸƒแžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O

แžขแŸ’แž“แž€แžแŸ’แžšแžผแžœแž™แž›แŸ‹แžแžถ แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž˜แžทแž“แž˜แŸ‚แž“แžŠแŸ„แž™แž‚แŸ’แž˜แžถแž“แž‚แžปแžŽแžœแžทแž”แžแŸ’แžแžทแžšแž”แžŸแŸ‹แžœแžถแž‘แŸ แž–แŸ„แž›แž‚แžบแŸ–

  • แž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžšแŸ‰แŸแžขแžถแž€แŸ‹แž‘แŸแžš I/O แž“แŸ…แž€แŸ’แž“แžปแž„แž”แžšแžทแž™แžถแž€แžถแžŸแž–แž แžปแžแŸ’แžŸแŸ‚แž‚แžบแž–แžทแž”แžถแž€แž‡แžถแž„แž”แž“แŸ’แžแžทแž… แž–แžธแž–แŸ’แžšแŸ„แŸ‡ แžขแŸ’แž“แž€แž“แžนแž„แžแŸ’แžšแžผแžœแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž›แŸ†แž แžผแžšแžŠแŸ„แž™แžŠแŸƒแŸ”
  • แž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแž”แž„แŸ’แž แžถแž‰แžแžถแž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแž—แžถแž‚แž…แŸ’แžšแžพแž“แž€แžถแžšแž•แŸ’แž‘แžปแž€แž˜แžทแž“แžŸแŸ’แž˜แžพแž‚แŸ’แž“แžถแžŠแŸ‚แž›แžขแžถแž…แž“แžถแŸ†แžฑแŸ’แž™แž˜แžถแž“แž€แžถแžšแž€แžถแž”แŸ‹แžˆแžพแž˜แžฝแž™แžแŸ’แžŸแŸ‚แžแžŽแŸˆแž–แŸแž›แžŠแŸ‚แž›แž˜แžฝแž™แž‘แŸ€แžแžšแžœแž›แŸ‹แž‡แžถแž˜แžฝแž™แž€แžถแžšแž„แžถแžšแŸ”
  • แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž–แŸ’แžšแžนแžแŸ’แžแžทแž€แžถแžšแžŽแŸแž˜แžฝแž™แžšแžถแžšแžถแŸ†แž„แžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™ แž“แŸ„แŸ‡แžขแŸ’แž“แž€แž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแž–แŸแž“แŸ’แž’แžแŸ’แž›แžฝแž“แžฏแž„แž€แŸแž“แžนแž„แž‘แž”แŸ‹แžŸแŸ’แž€แžถแžแŸ‹แž•แž„แžŠแŸ‚แžš แžŠแŸ‚แž›แžขแžถแž…แž“แžถแŸ†แžฑแŸ’แž™แž–แžทแž”แžถแž€แžŸแŸ’แžœแŸ‚แž„แžšแž€แž€แŸ†แž แžปแžŸแŸ”

แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž”แž‰แŸ’แž แžถแž‘แžถแŸ†แž„แž“แŸแŸ‡ แž—แŸ’แž“แžถแž€แŸ‹แž„แžถแžš I/OแžŠแŸ‚แž›แž‡แžถแžšแžฟแž™แŸ—แž˜แžถแž“แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž€แŸ†แžŽแžแŸ‹แž–แŸแž›แžŠแŸ‚แž›แž…แŸ‚แž€แž…แžถแž™แž”แž“แŸ’แž‘แžปแž€แžŸแŸ’แž˜แžพแŸ—แž‚แŸ’แž“แžถแž‘แŸ…แž€แžถแž“แŸ‹แž”แžŽแŸ’แžแžปแŸ†แž“แŸƒแžแŸ’แžŸแŸ‚แžŸแŸ’แžšแžกแžถแž™ แž แžพแž™แž€แŸแž˜แžถแž“ API แž„แžถแž™แžŸแŸ’แžšแžฝแž›แž‡แžถแž„แž•แž„แžŠแŸ‚แžšแŸ” แž™แžพแž„แž“แžนแž„แž“แžทแž™แžถแž™แžขแŸ†แž–แžธแžœแžถแž“แŸ…แž–แŸแž›แž€แŸ’แžšแŸ„แž™แž“แŸ…แž€แŸ’แž“แžปแž„แžขแžแŸ’แžแž”แž‘แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแžšแž”แžŸแŸ‹แžแŸ’แž‰แžปแŸ†แŸ”

แžŸแŸแž…แž€แŸ’แžแžธแžŸแž“แŸ’แž“แžทแžŠแŸ’แž‹แžถแž“

แž“แŸแŸ‡แž‚แžบแž‡แžถแž€แž“แŸ’แž›แŸ‚แž„แžŠแŸ‚แž›แž€แžถแžšแž’แŸ’แžœแžพแžŠแŸ†แžŽแžพแžšแžšแž”แžŸแŸ‹แž™แžพแž„แž–แžธแž‘แŸ’แžšแžนแžŸแŸ’แžŠแžธแžแŸ’แžšแž„แŸ‹แž…แžผแž›แž‘แŸ…แž€แŸ’แž“แžปแž„แž”แŸ†แž–แž„แŸ‹แž•แŸ’แžŸแŸ‚แž„ profiler แž”แžถแž“แž”แž‰แŸ’แž…แž”แŸ‹แŸ”

แžขแŸ’แž“แž€แž˜แžทแž“แž‚แžฝแžšแž–แžนแž„แž•แŸ’แžขแŸ‚แž€แž›แžพแžšแžฟแž„แž“แŸแŸ‡แž‘แŸ แž–แŸ’แžšแŸ„แŸ‡แž˜แžถแž“แžœแžทแž’แžธแžŸแžถแžŸแŸ’แžšแŸ’แžแž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸแžŠแžผแž…แž‚แŸ’แž“แžถแž‡แžถแž…แŸ’แžšแžพแž“แž‘แŸ€แžแž€แŸ’แž“แžปแž„แž€แžถแžšแžŸแžšแžŸแŸแžšแž€แž˜แŸ’แž˜แžœแžทแž’แžธแž”แžŽแŸ’แžแžถแž‰แž‡แžถแž˜แžฝแž™แž“แžนแž„แž€แž˜แŸ’แžšแžทแžแž—แžถแž–แž„แžถแž™แžŸแŸ’แžšแžฝแž› แž“แžทแž„แž›แŸ’แž”แžฟแž“แžแžปแžŸแŸ—แž‚แŸ’แž“แžถแŸ” แž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸ, แž“แŸ…แž€แŸ’แž“แžปแž„แž‚แŸ†แž“แžทแžแžšแž”แžŸแŸ‹แžแŸ’แž‰แžปแŸ†, แžแŸ†แžŽแž—แŸ’แž‡แžถแž”แŸ‹แžแŸ’แžšแžผแžœแž”แžถแž“แž•แŸ’แžแž›แŸ‹แžฑแŸ’แž™แžแžถแž„แž€แŸ’แžšแŸ„แž˜แŸ”

แžšแž แžผแžแžŠแž›แŸ‹โ€‹แž–แŸแž›แž€แŸ’แžšแŸ„แž™!

แž‚แž˜แŸ’แžšแŸ„แž„แž‚แžฝแžšแžฑแŸ’แž™แž…แžถแž”แŸ‹แžขแžถแžšแž˜แŸ’แž˜แžŽแŸ

แžแžพแžแŸ’แžšแžผแžœแžขแžถแž“แžขแŸ’แžœแžธแž‘แŸ€แž?

แž”แŸ’แžšแž—แž–: www.habr.com

แž”แž“แŸ’แžแŸ‚แž˜แž˜แžแžทแž™แŸ„แž”แž›แŸ‹