เซิร์ฟเวอร์ซ็อกเก็ตการประมวลผลหลายตัวที่มีทางแยกในภาษา C ช่วยให้เราสามารถจัดการการเชื่อมต่อไคลเอนต์หลายตัวพร้อมกันได้ ด้วยการใช้การเรียกระบบทางแยก เซิร์ฟเวอร์สามารถสร้างกระบวนการลูกสำหรับไคลเอนต์ที่เชื่อมต่อแต่ละเครื่อง ซึ่งช่วยให้มั่นใจได้ถึงช่องทางการสื่อสารที่เป็นอิสระ แนวทางนี้ช่วยให้สามารถสื่อสารพร้อมกันกับลูกค้าหลายรายได้
ให้เราหารือเกี่ยวกับวิธีใช้งานเซิร์ฟเวอร์ซ็อกเก็ตที่มีการประมวลผลหลายตัวด้วย fork ใน C เราจะอธิบายเกี่ยวกับตัวอย่างการเขียนโปรแกรมของโปรแกรมฝั่งเซิร์ฟเวอร์และโปรแกรมฝั่งไคลเอ็นต์ ซึ่งเราสามารถบรรลุถึงเซิร์ฟเวอร์ซ็อกเก็ตที่มีการประมวลผลหลายตัวด้วย fork ใน C
การเรียกของระบบ Fork คืออะไร
เมื่อการเรียกของระบบสร้างโคลนของกระบวนการที่มีอยู่ จะเรียกว่าการเรียกของระบบ “fork()” โดยพื้นฐานแล้วมันจะแยกโปรแกรมที่รันอยู่ออกเป็นสองกระบวนการแยกกันซึ่งเรียกว่าผู้ปกครองและลูก พารามิเตอร์ทั้งหมดจะเหมือนกันสำหรับกระบวนการลูกและพาเรนต์ ยกเว้นว่ามี PID ที่แตกต่างกัน การเรียกของระบบนี้ส่งคืนสิ่งต่อไปนี้:
- PID ของกระบวนการย่อยไปยังผู้ปกครอง
- ศูนย์ (0) สำหรับเด็ก
ตัวอย่างการเขียนโปรแกรม 1:โปรแกรมฝั่งเซิร์ฟเวอร์
#รวม
#รวม
#รวม
#รวม
#รวม
#รวม
#รวม
#รวม
#กำหนดพอร์ต 8888
int หลัก ()
{
int serSoc, cliSoc;
โครงสร้าง sockaddr_in serverAddr, clientAddr;
socklen_t addrSize =ขนาดของ (clientAddr);
บัฟเฟอร์ถ่าน [1024];
int clientCount =0;
// สร้างซ็อกเก็ตเซิร์ฟเวอร์
serSoc =ซ็อกเก็ต (AF_INET, SOCK_STREAM, 0);
ถ้า (serSoc <0) {
perror ("ข้อผิดพลาดในการสร้างซ็อกเก็ต");
ออก (1);
printf ("สร้างซ็อกเก็ตเซิร์ฟเวอร์แล้ว\n");
// ให้เราตั้งค่าที่อยู่เซิร์ฟเวอร์
serverAddr.sin_family =AF_INET;
serverAddr.sin_port =htons (พอร์ต);
serverAddr.sin_addr.s_addr =INADDR_ANY;
ถ้า (ผูก (serSoc, (struct sockaddr *) &serverAddr, sizeof (serverAddr)) <0) {
perror ("ข้อผิดพลาดในการผูก");
ออก (1);
// เริ่มฟังการเชื่อมต่อที่เข้ามา
ถ้า (ฟัง (serSoc, 5) ==0) {
printf ("กำลังฟังการเชื่อมต่อ...\n");
} อื่น ๆ {
perror ("ข้อผิดพลาดในการฟัง");
ออก (1);
ในขณะที่ (1) {
// ให้เรายอมรับการเชื่อมต่อลูกค้า
cliSoc =ยอมรับ (serSoc, (struct sockaddr* )&clientAddr, &addrSize);
ถ้า (cliSoc <0) {
perror("เกิดข้อผิดพลาดในการรับการเชื่อมต่อ");
ออก (1);
// เพิ่มจำนวนลูกค้าและแสดงข้อมูลลูกค้า
ลูกค้านับ ++;
printf("ยอมรับการเชื่อมต่อจากไคลเอนต์ %d:%s:%d\n", clientCount, inet_ntoa (clientAddr.sin_addr), ntohs (clientAddr.sin_port));
printf ("ลูกค้าทั้งหมดเชื่อมต่อ:%d\n", clientCount);
pid_t pid =ทางแยก ();
ถ้า (pid ==0) {
// กระบวนการลูก
ปิด (serSoc);
// รับข้อความจากลูกค้า
ในขณะที่ (1) {
memset (บัฟเฟอร์, 0, ขนาดของ (บัฟเฟอร์));
if (recv (cliSoc , บัฟเฟอร์, ขนาดของ (บัฟเฟอร์), 0) <0) {
perror ("ข้อผิดพลาดในการรับข้อมูล");
ออก (1);
printf ("ได้รับข้อมูลจากไคลเอนต์ %d:%s\n", clientCount, บัฟเฟอร์);
// สะท้อนข้อความที่ได้รับกลับไปยังไคลเอนต์
ถ้า (ส่ง (cliSoc , บัฟเฟอร์, strlen (บัฟเฟอร์), 0) 0) {
// กระบวนการหลัก
ปิด(cliSoc );
} อื่น ๆ {
perror ("ข้อผิดพลาดในการฟอร์ก");
ออก (1);
}
// ปิดซ็อกเก็ตเซิร์ฟเวอร์
ปิด (serSoc);
กลับ 0;
Prการเขียนโปรแกรมตัวอย่าง 2:โปรแกรมฝั่งไคลเอ็นต์
#รวม
#รวม
#รวม
#รวม
#รวม
#รวม
#รวม
#รวม
#กำหนดพอร์ต 8888
#define SERVER_IP "127.0.0.1"
int หลัก ()
{
int cliSoc;
โครงสร้าง sockaddr_in serverAddr;
บัฟเฟอร์ถ่าน [1024];
// สร้างซ็อกเก็ตไคลเอ็นต์
cliSoc =ซ็อกเก็ต (AF_INET, SOCK_STREAM, 0);
ถ้า (cliSoc <0) {
perror ("ข้อผิดพลาดในการสร้างซ็อกเก็ต");
ออก (1);
printf("ไคลเอนต์ %d ซ็อกเก็ตที่สร้างแล้ว\n", getpid ());
// ตั้งค่าพารามิเตอร์ที่อยู่เซิร์ฟเวอร์
serverAddr.sin_family =AF_INET;
serverAddr.sin_port =htons (พอร์ต);
serverAddr.sin_addr.s_addr =inet_addr (SERVER_IP);
// เชื่อมต่อกับเซิร์ฟเวอร์
ถ้า (เชื่อมต่อ (cliSoc , (struct sockaddr*) &serverAddr, sizeof (serverAddr)) <0) {
perror("ข้อผิดพลาดในการเชื่อมต่อกับเซิร์ฟเวอร์");
ออก (1);
printf ("เชื่อมต่อกับเซิร์ฟเวอร์แล้ว\n");
ในขณะที่ (1) {
// อ่านอินพุตจากผู้ใช้
printf ("ไคลเอนต์ %d - ป้อนข้อความ:", getpid ());
fgets (บัฟเฟอร์, ขนาดของ (บัฟเฟอร์), stdin);
ถ้า (ส่ง (cliSoc บัฟเฟอร์ strlen (บัฟเฟอร์) 0) <0) {
perror ("ข้อผิดพลาดในการส่งข้อมูล");
ออก (1);
}
// รับการตอบกลับจากเซิร์ฟเวอร์
memset (บัฟเฟอร์, 0, ขนาดของ (บัฟเฟอร์));
if (recv (cliSoc , บัฟเฟอร์, ขนาดของ (บัฟเฟอร์), 0) <0) {
perror ("ข้อผิดพลาดในการรับข้อมูล");
ออก (1);
}
printf ("ไคลเอนต์ %d - การตอบสนองของเซิร์ฟเวอร์:%s\n", getpid (), บัฟเฟอร์);
// ปิดซ็อกเก็ตไคลเอนต์
ปิด (cliSoc );
กลับ 0;
เอาต์พุต: ป>
**การรวบรวมโปรแกรมเซิฟเวอร์**
$ gcc ser.c -o เซอร์
$ ./เซอร์
สร้างซ็อกเก็ตเซิร์ฟเวอร์แล้ว
กำลังฟังการเชื่อมต่อ...
สร้างซ็อกเก็ตเซิร์ฟเวอร์แล้ว
กำลังฟังการเชื่อมต่อ...
ยอมรับการเชื่อมต่อจากไคลเอนต์ 1:127.0.0.1:59074
ลูกค้าทั้งหมดที่เชื่อมต่อ:1
รับข้อมูลจากลูกค้า 1:hii admin
ยอมรับการเชื่อมต่อจากไคลเอนต์ 2:127.0.0.1:40192
ลูกค้าทั้งหมดที่เชื่อมต่อ:2
รับข้อมูลจากลูกค้า 2:สวัสดีทุกคน
**การรวบรวมโปรแกรมไคลเอนต์ 1**
$ gcc cel.c -o เซล
$ ./cel
สร้างซ็อกเก็ตไคลเอ็นต์ 4007 แล้ว
เชื่อมต่อกับเซิร์ฟเวอร์แล้ว
ลูกค้า 4007 - ป้อนข้อความ:hii admin
**การรวบรวมโปรแกรมไคลเอนต์ 2**
$ gcc cel.c -o เซล
$ ./cel
สร้างซ็อกเก็ตไคลเอ็นต์ 4024 แล้ว
เชื่อมต่อกับเซิร์ฟเวอร์แล้ว
ลูกค้า 4024 - ป้อนข้อความ:สวัสดีทุกคน
คำอธิบาย: ป>
ในตัวอย่างการเขียนโปรแกรมนี้ เราได้อธิบายการใช้งานเซิร์ฟเวอร์ซ็อกเก็ตที่มีการประมวลผลหลายตัวด้วยทางแยกในภาษา C ที่นี่ในโปรแกรมฝั่งเซิร์ฟเวอร์ เราสร้างซ็อกเก็ตเซิร์ฟเวอร์ ผูกเข้ากับที่อยู่และพอร์ตเฉพาะ และรับฟังการเชื่อมต่อขาเข้า เมื่อไคลเอนต์เชื่อมต่อ กระบวนการลูกจะถูกสร้างขึ้นโดยใช้ “fork()” ช่วยให้สามารถจัดการไคลเอนต์หลายตัวพร้อมกันได้ กระบวนการลูกได้รับข้อความจากไคลเอนต์และแสดงข้อมูลด้วย ID ของลูกค้า เซิร์ฟเวอร์ซ็อกเก็ตที่มีการประมวลผลหลายตัวนี้ช่วยให้เราสามารถสื่อสารกับไคลเอนต์จำนวน "n" ได้พร้อมกัน
บทสรุป
เราได้พูดคุยกันเกี่ยวกับการใช้งานเซิร์ฟเวอร์ซ็อกเก็ตการประมวลผลหลายตัวด้วย fork ใน C การใช้การเรียกระบบ fork ช่วยให้เราสามารถจัดการการเชื่อมต่อไคลเอนต์หลายตัวพร้อมกันได้ ช่วยให้สามารถสื่อสารพร้อมกันกับลูกค้าหลายรายและจัดการคำขอของลูกค้าได้อย่างมีประสิทธิภาพ
เกี่ยวกับผู้เขียน
บัมเด็บ โกช
Bamdeb Ghosh มีประสบการณ์ตรงในโดเมนเครือข่ายไร้สาย เขาเป็นผู้เชี่ยวชาญในการวิเคราะห์การจับ Wireshark บนเครือข่ายไร้สายหรือแบบมีสาย พร้อมด้วยความรู้เกี่ยวกับ Android, Bluetooth, คำสั่ง Linux และ Python ติดตามเว็บไซต์ของเขา:wifisharks.com