ประสิทธิภาพการทำงานช้าเกิดขึ้นเมื่อคุณคัดลอกข้อมูลไปยังเซิร์ฟเวอร์ TCP โดยใช้โปรแกรม Windows Sockets API

การแปลบทความ การแปลบทความ
หมายเลขบทความ (Article ID): 823764 - ผลิตภัณฑ์ที่เกี่ยวข้องในบทความนี้
ขยายทั้งหมด | ยุบทั้งหมด

เนื้อหาบนหน้านี้

อาการ

เมื่อคุณเรียกใช้โปรแกรมที่ใช้ API ของ Windows Sockets คุณอาจพบประสิทธิภาพการทำงานช้าลงเมื่อคุณคัดลอกข้อมูลไปยังเซิร์ฟเวอร์ TCP

ถ้าคุณทำการตรวจสอบเครือข่าย ด้วยการ sniffer เครือข่ายเช่นการตรวจสอบเครือข่ายของ Microsoft เซิร์ฟเวอร์ TCP ส่งแบบ TCP ACK เซ็กเมนต์สุดท้ายเซ็กเมนต์ TCP ในสตรีมข้อมูล TCP ในตัวจับเวลาตอบรับที่ล่าช้า (เรียกอีกอย่างว่าการล่าช้า ACK เมอร์) โดยค่าเริ่มต้น สำหรับระบบปฏิบัติการ Windows ค่าตัวจับเวลานี้คือ 200 มิลลิวินาที (ms) เป็นกระแสข้อมูลโดยทั่วไปสำหรับการส่งข้อมูล 64 กิโลไบต์ (KB) มีลักษณะคล้ายคลึงกับลำดับต่อไปนี้:
Client->Server 1460 bytes
Client->Server 1460 bytes
Server->Client ACK
Client->Server 1460 bytes
Client->Server 1460 bytes
Server->Client ACK
....
Client->Server 1460 bytes
Client->Server 1460 bytes
Server->Client ACK-PUSH
Client->Server 1296 bytes
-> delayed ACK 200 ms


สาเหตุ

ปัญหานี้เกิดขึ้นเนื่องจากลักษณะการทำงานของ Windows Sockets API และ Afd.sys architectural ปัญหานี้เกิดขึ้นหากเงื่อนไขต่อไปนี้ทั้งหมดเป็นจริง:
  • โปรแกรม Windows Sockets ใช้บล็อกที่ไม่ใช่ซ็อกเก็ต
  • เดียว ส่ง เรียกใช้ หรือ WSASend การเรียกข้อมูลส่งบัฟเฟอร์ของซ็อกเก็ตทั้งหมดที่อยู่ภายใต้

    ตัวอย่างเช่น โปรแกรมใช้ Windows Sockets ระดับ ฟังก์ชันการเปลี่ยนซ็อกเก็ตเริ่มต้นส่งบัฟเฟอร์ไปยัง 32 กิโลระหว่างซ็อกเก็ตของงานประจำในการเตรียมใช้งาน:
    setsockopt( sock, SOL_SOCKET, 32768, (char *) &val, sizeof( int ) );
    ในภายหลัง เมื่อโปรแกรมส่งข้อมูล โปรแกรมออกแบบ ส่ง เรียก หรือยัง WSASend การเรียกและส่ง 64 กิโลไบต์ของข้อมูลแต่ละรายการในระหว่างส่ง:
    send(socket, pWrBuffer, 65536, 0);
    ในสถานการณ์นี้ แต่ละครั้งคือปัญหาของโปรแกรม ส่ง การเรียก 64 กิโลไบต์ของข้อมูล การส่งคืนโปรแกรม SOCKET_ERROR รหัสข้อผิดพลาดถ้าบัฟเฟอร์ซ็อกเก็ต-32 กิโลไบต์ที่อยู่ภายใต้ทั้งหมดถูกกรอกข้อมูล หลังจากนั้นเรียกตัว WSAGetLastError ฟังก์ชัน การได้รับโปรแกรม WSAEWOULDBLOCK รหัสข้อผิดพลาด โปรแกรมส่วนใหญ่ใช้ Windows Sockets เลือก ฟังก์ชันการตรวจสอบสถานะของซ็อกเก็ต ในสถานการณ์นี้ เลือก ฟังก์ชันรายงานซ็อกเก็ตเป็นแบบเขียนได้จนกว่าไคลเอ็นต์ได้รับการเซ็กเมนต์ TCP ACK คงค้าง โดยค่าเริ่มต้นในสภาพแวดล้อม Windows ซึ่งอาจใช้เวลานานเป็น 200 ms เนื่องจาก มีอัลกอริทึมการรับรองล่าช้า
  • เซิร์ฟเวอร์ระยะไกล TCP ยอมรับเกี่ยวกับเซ็กเมนต์ TCP ทั้งหมดก่อนที่ไคลเอนต์ส่งการเซ็กเมนต์ TCP ล่าสุด มีการตั้งค่าบิตผลักดัน

การหลีกเลี่ยงปัญหา

เมื่อต้องการหลีกเลี่ยงปัญหานี้ ใช้ใดก็ได้ในวิธีต่อไปนี้

วิธีที่ 1: ใช้ซ็อกเก็ตที่บล็อก

ปัญหานี้เกิดขึ้นกับบล็อกที่ไม่ใช่ซ็อกเก็ตเท่านั้น เมื่อคุณใช้ซ็อกเก็ตการบล็อค ปัญหานี้ไม่เกิดขึ้นเนื่องจาก Afd.sys จัดการบัฟเฟอร์ซ็อกเก็ตที่แตกต่างออกไป สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการบล็อค และการ บล็อกที่ไม่ใช่ซ็อกเก็ตที่เขียนโปรแกรม ดูเอกสารประกอบ SDK แพลตฟอร์มของ Microsoft

วิธีที่ 2: ทำให้ขนาดของบัฟเฟอร์ส่งซ็อกเก็ตใหญ่กว่าขนาดของบัฟเฟอร์ส่งโปรแกรม

เมื่อต้องการปรับเปลี่ยนบัฟเฟอร์ซ็อกเก็ตส่ง ใช้ฟังก์ชันgetsockopt Windows Sockets เพื่อกำหนดซ็อกเก็ตขนาดบัฟเฟอร์ส่ง (SO_SNDBUF) ปัจจุบัน และจากนั้น ให้ใช้ระดับฟังก์ชันการตั้งค่าการซ็อกเก็ตส่งขนาดบัฟเฟอร์ เมื่อเสร็จเรียบร้อยแล้ว ค่า SO_SNDBUF ต้องมีขนาดใหญ่กว่าขนาดของบัฟเฟอร์ส่งโปรแกรมอย่างน้อย 1 ไบต์

การโทรส่งการปรับเปลี่ยน หรือการเรียกWSASendเพื่อระบุบัฟเฟอร์ขนาดเล็กกว่าค่า SO_SNDBUF น้อย 1 ไบต์ ในตัวก่อนหน้าอย่างในส่วน "สาเหตุ" ของบทความนี้ คุณไม่สามารถปรับเปลี่ยนเรียกระดับเพื่อใช้ค่าต่อไปนี้
setsockopt( sock, SOL_SOCKET, 65537, (char *) &val, sizeof( int ) );
หรือคุณไม่สามารถปรับเปลี่ยนการเรียกที่ส่งไปยังค่าต่อไปนี้:
send(socket, pWrBuffer, 32767, 0);
นอกจากนี้คุณสามารถใช้การรวมกันของค่าเหล่านี้

วิธีที่ 3: ปรับเปลี่ยนการตั้งค่า TCP/IP บนเซิร์ฟเวอร์ TCP

สิ่งสำคัญ ส่วน วิธีการ หรืองานนี้ประกอบด้วยขั้นตอนที่บอกให้คุณทราบวิธีการปรับเปลี่ยนรีจิสทรี อย่างไรก็ตาม ปัญหาร้ายแรงอาจเกิดขึ้นหากคุณปรับเปลี่ยนรีจิสทรีอย่างไม่ถูกต้อง ดังนั้น ตรวจสอบให้แน่ใจว่า คุณทำตามขั้นตอนเหล่านี้อย่างระมัดระวัง สำหรับการป้องกันเพิ่มเติม ให้สำรองข้อมูลรีจิสทรีก่อนที่คุณจะปรับเปลี่ยน จากนั้นคุณจะสามารถคืนค่ารีจิสทรีได้หากเกิดปัญหา สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการสำรอง และคืนค่ารีจิสทรี คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:
322756 วิธีการสำรอง และคืนค่ารีจิสทรีใน Windows


ปรับเปลี่ยนการตั้งค่า TCP/IP บนเซิร์ฟเวอร์ TCP เพื่อยอมรับการเซ็กเมนต์ TCP ขาเข้าทันที วิธีแก้ปัญหานี้ได้ผลดีที่สุดในสภาพแวดล้อมที่มีการติดตั้งไคลเอ็นต์ขนาดใหญ่แบบพื้นฐาน และที่คุณไม่สามารถเปลี่ยนลักษณะการทำงานของโปรแกรม สำหรับสถานการณ์สมมติที่ใช้อยู่ TCP เซิร์ฟเวอร์ระยะไกลบนเซิร์ฟเวอร์ที่ใช้ Windows คุณต้องปรับเปลี่ยนรีจิสทรีของเซิร์ฟเวอร์ระยะไกล สำหรับระบบปฏิบัติการอื่น ๆ ดูเอกสารประกอบของระบบปฏิบัติการสำหรับข้อมูลเกี่ยวกับวิธีการเปลี่ยนตัวจับเวลาตอบรับล่าช้า

บนเซิร์ฟเวอร์ที่รัน Windows 2000 ให้ทำตามขั้นตอนเหล่านี้:
  1. เริ่มตัวแก้ไขรีจิสทรี (Regedit.exe)
  2. ค้นหาและคลิกที่คีย์ย่อยของรีจิสทรีต่อไปนี้:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<Interface GUID>
  3. ในการ แก้ไข เมนู คลิก เพิ่มค่าและจากนั้น สร้างค่ารีจิสทรีต่อไปนี้:

    ชื่อของค่า: TcpDelAckTicks
    ชนิดข้อมูล: REG_DWORD
    ข้อมูลค่า: 0
  4. ออกจาก Registry Editor
  5. รีสตาร์ท Windows สำหรับการเปลี่ยนแปลงนี้มีผลบังคับใช้
บนเซิร์ฟเวอร์ที่รัน Windows XP หรือ Windows Server 2003 ให้ทำตามขั้นตอนเหล่านี้:
  1. เริ่มตัวแก้ไขรีจิสทรี
  2. ค้นหาและคลิกที่คีย์ย่อยของรีจิสทรีต่อไปนี้:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<Interface GUID>
  3. ในการ แก้ไข เมนู ชี้ไปที่ ใหม่แล้ว คลิก ค่า DWORD.
  4. ตั้งชื่อค่าใหม่TcpAckFrequencyและกำหนดค่าเท่ากับ 1
  5. ออกจาก Registry Editor
  6. รีสตาร์ท Windows สำหรับการเปลี่ยนแปลงนี้มีผลบังคับใช้

วิธีที่ 4: ปรับเปลี่ยนพฤติกรรมบัฟเฟอร์ใน Afd.sys สำหรับบล็อกที่ไม่ใช่ซ็อกเก็ต

สิ่งสำคัญ ส่วน วิธีการ หรืองานนี้ประกอบด้วยขั้นตอนที่บอกให้คุณทราบวิธีการปรับเปลี่ยนรีจิสทรี อย่างไรก็ตาม ปัญหาร้ายแรงอาจเกิดขึ้นหากคุณปรับเปลี่ยนรีจิสทรีอย่างไม่ถูกต้อง ดังนั้น ตรวจสอบให้แน่ใจว่า คุณทำตามขั้นตอนเหล่านี้อย่างระมัดระวัง สำหรับการป้องกันเพิ่มเติม ให้สำรองข้อมูลรีจิสทรีก่อนที่คุณจะปรับเปลี่ยน จากนั้นคุณจะสามารถคืนค่ารีจิสทรีได้หากเกิดปัญหา สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการสำรอง และคืนค่ารีจิสทรี คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:
322756 วิธีการสำรอง และคืนค่ารีจิสทรีใน Windows


หมายเหตุ รีจิสทรีคีย์นี้จะพร้อมใช้งานสำหรับ Windows Server 2003 Service Pack 1 การและในเวลาต่อมาเซอร์วิสแพ็คเท่านั้น
  1. คลิก เริ่มชนิด regedit.exeแล้ว คลิก ตกลง.
  2. ค้นหาและคลิกที่คีย์ย่อยของรีจิสทรีต่อไปนี้:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters
  3. ในการ แก้ไข เมนู ชี้ไปที่ ใหม่แล้ว คลิก ค่า DWORD.
  4. ตั้งชื่อค่าใหม่NonBlockingSendSpecialBufferingและกำหนดค่าเท่ากับ 1
  5. ออกจาก Registry Editor
  6. รีสตาร์ท Windows สำหรับการเปลี่ยนแปลงนี้มีผลบังคับใช้

สถานะ

Microsoft ยืนยันว่า ปัญหานี้เป็นปัญหาที่เกิดขึ้นกับผลิตภัณฑ์ของ Microsoft ที่ระบุไว้ในส่วน "นำไปใช้งาน"

ข้อมูลอ้างอิง

328890 รายการรีจิสทรีใหม่สำหรับการควบคุมการทำงาน TCP ยอมรับ (ACK) ใน Windows XP และ ใน Windows Server 2003

คุณสมบัติ

หมายเลขบทความ (Article ID): 823764 - รีวิวครั้งสุดท้าย: 5 มีนาคม 2556 - Revision: 6.0
ใช้กับ
  • Microsoft Windows Server 2003 Enterprise Edition
  • Microsoft Windows Server 2003 Standard Edition
  • Microsoft Windows Server 2003 Web Edition
  • Microsoft Windows XP Home Edition
  • Microsoft Windows XP Professional Edition
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Windows 2000 Server
  • Windows Server 2008 Datacenter without Hyper-V
  • Windows Server 2008 Enterprise without Hyper-V
  • Windows Server 2008 for Itanium-Based Systems
  • Windows Server 2008 Standard without Hyper-V
  • Windows Server 2008 Datacenter
  • Windows Server 2008 Enterprise
  • Windows Server 2008 Standard
  • Windows Web Server 2008
  • Windows Server 2008 R2 Standard
  • Windows Server 2008 R2 Enterprise
  • Windows Server 2008 R2 Datacenter
  • Windows Server 2012 Datacenter
  • Windows Server 2012 Standard
  • Windows 8 Enterprise
  • Windows 8 Pro
  • Windows 7 Professional
  • Windows 7 Enterprise
  • Windows 7 Home Basic
  • Windows 7 Home Premium
Keywords: 
kbprb kbmt KB823764 KbMtth
แปลโดยคอมพิวเตอร์
ข้อมูลสำคัญ: บทความนี้แปลโดยซอฟต์แวร์การแปลด้วยคอมพิวเตอร์ของ Microsoft แทนที่จะเป็นนักแปลที่เป็นบุคคล Microsoft มีบทความที่แปลโดยนักแปลและบทความที่แปลด้วยคอมพิวเตอร์ เพื่อให้คุณสามารถเข้าถึงบทความทั้งหมดในฐานความรู้ของเรา ในภาษาของคุณเอง อย่างไรก็ตาม บทความที่แปลด้วยคอมพิวเตอร์นั้นอาจมีข้อบกพร่อง โดยอาจมีข้อผิดพลาดในคำศัพท์ รูปแบบการใช้ภาษาและไวยากรณ์ เช่นเดียวกับกรณีที่ชาวต่างชาติพูดผิดเมื่อพูดภาษาของคุณ Microsoft ไม่มีส่วนรับผิดชอบต่อความคลาดเคลื่อน ความผิดพลาดหรือความเสียหายที่เกิดจากการแปลเนื้อหาผิดพลาด หรือการใช้บทแปลของลูกค้า และ Microsoft มีการปรับปรุงซอฟต์แวร์การแปลด้วยคอมพิวเตอร์อยู่เป็นประจำ
ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:823764

ให้ข้อเสนอแนะ

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com