34 Matching Annotations
  1. Jul 2023
  2. Apr 2023
  3. Mar 2023
    1. ```js // Adds an entry to the event log on the page, optionally applying a specified // CSS class.

      let currentTransport, streamNumber, currentTransportDatagramWriter;

      // "Connect" button handler. async function connect() { const url = document.getElementById('url').value; try { var transport = new WebTransport(url); addToEventLog('Initiating connection...'); } catch (e) { addToEventLog('Failed to create connection object. ' + e, 'error'); return; }

      try { await transport.ready; addToEventLog('Connection ready.'); } catch (e) { addToEventLog('Connection failed. ' + e, 'error'); return; }

      transport.closed .then(() => { addToEventLog('Connection closed normally.'); }) .catch(() => { addToEventLog('Connection closed abruptly.', 'error'); });

      currentTransport = transport; streamNumber = 1; try { currentTransportDatagramWriter = transport.datagrams.writable.getWriter(); addToEventLog('Datagram writer ready.'); } catch (e) { addToEventLog('Sending datagrams not supported: ' + e, 'error'); return; } readDatagrams(transport); acceptUnidirectionalStreams(transport); document.forms.sending.elements.send.disabled = false; document.getElementById('connect').disabled = true; }

      // "Send data" button handler. async function sendData() { let form = document.forms.sending.elements; let encoder = new TextEncoder('utf-8'); let rawData = sending.data.value; let data = encoder.encode(rawData); let transport = currentTransport; try { switch (form.sendtype.value) { case 'datagram': await currentTransportDatagramWriter.write(data); addToEventLog('Sent datagram: ' + rawData); break; case 'unidi': { let stream = await transport.createUnidirectionalStream(); let writer = stream.getWriter(); await writer.write(data); await writer.close(); addToEventLog('Sent a unidirectional stream with data: ' + rawData); break; } case 'bidi': { let stream = await transport.createBidirectionalStream(); let number = streamNumber++; readFromIncomingStream(stream, number);

          let writer = stream.writable.getWriter();
          await writer.write(data);
          await writer.close();
          addToEventLog(
              'Opened bidirectional stream #' + number +
              ' with data: ' + rawData);
          break;
        }
      }
      

      } catch (e) { addToEventLog('Error while sending data: ' + e, 'error'); } }

      // Reads datagrams from |transport| into the event log until EOF is reached. async function readDatagrams(transport) { try { var reader = transport.datagrams.readable.getReader(); addToEventLog('Datagram reader ready.'); } catch (e) { addToEventLog('Receiving datagrams not supported: ' + e, 'error'); return; } let decoder = new TextDecoder('utf-8'); try { while (true) { const { value, done } = await reader.read(); if (done) { addToEventLog('Done reading datagrams!'); return; } let data = decoder.decode(value); addToEventLog('Datagram received: ' + data); } } catch (e) { addToEventLog('Error while reading datagrams: ' + e, 'error'); } }

      async function acceptUnidirectionalStreams(transport) { let reader = transport.incomingUnidirectionalStreams.getReader(); try { while (true) { const { value, done } = await reader.read(); if (done) { addToEventLog('Done accepting unidirectional streams!'); return; } let stream = value; let number = streamNumber++; addToEventLog('New incoming unidirectional stream #' + number); readFromIncomingStream(stream, number); } } catch (e) { addToEventLog('Error while accepting streams: ' + e, 'error'); } }

      async function readFromIncomingStream(stream, number) { let decoder = new TextDecoderStream('utf-8'); let reader = stream.pipeThrough(decoder).getReader(); try { while (true) { const { value, done } = await reader.read(); if (done) { addToEventLog('Stream #' + number + ' closed'); return; } let data = value; addToEventLog('Received data on stream #' + number + ': ' + data); } } catch (e) { addToEventLog( 'Error while reading from stream #' + number + ': ' + e, 'error'); addToEventLog(' ' + e.message); } }

      function addToEventLog(text, severity = 'info') { let log = document.getElementById('event-log'); let mostRecentEntry = log.lastElementChild; let entry = document.createElement('li'); entry.innerText = text; entry.className = 'log-' + severity; log.appendChild(entry);

      // If the most recent entry in the log was visible, scroll the log to the // newly added element. if (mostRecentEntry != null && mostRecentEntry.getBoundingClientRect().top < log.getBoundingClientRect().bottom) { entry.scrollIntoView(); } } ```

  4. Dec 2022
    1. There is a mistaken assumption often associated withdatagrams, which is that the motivation for datagrams isthe support of a higher level service which is essentiallyequivalent to the datagram. In other words, it hassometimes been suggested that the datagram is providedbecause the transport service which the applicationrequires is a datagram service. In fact, this is seldom thecase. While some applications in the Internet, such assimple queries of date servers or name servers, use anaccess method based on an unreliable datagram, mostservices within the Internet would like a moresophisticated transport model than simple datagram.Some services would like the reliability enhanced, somewould like the delay smoothed and buffered, but almostall have some expectation more complex than adatagram. It is important to understand that the role ofthe datagram in this respect is as a building block, and notas a service in itself.

      Datagram as the fundamental building block

      Is it any wonder then that QUIC—a TCP-like stateful connection—is being engineered using UDP?

  5. Aug 2022
  6. Jul 2022
  7. Jun 2022
  8. Apr 2022
    1. EvoArch suggests an additional reason that IPv4 has been so sta-ble over the last three decades. Recall that a large birth rate atthe layer above the waist can cause a lethal drop in the normalizedvalue of the kernel, if the latter is not chosen as substrate by thenew nodes. In the current Internet architecture, the waist is the net-work layer but the next higher layer (transport) is also very narrowand stable. So, the transport layer acts as an evolutionary shield forIPv4 because any new protocols at the transport layer are unlikelyto survive the competition with TCP and UDP. On the other hand,a large number of births at the layer above TCP or UDP (applica-tion protocols or specific applications) is unlikely to significantlyaffect the value of those two transport protocols because they al-ready have many products. In summary, the stability of the twotransport protocols adds to the stability of IPv4, by eliminating anypotential new transport protocols that could select a new networklayer protocol instead of IPv4.

      Network Layer protected by Transport Layer

      In the case of IPv4 at the network layer, it is protected by the small number of protocols at the Transport Layer. Even the cannibalization of TCP by QUIC, that is still happening at the Transport layer: [QUIC] does this by establishing a number of multiplexed connections between two endpoints using User Datagram Protocol (UDP), and is designed to obsolete TCP at the transport layer for many applications, thus earning the protocol the occasional nickname "TCP/2"..

  9. Nov 2019
  10. Nov 2018