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
class Program | |
{ | |
private static TcpListener _listener; | |
private static readonly byte[] ShortMessageBuffer = Encoding.UTF8.GetBytes("Hello\r\n"); | |
private static readonly byte[] LongMessageBuffer = Encoding.UTF8.GetBytes("Be my friend, please?\r\n"); | |
static readonly byte[] HeartbeatBuffer = Encoding.UTF8.GetBytes("\r\n"); | |
static void Main() | |
{ | |
_listener = new TcpListener(IPAddress.Loopback, 9090); | |
_listener.Start(); | |
for (int i = 0; i < 4; i++) | |
{ | |
ListenToNewTcpConnection(); | |
} | |
for (int i = 0; i < 1000; i++) | |
{ | |
Console.Write("\r" + i + " "); | |
RunClient().Wait(); | |
} | |
} | |
private static async Task RunClient() | |
{ | |
using (var tcpClient = new TcpClient()) | |
{ | |
await tcpClient.ConnectAsync("127.0.0.1", 9090); | |
using (var networkStream = tcpClient.GetStream()) | |
{ | |
var streamReader = new StreamReader(networkStream); | |
await networkStream.WriteAsync(ShortMessageBuffer, 0, ShortMessageBuffer.Length); | |
await networkStream.WriteAsync(LongMessageBuffer, 0, LongMessageBuffer.Length); | |
var reply = await streamReader.ReadLineAsync(); | |
if (reply != "ixqZU8RhEpaoJ6v4xHgE1w==") | |
throw new InvalidDataException("Bad server?"); | |
await networkStream.FlushAsync(); | |
do | |
{ | |
reply = await streamReader.ReadLineAsync(); | |
} while (string.IsNullOrEmpty(reply)); | |
Console.WriteLine(reply); | |
} | |
} | |
} | |
private static void ListenToNewTcpConnection() | |
{ | |
Task.Run(async () => | |
{ | |
var tcpClient = await _listener.AcceptTcpClientAsync(); | |
ListenToNewTcpConnection(); | |
using(var networkStream = tcpClient.GetStream()) | |
{ | |
var streamReader = new StreamReader(networkStream); | |
var greet = await streamReader.ReadLineAsync(); | |
var computeHash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(greet)); | |
var replyBuffer = Encoding.UTF8.GetBytes(Convert.ToBase64String(computeHash) + "\r\n"); | |
await networkStream.WriteAsync(replyBuffer, 0, replyBuffer.Length); | |
// now the connection is valid, we can start talking to each other | |
await ProcessConnection(networkStream); | |
} | |
}); | |
} | |
private static async Task ProcessConnection(NetworkStream stream) | |
{ | |
using (var streamReader = new StreamReader(stream)) | |
using (var streamWriter = new StreamWriter(stream)) | |
{ | |
var readNextLine = streamReader.ReadLineAsync(); | |
while (true) | |
{ | |
var resultingTask = await Task.WhenAny(readNextLine, Task.Delay(5000)); | |
if (resultingTask != readNextLine) | |
{ | |
// keep alive for the tcp connection | |
await stream.WriteAsync(HeartbeatBuffer, 0, HeartbeatBuffer.Length); | |
continue; | |
} | |
var msg = await readNextLine; | |
readNextLine = streamReader.ReadLineAsync(); | |
msg = new string(msg.Reverse().ToArray()); | |
await streamWriter.WriteLineAsync(msg); | |
await streamWriter.FlushAsync(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment