การสร้างเซิร์ฟเวอร์สะท้อน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- API ซ็อกเก็ต BSD ใน C++
- การสร้างเซิร์ฟเวอร์สะท้อน TCP
- IO แบบอะซิงโครนัสด้วย epoll และ kqueue
- การใช้ Boost Asio สำหรับ IO แบบอะซิงโครนัสสมัยใหม่