Điều khiển luồng

Một phần của tài liệu Bài giảng mạng máy tính ths nguyễn xuân anh (Trang 112 - 114)

Khi kết nối TCP nhận được các đoạn dữ liệu, nó sẽ đặt chúng vào một vùng nhớ tạm thời gọi là đệm nhận. Một tiến trình tương ứng của tầng ứng dụng sẽ đọc dữ liệu từ bộ đệm này, sau khi đọc xong thì phải giải phóng bộ đệm để dành cho các đoạn tin kế tiếp. Vì một lý do nào đó, tiến trình đọc chưa đọc kịp dữ liệu trong bộ đệm, khi đó sẽ xảy ra tình trạng tràn bộ đệm. Để giải quyết vấn đề này, TCP cung cấp dịch vụ kiểm soát lưu lượng (flow control), thực chất đó là quá trình làm tương thích về tốc độ gửi/nhận.

Để kiểm soát lưu lượng, TCP bên gửi sử dụng biến receive window. Đây là giá trị mà bên nhận báo cho bên gửi biết độ lớn vùng đệm còn rỗi của nó. Trong kết nối hai hướng, ở mỗi phía kết nối có giá trị receive window phân biệt. Giá trị receive window động, có nghĩa là nó sẽ thay đổi trong thời gian kết nối. Giả sử máy A gửi một tập tin đếni máy B qua kết nối TCP. Máy B sẽ khởi tạo bộ đệm cho kết nối này với độ lớn RcvBuffer. Tiến trình ứng dụng trên B đọc dữ liệu tớ bộ đệm.

Hình 6.5 Cửa số và bộ đệm nhận Giả thiết:

LastByteread = số thứ tự của byte cuối cùng trong dòng dữ liệu mà tiến trình ứng dựng trong máy B đọc từ buffer

LastByteRcvd = số byte cuối cùng trong dòng dữ liệu đến từ mạng và được để trong receive buffer của máy B

Vì TCP không được phép tràn bộ đệm nên chúng ta phải có: LastByteRcvd - LastByteread < RcvBuffer

Receive window là giá trị RcvWindow, là độ lớn vùng đệm rỗi: RcvWindow = RcvBuffer - [LastByteRcvd - LastByteread]

Vì độ lớn vùng đệm rỗi thay đổi theo thời gian nên giá trị RcvWindow động. kết nối sử dụng biến RcvWindow để cung cấp dịch vụ kiểm soát lưu lượng như thế nào? máy B báo cho máy A độ lớn vùng rỗi mà nó có trong bộ đệm là bao nhiêu bằng cách đặt giá trị RcvWindow hiện thời vào trong trường window của tất cả các segment gửi từ A. Ban đầu máy B thiết lập RcvWindow RcvBuffer. Rõ ràng để đạt được điều này thì máy B phải kiểm soát vài biến kết nối.

Máy A cũng có hai biến LastByteSent và LastByteAcked. Độ lệch giữa hai biến này, LastByteSent - LastByteAcked là số lượng dữ liệu chưa được biên nhận mà A gửi qua kết nối. Bằng cách khống chế số lượng dữ liệu chưa được biên nhận nhỏ hơn giá trị RcvWindow, A đảm bảo không làm tràn bộ đệm tại B. Do vậy trong suốt thời gian kết nối, A phải đảm bảo:

LastByteSent - LastByteAcked <= RcvWindow

Một vấn đề kỹ thuật nhỏ nẩy sinh ở đây. Giả sử bộ đệm ở máy B đầy, có nghĩa là RcvWindow = 0. Sau khi thông báo tới máy A là RcvWindow = 0, máy B không có gì để gởi tới máy A. Khi tiến trình ứng dụng ở máy B lấy dữ liệu lên

làm cho bộ đệm rỗng thì TCP không gửi đoạn tin mới cùng với giá trị RcvWindow mới tới máy A - TCP chỉ gửi đoạn tin tới A khi có dữ liệu hoặc ACK để gửi. Bởi vậy máy A sẽ không bao giờ được thông báo đã có thêm khoảng trống trong bộ đệm ở B. Máy A bị “khoá” và không truyền thêm dữ liệu. Để giải quyết vấn đề này, đặc tả TCP yêu cầu máy A tiếp tục gửi đoạn tin với một byte dữ liệu khi receive window của máy B bằng 0. Những đoạn tin này sẽ được B biên nhận. Khi bộ đệm bắt đầu có vùng rỗng thì trong gói biên nhận sẽ có cả giá trị khác không của RcvWindow.

Khác với TCP, giao thức UDP không có cơ chế kiểm soát lưu lượng. UDP đặt các datagram vào trong một hàng đợi có độ lớn hữu hạn ứng với socket nào. Tiến trình đọc lần lượt từng datagram trong hàng đợi. Nếu tốc độ đọc của tiến trình không đủ nhanh thì hàng đợi sẽ tràn và các datagram đến sau sẽ bị mất.

Một phần của tài liệu Bài giảng mạng máy tính ths nguyễn xuân anh (Trang 112 - 114)