2011-11-13 28 views
7

tôi không thể có ý nghĩa như thế nào và tại sao các phân đoạn mã sau đây làm việc:Ảnh hưởng của SO_SNDBUF

/* Now lets try to set the send buffer size to 5000 bytes */ 
    size = 5000; 
    err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int)); 
    if (err != 0) { 
     printf("Unable to set send buffer size, continuing with default size\n"); 
    } 

Nếu chúng ta kiểm tra giá trị của send đệm, nó thực sự là một cách chính xác thiết lập để 5000 * 2 = 10000 Tuy nhiên, nếu chúng tôi cố gắng gửi nhiều hơn kích thước bộ đệm gửi, nó sẽ gửi tất cả. Ví dụ:

n = send(sockfd, buf, 30000, 0); 

    /* Lets check how much us actually sent */ 
    printf("No. of bytes sent is %d\n", n); 

này in ra 30000.

Làm thế nào chính xác đã làm công việc này? Không thực tế là kích thước bộ đệm gửi được giới hạn đến 10000 có hiệu lực không? Nếu có, chính xác thì chuyện gì đã xảy ra? Một số loại phân mảnh?

CẬP NHẬT: Điều gì sẽ xảy ra nếu ổ cắm ở chế độ không chặn? Tôi thử như sau: kích thước bộ đệm

  1. Thay đổi 10000 (5000 * 2) gây 16384 byte được gửi
  2. Thay đổi kích thước bộ đệm để 20000 (10000 * 2) gây 30000 byte được gửi

Một lần nữa, tại sao?

Trả lời

11

Tác dụng của cài đặt SO_SNDBUF tùy chọn khác với TCP và UDP.

  • Đối với UDP này đặt giới hạn về kích thước của datagram, ví dụ: bất cứ điều gì lớn hơn sẽ bị loại bỏ.
  • Đối với TCP, điều này chỉ đặt kích thước bộ đệm trong hạt nhân cho ổ cắm đã cho (với một số làm tròn đến ranh giới trang và với giới hạn trên).

Kể từ khi nó trông giống như bạn đang nói về TCP, hiệu ứng bạn đang quan sát được giải thích bởi các ổ cắm được ở chế độ, vì vậy send(2) khối cho đến khi hạt nhân có thể chấp nhận tất cả các dữ liệu của bạn, và/hoặc mạng chặn ngăn xếp không đồng bộ dữ liệu de-xếp hàng và đẩy nó vào card mạng, do đó giải phóng không gian trong bộ đệm.

Ngoài ra, TCP là giao thức luồng , nó không giữ lại bất kỳ cấu trúc "thư" nào. Một send(2) có thể tương ứng với nhiều recv(2) s ở phía bên kia và ngược lại. Hãy coi nó là luồng byte.

+0

và điều gì xảy ra nếu ổ cắm ở chế độ không chặn? Tôi đã thử như sau: 1) Thay đổi kích thước bộ đệm thành 10000 khiến 16384 byte được gửi 2) Thay đổi kích thước bộ đệm thành 20000 khiến 30000 byte được gửi Một lần nữa, tại sao? – Arun

+0

@Arun: đó chỉ là làm tròn .. tại sao điều đó lại quan trọng? bạn không nên dựa vào thực tế là bộ đệm là * chính xác * n byte. hạt nhân có thể phân bổ nhiều hơn. –

+1

Đầu tiên, hạt nhân không lấy kích thước bộ đệm của bạn như là, như @yi_H chỉ ra. Sau đó, ngăn xếp mạng hoạt động * không đồng bộ * liên quan đến quá trình của bạn. Hãy thử các bước sau - bắt đầu ghi vào ổ cắm, nhưng * không đọc ở kích thước khác *.Cuối cùng bạn sẽ nhận được một đoạn ngắn (kernel chấp nhận ít byte hơn sau đó bạn cung cấp cho nó) hoặc viết không thành công. –

4

SO_SNDBUF định cấu hình bộ đệm mà triển khai socket sử dụng trong nội bộ. Nếu ổ cắm của bạn không bị chặn, bạn chỉ có thể gửi đến kích thước đã được cấu hình, nếu ổ cắm của bạn đang chặn không có giới hạn cho cuộc gọi của bạn.

Các vấn đề liên quan