0Pricing
C++ Academy · บทเรียน

การสร้างเซิร์ฟเวอร์สะท้อน TCP

เรียนรู้การสร้างเซิร์ฟเวอร์สะท้อน TCP แบบครบถ้วน

การสร้างเซิร์ฟเวอร์สะท้อน TCP เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

เป้าหมาย

สร้างเซิร์ฟเวอร์ TCP ขั้นต่ำที่รับการเชื่อมต่อ อ่านไบต์ และเขียนไบต์เหล่านั้นกลับไป นี่คือ "Hello World" ของการเขียนโปรแกรมเครือข่าย

โครงร่างเซิร์ฟเวอร์

ลำดับการทำงานของเซิร์ฟเวอร์คือ สร้างซ็อกเก็ต ผูกที่อยู่ รอรับการเชื่อมต่อ รับการเชื่อมต่อ และ handle วนซ้ำตลอดไป

int srv = socket(AF_INET, SOCK_STREAM, 0);
bind(srv, (sockaddr*)&addr, sizeof(addr));
listen(srv, 10);
while (true) {
    int client = accept(srv, nullptr, nullptr);
    handle(client);
    close(client);
}

ตัวเลือกนำที่อยู่กลับมาใช้ใหม่

ตั้งค่า SO_REUSEADDR เพื่อให้เซิร์ฟเวอร์เริ่มทำงานใหม่ได้ทันที โดยไม่ต้องรอให้ OS ปล่อยพอร์ต

int yes = 1;
setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

ลูปสะท้อนกลับ

อ่านข้อมูลลงในบัฟเฟอร์ แล้วเขียนไบต์เดิมกลับไป หยุดเมื่อไคลเอ็นต์ปิดการเชื่อมต่อ

void handle(int client) {
    char buf[1024];
    while (true) {
        ssize_t n = recv(client, buf, sizeof(buf), 0);
        if (n <= 0) break;          // closed or error
        send(client, buf, n, 0);
    }
}

การอ่านและเขียนบางส่วน

ทั้ง recv และ send อาจถ่ายโอนไบต์ได้น้อยกว่าที่ร้องขอ สำหรับโพรโทคอลแบบสตรีม ให้วนซ้ำจนเสร็จ

ssize_t total = 0;
while (total < n) {
    ssize_t s = send(client, buf + total, n - total, 0);
    if (s <= 0) break;
    total += s;
}

การจัดการไคลเอ็นต์หลายราย

วิธีที่ง่ายที่สุดคือสร้างเธรดใหม่ต่อการเชื่อมต่อหนึ่งรายการ วิธีนี้ใช้ได้กับไคลเอ็นต์หลายร้อยราย แต่จะเริ่มมีปัญหาเมื่อมีหลายพันราย

while (true) {
    int client = accept(srv, nullptr, nullptr);
    std::thread([client]{ handle(client); close(client); }).detach();
}

ทางเลือกที่ดีกว่า: กลุ่มเธรด

การสร้างเธรดใหม่ต่อการเชื่อมต่อหนึ่งรายการสิ้นเปลืองทรัพยากรเมื่อขยายขนาดระบบ กลุ่มเธรดแบบคงที่พร้อมคิวงานรองรับการขยายขนาดได้ดีกว่า

การปิดระบบอย่างเรียบร้อย

จัดการ SIGTERM/SIGINT เพื่อปิดซ็อกเก็ตที่รอรับการเชื่อมต่ออย่างเรียบร้อย RAII ยังช่วยให้มั่นใจว่าซ็อกเก็ตของไคลเอ็นต์ทั้งหมดจะถูกปิดด้วย

การจัดการข้อผิดพลาด

มองข้อผิดพลาดเป็นสิ่งที่คาดว่าจะเกิดขึ้นได้ ไคลเอ็นต์ตัดการเชื่อมต่อ เครือข่ายขัดข้องชั่วคราว และขีดจำกัดของ OS ถูกใช้จนหมด ให้บันทึกข้อมูลแล้วทำงานต่อ อย่าทำให้ระบบหยุดทำงานเพราะไคลเอ็นต์ที่มีปัญหา

การบันทึกข้อมูลของไคลเอ็นต์แต่ละราย

บันทึกที่อยู่ระยะไกลเพื่อให้สังเกตการณ์ระบบได้

sockaddr_in remote{};
socklen_t len = sizeof(remote);
int client = accept(srv, (sockaddr*)&remote, &len);
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &remote.sin_addr, ip, sizeof(ip));
std::cout << "client " << ip << ":" << ntohs(remote.sin_port);

การทดสอบด้วย netcat

ทดสอบเซิร์ฟเวอร์สะท้อนกลับของคุณแบบโต้ตอบด้วย nc

nc 127.0.0.1 8080
hello
hello       # echoed back

นอกเหนือจากการสะท้อนกลับ

จากการสะท้อนกลับ คุณสามารถต่อยอดไปยัง:

  • โพรโทคอลแบบใช้บรรทัด (คล้าย HTTP)
  • โพรโทคอลไบนารีแบบมีกรอบ (นำหน้าด้วยความยาว)
  • ข้อความ JSON หรือ Protobuf

ตรวจสอบอย่างรวดเร็ว

ตัวเลือกซ็อกเก็ต SO_REUSEADDR มีจุดประสงค์อะไร

สรุปทบทวน

เซิร์ฟเวอร์สะท้อนกลับ TCP ขั้นต่ำประกอบด้วย socket, setsockopt SO_REUSEADDR, bind, listen และ accept ในลูป สำหรับไคลเอ็นต์หลายราย ให้สร้างเธรดหรือใช้กลุ่มเธรด หากต้องรองรับขนาดใหญ่ ให้เปลี่ยนไปใช้ I/O แบบอะซิงโครนัส (บทเรียนถัดไป)

คำถามที่พบบ่อย

บทเรียน “การสร้างเซิร์ฟเวอร์สะท้อน TCP” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสร้างเซิร์ฟเวอร์สะท้อน TCP” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างเซิร์ฟเวอร์สะท้อน TCP”

เรียนรู้การสร้างเซิร์ฟเวอร์สะท้อน TCP แบบครบถ้วน คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การสร้างเซิร์ฟเวอร์สะท้อน TCP” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม

ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. API ซ็อกเก็ต BSD ใน C++
  2. การสร้างเซิร์ฟเวอร์สะท้อน TCP
  3. IO แบบอะซิงโครนัสด้วย epoll และ kqueue
  4. การใช้ Boost Asio สำหรับ IO แบบอะซิงโครนัสสมัยใหม่
← กลับไปที่ C++ Academy