Skip to content

Commit

Permalink
Additionally to disabling the Nagle algorithm, disable delayed ACKs.
Browse files Browse the repository at this point in the history
  • Loading branch information
kpreisser committed Feb 13, 2021
1 parent 2a2b441 commit 3e42041
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
46 changes: 46 additions & 0 deletions SimpleSocketClient/SocketConfigurator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Net.Sockets;

namespace SimpleSocketClient
{
internal static class SocketConfigurator
{
private static readonly byte[] IntOneAsBytes = BitConverter.GetBytes(1);

/// <summary>
/// Disables the Nagle algorithm and delayed ACKs for TCP sockets
/// in order to improve response time.
/// </summary>
/// <param name="socket"></param>
public static void ConfigureSocket(Socket socket)
{
// Disable the Nagle algorithm (so that we don't delay new packets to be sent
// when the remote party didn't ACK our previous packet(s) yet).
socket.NoDelay = true;

// Disable delayed ACK (so that if the remote party uses the Nagle algorithm,
// we can reduce the time it has to wait until it can send us new packets).
DisableTcpDelayedAck(socket);
}

private static void DisableTcpDelayedAck(Socket socket)
{
// See: https://github.com/dotnet/runtime/issues/798 for plans to integrate this
// into a future .NET version.
// Note: On Debian-based Linux OSes, it seems TCP_QUICKACK is already enabled
// by default (according to the man page of socket_quickack(3).
if (socket.ProtocolType == ProtocolType.Tcp && OperatingSystem.IsWindows())
{
try
{
const int SIO_TCP_SET_ACK_FREQUENCY = unchecked((int)0x98000017);
socket.IOControl(SIO_TCP_SET_ACK_FREQUENCY, IntOneAsBytes, Array.Empty<byte>());
}
catch (SocketException)
{
// Ignore; we don't want to fail.
}
}
}
}
}
8 changes: 4 additions & 4 deletions SimpleSocketClient/UiSocketHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,10 @@ private async Task RunTcpReceiveTaskAsync()
{
try
{
using var client = new TcpClient(this.addressFamily)
{
NoDelay = true
};
using var client = new TcpClient(this.addressFamily);

// Disable the Nagle algorithm and delayed ACKs.
SocketConfigurator.ConfigureSocket(client.Client);

await client.ConnectAsync(host!, port, this.ctSource.Token);
Stream clientStream = client.GetStream();
Expand Down

0 comments on commit 3e42041

Please sign in to comment.