Thứ Tư, 20 tháng 3, 2013

Vấn đề về ghép và tách kênh

Trong phần này chúng ta sẽ thảo luận về vấn đề ghép kênh và tách kênh tại lớp truyền tải. Đó là một dịch vụ vận chuyển mở rộng host to host được cung cấp bởi network layer đến dịch vụ vận chuyển host to host của các ứng dụng chạy trên các hosts. Để giữ các vấn đề thảo luận đạt mức cụ thể, chúng ta sẽ thảo luận về các dịch vụ cơ bản của lớp truyền tải trong môi trương Internet. Chúng tôi nhấn mạnh rằng, dịch vụ ghép và tách kênh là cần thiết cho tất cả các kiểu mạng máy tính.
Ở host đích, lớp truyền tải nhận các segments từ lớp mạng phía dưới. Lớp vận tải có nhiệm vụ vận chuyển dữ liệu trong các segments đến các process ứng dụng thích hợp đang chạy trên host. Nào hãy cùng nhìn vào một ví dụ. Giả sử bạn đang ngồi trước máy tính và download Web pages trong khi đang chạy một phiên FTP và hai phiên Telnet. Do đó bạn có 4 processes ứng dụng đang chạy trên máy của mình- 2 processes Telnet, 1 process FTP và 1 process Http. Trong khi lớp truyền tải trên máy tính của bạn nhận dữ liệu từ lớp mạng bên dưới nó cần định hướng dữ liệu của bạn đến một trong 4 ứng dụng. Nào hãy cùng nhau phân tích làm sao để nó làm được điều này.
Chúng ta biết rằng mỗi process có thể có một hoặc nhiều sockets, những cái cửa mà dữ liệu từ process đi qua rồi tới lớp mạng. Lớp transport tại host nhận sẽ không thực sự vận chuyển dữ liệu trực tiếp đến các process, thay vào đó nó chuyển đến các socket trung gian. Bởi vì trong một khoảng thời gian cho trước có thể có nhiều hơn một socket tại host nhận, mỗi socket sẽ có một số định danh duy nhất. Định dạng của các định danh (identifier) phụ thuộc vào socket đó là UDP hay TCP socket.
Nào hãy cùng suy ngẫm thử xem làm thế nào để các host nhận có thể định hướng trực tiếp các segments tới (incoming segments) đến socket thích hợp. Mỗi transport-layer segment có một tập hợp các trường trong segment để làm nhiệm vụ này. ở host nhận, transport layer sẽ thực hiện việc phân tích các segment để nhận dạng được các socket đích và chuyển segment tới socket đó. Công việc của việc vận chuyển dữ liệu trong transport layer segment đến đúng socket cần nhận được gọi là tách kênh. Công việc thu gôm dữ liệu tại host nguồn từ các nguồn socket khác nhau và đóng gói mỗi data chunk với thông tin header(được sử dụng khi tách kênh) để tạo các segments và chuyển tiếp các segments đên lớp mạng được gọi là ghép kênh. Lớp truyền tải sở dĩ tách kênh các segments đến các process thích hợp là do việc direct các dữ liệu trong segment đến  (arriving segment's data ) đên các sockets thích hợp. Những host trung gian còn phải thu thập các dữ liệu ra từ các sockets, form các transport layer segment, và chuyển các segments đi xuống lớp mạng. Mặc dù được giới thiệu ghép kênh và tách kênh trong môi trường Internet, điều quan trọng là bạn nhận ra rằng chúng (ghép kênh và tách kênh) liên quan đến hầu hết giao thức nào là duy nhất đặt tại một layer (ví dụ như transport layer) được sử dụng bởi nhiều giao thức lớp trên.

Để hiểu về công việc tách kênh, ta nhắc lại về khái niệm tương tự : hộ gia đình. Mỗi đứa trẻ được nhận dạng bởi tên của cậu bé hay cô bé đó. Khi Bill nhận được một bó các mails từ mail carrier, anh ấy thực hiện công việc ''tách kênh'' thông qua việc quan xét xem ai được đánh địa chỉ trong bức thư và sau đó chuyển thư đến cho chị  hay anh của anh ấy. Ann thực hiện việc ghép kênh khi cô ấy thu các mail từ chị và anh của cô ấy và gửi cho mail person.

Nào bây giờ chúng ta đã hiểu về việc ghép kênh và tách kênh tại lớp truyền tải, chúng ta hãy cùng phân tích làm thế nào chúng được hoàn thành trong host. Chúng ta biết răng transport-layer multiplexing yêu cầu các sockets có các định danh duy nhất (1). và mỗi segment có những trường đặc biệt để chỉ ra cho socket biết segments nào được vận chuyển. Các trường đặc biết đó là source port number field destination port number field  (đối với từng trường hợp TCP và UDP sẽ có những trường khác nhau). Mỗi chỉ số port là một số 16 bit chạy từ 0 đến 65535, các ports từ 0 - 1023 được gọi là các well-known port numbers và được hạn chế sử dụng, có nghĩa là các port này được sử dụng cho các ứng dụng well-known như là  HTTP(80), FTP(21). Danh sách các ports nổi tiếng bạn có thể tham khảo trong RFC 1700 và được cập nhật trong RFC 3232. Khi chúng ta phát triển một ứng dụng chúng ta phải gán port ứng dụng.
Bây giờ rõ ràng bạn nên biết: Làm thế nào để transport layer có thể triển khai một ứng dụng tách kênh: Mỗi socket trong host có thể được gắn một port number, và khi segment đi tới một host, transport layer sẽ phân tích địa chỉ port đích trong segment và direct segment đó đên socket tương ứng. Dữ liệu của segment có thể băng qua socket để tìm tới process được dán vào socket đó. Như ta có thể thấy đó là cách UDP làm, riêng đối với TCP việc ghép tách kênh mang màu sắc tinh tế hơn.

Connectionless Multiplexing and Demultiplexing

Nhắc lại trong chương trước, một chương trình Java chạy trên host có thể tạo một UDP socket với dòng dưới đây:
                 DatagramSocket mySocket  = new DatagramSocket();
Khi một UDP socket được tạo theo cách trên thì thì transport layer tự động gán một port  number đến socket. Cụ thể hơn, transport layer sẽ gắn các port từ 1024  đến 65535 đến socket với một chú ý nhỏ rằng port được gán hiện không được sử dụng bởi socket nào khác trên host. Một sự thay thế, Java có thể tạo một UDP socket theo cách sau đây:
                 DatagramSocket mySocket = new DatagramSocket(19157);
Trong trường hợp này ứng dụng gán một port được chỉ định, 19157 đến UDP socket. Nếu người dụng viết code để triển khai một ứng dụng sử dụng "well-known protocol" khi đó người viết ứng dụng phải gán một giá well-known port number tương ứng. Về phía client các port sẽ tự động được gán trong khi tại phía server các port được chỉ định.
Với các port numbers được gán đến UDP sockets ta có thể mô tả chính xác định quá trinh UDP Multiplexing/ Demultiplexing. Giả sử process trong host A với UDP port number là 19157 muốn gửi một khối dữ liệu ứng dụng tới process với UDP port number là 46428 tại host B. Transport layer trong host A sẽ tạo một transport layer segment chứa dữ liệu của ứng dụng (application data), source port 19157 và destination port 46428 và 2 giá trị khác (sẽ được thảo luận sau). transport layer sau đó chuyển segment kết quả (the result segment) đến network layer. network layer sau đó đóng gói (encapsulate) segment trong IP datagram và tạo ra những điều kiện tốt nhất để vận chuyển segment tới host nhận. Nếu segment đến tại host nhận B, transport layer trong host nhận sẽ kiểm tra destination port number trong segment(46428) và vận chuyển segment đến socket của nó nhận dạng bởi port 46428. Chú ý rằng tại host B có thể chạy nhiều process với mỗi process sẽ có UDP socket cũng như port number tương ứng của riêng nó. Như đã biết khi các UDP segments đến từ mạng, host B sẽ direct (demultiplexing) mỗi segment đến nhưng socket tương xứng với nó thông qua việc kiểm tra destination port number.

Một điều quan trọng cần ghi chú đó là UDP socket hoàn toàn được định danh bởi một bộ destionation IP address và destination port number. Kết quả cho thấy, nếu 2 UDP segments có source IP address và/ hoặc source port number nhưng có chung destination IP address và destionation port number khi đó 2 segments sẽ được directed đến cùng một destionation process qua cùng một destination socket.

Chúng ta có thể tự hỏi ? Mục đích của source port number để làm gì ? Ví dụ trong A-to-B segment (segment gửi từ A đến B) source port number phục vụ như là một "return address"- Khi B muốn gửi segment ngược lại cho A, destination port trong B-to-A segment sẽ là source port number trong A-to-B segment (Địa chỉ đầy đủ trả về bao gồm địa chỉ IP nguồn của A và source port number). Trong UDPServer.java, server sử dụng một phương thức để extract source port number trong segment nó nhận được từ phía client, với source port number vừa extract được ở trên sẽ được sử dụng làm destination port number trong segment kế tiếp.

Connection-Oriented Multiplexing and Demultiplexing

Để hiểu về TCP demultiplexing , chúng ta cần quan sát kĩ TCP socket và TCP connection establishment (thiết lập kết nối TCP) . Một sự khác biệt tinh tế giữa TCP socket và UDP socket đó là TCP socket được định dạng bởi bộ bốn (four-tuple): (source IP address, source port number, destination IP address, destination port number). Do vậy, khi TCP segment đi từ network đến host, host sử dụng cả thẩy 4 giá trị để direct (demultiplex) segment đến socket thích hợp. Cụ thể hơn, trái ngược với UDP, 2 segments đến với địa IP source khác nhau hoặc source port numbers sẽ (với ngoại lệ là các TCP segment mang yêu cầu thiết lập kết nối ban đầu ( the original connection-establishment request) ). Được direct đến hai sockets khác nhau. Để có được cái nhìn cụ thể hơn. Hãy cùng suy ngẫm về TCP client-server programming
- TCP server application có một "welcoming socket " , những gì chờ đợi các connection-establishment requests từ phía TCP clients  trên một port number, giả sử là 6789
- TCP client sẽ sinh ra một segment thiết lập kết nối (connection-establishment segment) với dòng sau
Socket clientSocket = new Socket ("serverHostName", 6789);

-Một request thiết lập kết nối đơn thuần chỉ là một TCP segment với destination port number 6789 và một bit đặc biệt trong TCP header phục vụ cho việc thiết lập kết nối. Segment còn bao gồm cả source port number, những gì được chọn bởi client. Dòng phía trên tạo một TCP socket cho client process, thông qua đó những data có thể được enter và rời khỏi client process.

- Khi hệ điều hành của host chạy server process nhận được một yêu cầu kết nối đến (incoming-connection request ) với destination port là 6789, nó xác định server process đang đợi để chấp nhận kết nối trên port 6789. Server process sau đó tạo ra một new socket:
Socket connectionSocket = welcomeSocket.accept()

- transport layer tại server ghi chú 4 giá trị trong connection-request segment: (1) source port number trong segment, (2) địa chỉ IP của host nguồn, (3) destination port number trong segment, (4) địa chỉ IP của chính nó. socket mới được tạo ra được nhận dạng bởi 4 giá trị trên. Tất cả các segments sau đó nếu match tất cả 4 giá trị trên sẽ được demultiplexed đên socket đó. Với TCP connection như trên, client và server có thể gửi dữ liệu cho nhau.

Server host có thể support nhiều TCP sockets đồng thời, với mỗi socket được gắn với một process, và mỗi socket được nhận dạng bởi four-tuple nêu trên. Khi một TCP segment đến host tất cả 4 trường (source IP address, source port, destination port number, destionation IP address) được sử dụng để direct  (demultiplex) segment đến socket thích hợp.

Web Servers and TCP

Trước khi kết thúc bài thảo luận, thật hữu ích khi chúng ta nói một chút về Web servers và chúng sử dụng các port numbers như thế nào ?. Suy ngẫm, một host đang running một Web server, ví dụ như Apache web server, trên cổng 80. Khi clients (ví dụ như browsers) gửi các segments đến server, tất cả segments sẽ có destination port 80. Cụ thê hơn, cả các segments khởi động kết nối (initial connection-establishment segments) và các segments mang các HTTP request messages sẽ có destination port 80. Như đã mô tả trên, server sẽ phân biệt các clients khác nhau bằng cách sử dụng source IP address và source port numbers.
Web server sẽ sinh ra một new process cho mỗi kết nối, mỗi trong processes có connection socket riêng của nó, những gì HTTP requests đi tới và HTTP responses được gửi đi. Tuy nhiên không hẳn chỉ tồn tại một sự tương ứng one-to-one giữa connection sockets và processes. Các high performing Web servers ngày nay thường chỉ sử dụng một process và tạo một new thread với new connection socket cho mỗi client connection (thread có thể được nhìn nhận như một tiến trình con gọn nhẹ). Đối với server như trên, tại một thời gian cho trước có nhiều connection sockets (với các định danh (identifiers) khác nhau) gắn vào cùng một process.

Nếu client và server đang sử dụng sử dụng persistent HTTP(HTTP lâu dài), sau đó trong suốt quá trình của persistent connection nếu client và server trao đổi các HTTP messages thông qua cùng một server socket. Tuy nhiên, nếu client và server sử dụng non-persistent socket, một new TCP connection sẽ được tạo và đóng đối với mỗi request/response và hiển nhiên đi kèm nó là mỗi new socket connection được tạo cho mỗi request/response. Việc thường xuyên tạo và đóng các sockets có thể ảnh hưởng đến performance của các busy Web server (mặc dù cũng có những mẹo về hệ điều hành có thể giúp giảm thiểu điều này )

Không có nhận xét nào:

Đăng nhận xét