-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4d92633
commit 1fafe1b
Showing
8 changed files
with
498 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Tools | ||
|
||
## SocketTester | ||
|
||
A socket testing tool. | ||
|
||
### Usage | ||
|
||
```bash | ||
cd SocketTester | ||
|
||
# send tcp packages | ||
dotnet run -- -t tcp -sp 9999 -cp 9999 -tp 10 -c | ||
|
||
# send udp packages | ||
dotnet run -- -t udp -sp 9999 -cp 9999 -tp 10 -c | ||
``` | ||
|
||
Startup parameters | ||
|
||
```bash | ||
dotnet run -- -h | ||
``` | ||
|
||
| Name | Default Value | Desc | | ||
| ----------------- | ------------- | ---------------------------------------------- | | ||
| --type,-t | tcp | Socket type, value is tcp,udp etc. | | ||
| --server-port,-sp | 9999 | Server listen port | | ||
| --client-port,-cp | 8888 | Client connection port | | ||
| --compressed,-c | false | Enable stream compression | | ||
| --frequency,-f | 1000 | Frequency of sending(ms) | | ||
| --total-packs,-tp | 0 | Maximum number of packets sent. 0 is unlimited | | ||
| --pack-size,-ps | 1024 | Package size | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.CommandLine; | ||
using System.CommandLine.Binding; | ||
|
||
namespace SocketTester; | ||
|
||
internal interface ISocketTester | ||
{ | ||
bool Compressed { get; set; } | ||
int Frequency { get; set; } | ||
int TotalPacks { get; set; } | ||
int PackSize { get; set; } | ||
Task RunServerAsync(int port = 9999); | ||
Task RunClientAsync(int port = 8888, string ip = "127.0.0.1"); | ||
} | ||
|
||
internal class SocketTesterBinder : BinderBase<ISocketTester> | ||
{ | ||
private readonly Option<string> _typeOption; | ||
|
||
public SocketTesterBinder(Option<string> typeOption) | ||
{ | ||
_typeOption = typeOption; | ||
} | ||
|
||
protected override ISocketTester GetBoundValue(BindingContext bindingContext) | ||
{ | ||
var value = bindingContext.ParseResult.GetValueForOption(_typeOption); | ||
return value switch | ||
{ | ||
"tcp" => new TcpTester(), | ||
"udp" => new UdpTester(), | ||
_ => new TcpTester() | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// See https://aka.ms/new-console-template for more information | ||
|
||
using SocketTester; | ||
using System.CommandLine; | ||
|
||
var returnCode = 0; | ||
var rootCommand = new RootCommand("RhoAias Socket Tester."); | ||
|
||
var typeOption = new Option<string>( | ||
name: "--type", | ||
description: "Socket type, value is tcp,udp etc.", | ||
getDefaultValue: () => "tcp"); | ||
typeOption.AddAlias("-t"); | ||
|
||
var serverPortOption = new Option<int>( | ||
name:"--server-port", | ||
description: "Server listen port.", | ||
getDefaultValue: () => 9999); | ||
serverPortOption.AddAlias("-sp"); | ||
|
||
var clientPortOption = new Option<int>( | ||
name: "--client-port", | ||
description: "Client connection port.", | ||
getDefaultValue: () => 8888); | ||
clientPortOption.AddAlias("-cp"); | ||
|
||
var compressedOption = new Option<bool>( | ||
name: "--compressed", | ||
description: "Enable stream compression.", | ||
getDefaultValue: () => false); | ||
compressedOption.AddAlias("-c"); | ||
|
||
var frequencyOption = new Option<int>( | ||
name: "--frequency", | ||
description: "Frequency of sending(ms).", | ||
getDefaultValue: () => 1000); | ||
frequencyOption.AddAlias("-f"); | ||
|
||
var totalPacksOption = new Option<int>( | ||
name: "--total-packs", | ||
description: "Maximum number of packets sent. 0 is unlimited.", | ||
getDefaultValue: () => 0); | ||
totalPacksOption.AddAlias("-tp"); | ||
|
||
var packSizeOption = new Option<int>( | ||
name: "--pack-size", | ||
description: "Package size.", | ||
getDefaultValue: () => 1024); | ||
packSizeOption.AddAlias("-ps"); | ||
|
||
rootCommand.Add(typeOption); | ||
rootCommand.Add(serverPortOption); | ||
rootCommand.Add(clientPortOption); | ||
rootCommand.Add(compressedOption); | ||
rootCommand.Add(frequencyOption); | ||
rootCommand.Add(totalPacksOption); | ||
rootCommand.Add(packSizeOption); | ||
|
||
rootCommand.SetHandler(async (tester, serverPort, clientPort, compressed, frequency, totalPacks, packSize) => | ||
{ | ||
tester.Compressed = compressed; | ||
tester.Frequency = frequency; | ||
tester.TotalPacks = totalPacks; | ||
tester.PackSize = packSize; | ||
|
||
var task1 = tester.RunServerAsync(serverPort); | ||
await Task.Delay(2000); | ||
var task2 = tester.RunClientAsync(clientPort); | ||
await Task.WhenAll(task1, task2); | ||
}, | ||
new SocketTesterBinder(typeOption), | ||
serverPortOption, | ||
clientPortOption, | ||
compressedOption, | ||
frequencyOption, | ||
totalPacksOption, | ||
packSizeOption); | ||
|
||
await rootCommand.InvokeAsync(args); | ||
|
||
return returnCode; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<Version>1.0.0</Version> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Snappier" Version="1.1.6" /> | ||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" /> | ||
<PackageReference Include="System.IO.Hashing" Version="8.0.0" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using System.IO.Compression; | ||
using System.Net; | ||
using System.Net.Sockets; | ||
using Snappier; | ||
|
||
namespace SocketTester; | ||
|
||
internal class TcpTester : ISocketTester | ||
{ | ||
private long _packIndex = 1; | ||
public bool Compressed { get; set; } = false; | ||
public int Frequency { get; set; } = 2000; | ||
public int TotalPacks { get; set; } = 0; | ||
public int PackSize { get; set; } = 1024; | ||
|
||
public Task RunServerAsync(int port = 9999) | ||
{ | ||
return Task.Run(async () => | ||
{ | ||
var listener = new TcpListener(new IPEndPoint(IPAddress.Any, port)); | ||
listener.Start(); | ||
var client = await listener.AcceptTcpClientAsync(); | ||
await using var sendStream = GetStream(client, Compressed, CompressionMode.Compress); | ||
await using var recvStream = GetStream(client, Compressed, CompressionMode.Decompress); | ||
while (TotalPacks == 0 || _packIndex < TotalPacks) | ||
{ | ||
var readBytes = await RecvAsync(recvStream); | ||
if (readBytes > 0) | ||
{ | ||
await Task.Delay(Frequency); | ||
await SendAsync(sendStream); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
public Task RunClientAsync(int port = 8888, string ip = "127.0.0.1") | ||
{ | ||
return Task.Run(async () => | ||
{ | ||
var client = new TcpClient(); | ||
await client.ConnectAsync(IPAddress.Parse(ip), port); | ||
await using var sendStream = GetStream(client, Compressed, CompressionMode.Compress); | ||
await using var recvStream = GetStream(client, Compressed, CompressionMode.Decompress); | ||
await SendAsync(sendStream); | ||
while (TotalPacks == 0 || _packIndex < TotalPacks) | ||
{ | ||
var readBytes = await RecvAsync(recvStream); | ||
if (readBytes > 0) | ||
{ | ||
await Task.Delay(Frequency); | ||
await SendAsync(sendStream); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
private Stream GetStream(TcpClient client, bool compressed, CompressionMode mode) | ||
{ | ||
var stream = client.GetStream(); | ||
if (compressed) | ||
{ | ||
return new SnappyStream(stream, mode); | ||
} | ||
|
||
return stream; | ||
} | ||
|
||
private async Task SendAsync(Stream stream) | ||
{ | ||
if (TotalPacks != 0 && _packIndex > TotalPacks) | ||
{ | ||
return; | ||
} | ||
var data = Util.GenerateRandomBytes(PackSize); | ||
Console.WriteLine($"Send -> PackIndex: {_packIndex} PackSize: {PackSize} Length:{data.Length} CheckSum: {Util.CheckSum(data)}"); | ||
await stream.WriteAsync(data); | ||
await stream.FlushAsync(); | ||
} | ||
|
||
private async Task<int> RecvAsync(Stream stream) | ||
{ | ||
var buffer = new byte[2048]; | ||
var readBytes = await stream.ReadAsync(buffer, 0, buffer.Length); | ||
|
||
if (readBytes > 0) | ||
{ | ||
Console.WriteLine($"Recv -> PackIndex: {_packIndex} PackSize: {PackSize} Length:{readBytes} CheckSum: {Util.CheckSum(buffer[..readBytes])}"); | ||
_packIndex++; | ||
} | ||
return readBytes; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
using System.Net; | ||
using System.Net.Sockets; | ||
|
||
namespace SocketTester | ||
{ | ||
internal class UdpStream : Stream | ||
{ | ||
private readonly UdpClient _client; | ||
private readonly bool _remoteWrite; | ||
private IPEndPoint? _remoteEndPoint; | ||
|
||
public IPEndPoint RemoteEndPoint => _remoteEndPoint; | ||
|
||
public UdpStream(UdpClient client, bool remoteWrite) | ||
{ | ||
_client = client; | ||
_remoteWrite = remoteWrite; | ||
} | ||
|
||
public override void Flush() | ||
{ | ||
} | ||
|
||
public override int Read(byte[] buffer, int offset, int count) | ||
{ | ||
var recv = _client.Receive(ref _remoteEndPoint); | ||
recv.CopyTo(buffer, 0); | ||
return recv.Length; | ||
} | ||
|
||
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | ||
{ | ||
var recv = await _client.ReceiveAsync(cancellationToken); | ||
_remoteEndPoint = recv.RemoteEndPoint; | ||
recv.Buffer.CopyTo(buffer, 0); | ||
return recv.Buffer.Length; | ||
} | ||
|
||
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = new CancellationToken()) | ||
{ | ||
var recv = await _client.ReceiveAsync(cancellationToken); | ||
_remoteEndPoint = recv.RemoteEndPoint; | ||
recv.Buffer.CopyTo(buffer); | ||
return recv.Buffer.Length; | ||
} | ||
|
||
public override long Seek(long offset, SeekOrigin origin) | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
|
||
public override void SetLength(long value) | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
|
||
public override void Write(byte[] buffer, int offset, int count) | ||
{ | ||
if (_remoteWrite && _remoteEndPoint != null) | ||
{ | ||
_client.Send(buffer, count, _remoteEndPoint); | ||
} | ||
else | ||
{ | ||
_client.Send(buffer, count); | ||
} | ||
} | ||
|
||
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) | ||
{ | ||
if (_remoteWrite && _remoteEndPoint != null) | ||
{ | ||
await _client.SendAsync(buffer, count, _remoteEndPoint); | ||
} | ||
else | ||
{ | ||
await _client.SendAsync(buffer, count); | ||
} | ||
} | ||
|
||
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = new CancellationToken()) | ||
{ | ||
if (_remoteWrite && _remoteEndPoint != null) | ||
{ | ||
await _client.SendAsync(buffer, _remoteEndPoint, cancellationToken); | ||
} | ||
else | ||
{ | ||
await _client.SendAsync(buffer, cancellationToken); | ||
} | ||
} | ||
|
||
public override bool CanRead => true; | ||
public override bool CanSeek => false; | ||
public override bool CanWrite => true; | ||
public override long Length => throw new NotSupportedException(); | ||
public override long Position | ||
{ | ||
get => throw new NotSupportedException(); | ||
set => throw new NotSupportedException(); | ||
} | ||
} | ||
|
||
internal static class Ext | ||
{ | ||
public static UdpStream GetStream(this UdpClient client, bool remoteWrite = false) | ||
{ | ||
return new UdpStream(client, remoteWrite); | ||
} | ||
} | ||
} |
Oops, something went wrong.