VOGONS


Dedicated IPXNET server software (C# .NET 9)

Topic actions

Reply 60 of 64, by Caligula

User metadata
Rank Newbie
Rank
Newbie
Myg wrote on 2025-01-01, 01:48:

So how exactly do you imagine this should work? I've been thinking about it a bit more and was curious what I could actually add to the equation per say.

I just asked ChatGPT "How do I write a TCP server in C# that accepts two connections and forward the incoming data from one connection to the other?"

Reply (I just added Task.WaitAll to the code, otherwise it terminates immediately):

using System.Net;
using System.Net.Sockets;

class TcpServer
{
private const int Port = 5000; // Port number to listen on
private static TcpListener _tcpListener;
private static TcpClient _client1 = null;
private static TcpClient _client2 = null;

public static void Main(string[] args)
{
// Start the TCP listener
_tcpListener = new TcpListener(IPAddress.Any, Port);
_tcpListener.Start();

Console.WriteLine($"Server listening on port {Port}...");

// Accept exactly two client connections
AcceptClients().Wait();
}

private static async Task AcceptClients()
{
// Wait for the first client connection
_client1 = await _tcpListener.AcceptTcpClientAsync();
Console.WriteLine("First client connected.");

// Wait for the second client connection
_client2 = await _tcpListener.AcceptTcpClientAsync();
Console.WriteLine("Second client connected.");

// Handle the data forwarding between the two clients
var task1 = Task.Run(() => ForwardData(_client1, _client2)); // Forward from client1 to client2
var task2 = Task.Run(() => ForwardData(_client2, _client1)); // Forward from client2 to client1
Task.WaitAll([task1, task2], -1);
}

private static async Task ForwardData(TcpClient fromClient, TcpClient toClient)
{
using (fromClient)
using (toClient)
{
NetworkStream fromStream = fromClient.GetStream();
NetworkStream toStream = toClient.GetStream();

byte[] buffer = new byte[1024];
int bytesRead;

try
{
// Forward data from 'fromClient' to 'toClient'
while ((bytesRead = await fromStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
Console.WriteLine($"Forwarding {bytesRead} bytes from {fromClient.Client.RemoteEndPoint} to {toClient.Client.RemoteEndPoint}");

// Write the data to the other client's stream
await toStream.WriteAsync(buffer, 0, bytesRead);
await toStream.FlushAsync();
}
Show last 11 lines

Console.WriteLine("Client disconnected.");
}
catch (Exception ex)
{
Console.WriteLine($"Error in data forwarding: {ex.Message}");
}
}
}
}

This works already well with unmodified versions of Dosbox 0.74.3 and Dosbox-Staging (tested with DOOM2):

serial1 nullmodem port:5000 server:localhost
sersetup.exe

Main issues are that this code cannot handle any reconnect right now.

Reply 61 of 64, by Myg

User metadata
Rank Newbie
Rank
Newbie

I am fimilar with TCP servers/clients. I was just curious how to implement it on my server? How would I get the right people to send data to each other?

Reply 62 of 64, by Caligula

User metadata
Rank Newbie
Rank
Newbie
Myg wrote on 2025-01-05, 16:09:

I am fimilar with TCP servers/clients. I was just curious how to implement it on my server? How would I get the right people to send data to each other?

Maybe I get you wrong, but Nullmodem serial is a point to point connection, so data coming in from one client is always sent to the other client. In a LAN Dosbox already provides a client/server model. But it also works if both Dosbox instances connect to a server that just forwards the TCP packages. Since dosbox does not even use an envelope for the serial data, you could also forward the data between TCP and a physical serial port.

Or do you mean some kind of authentication or multiple nullmodem connections handled by the server at the same time?

Reply 63 of 64, by Myg

User metadata
Rank Newbie
Rank
Newbie
Caligula wrote on 2025-01-05, 17:37:
Myg wrote on 2025-01-05, 16:09:

I am fimilar with TCP servers/clients. I was just curious how to implement it on my server? How would I get the right people to send data to each other?

Maybe I get you wrong, but Nullmodem serial is a point to point connection, so data coming in from one client is always sent to the other client. In a LAN Dosbox already provides a client/server model. But it also works if both Dosbox instances connect to a server that just forwards the TCP packages. Since dosbox does not even use an envelope for the serial data, you could also forward the data between TCP and a physical serial port.

Or do you mean some kind of authentication or multiple nullmodem connections handled by the server at the same time?

Yea, I considered this but it seems very inefficient. I will contemplate approaches. If I can't find one I will consider a basic relaying to all clients approach. Yes I was concerned about multiple nullmodem connections... I am also concerned about this approach doubling (at the least) latency of an already latant protocol.

Reply 64 of 64, by siljo

User metadata
Rank Newbie
Rank
Newbie

Nice 😁