22using System . Net ;
33using System . Text ;
44using RetroNet_BBS . Encoders ;
5+ using RetroNet_BBS . Pages ;
56
67namespace RetroNet_BBS . Server
78{
89 public class Server
910 {
10- private TcpListener Listener ;
11+ private TcpListener listener ;
1112 private readonly string IpAddress ;
1213 private readonly int Port ;
1314
15+ private int clientConnectedCount ;
16+
1417 public Server ( string host )
1518 {
1619 IpAddress = "192.168.1.2" ;
1720 Port = 8502 ;
1821 }
1922
23+ /// <summary>
24+ /// Creates a new server instance and starts listening for incoming connections.
25+ /// </summary>
26+ /// <returns></returns>
27+ /// <exception cref="InvalidOperationException"></exception>
2028 public async Task Start ( )
2129 {
22- // Abort operation if server is already running
23- if ( Listener != null )
30+ if ( listener != null )
2431 {
2532 throw new InvalidOperationException ( "Server is already running!" ) ;
2633 }
2734
2835 IPAddress localAddr = IPAddress . Parse ( IpAddress ) ;
29- Listener = new TcpListener ( localAddr , Port ) ;
30- Listener . Start ( ) ;
36+ listener = new TcpListener ( localAddr , Port ) ;
37+ listener . Start ( ) ;
38+
39+ clientConnectedCount = 0 ;
3140
3241 OnMessageReceived ( "Server started. Waiting for a connection..." ) ;
3342
3443 while ( true )
3544 {
36- // Handle new client connection
37- TcpClient client = await Listener . AcceptTcpClientAsync ( ) ;
38- OnMessageReceived ( $ "Connected! Client IP: { client . Client . RemoteEndPoint } ") ;
39- _ = HandleClientAsync ( client ) ;
45+ try
46+ {
47+ while ( true )
48+ {
49+ Accept ( await listener . AcceptTcpClientAsync ( ) ) ;
50+ }
51+ }
52+ finally
53+ {
54+ listener . Stop ( ) ;
55+ }
4056 }
4157 }
4258
59+ /// <summary>
60+ /// Accepts a new client connection and starts a new task to handle the client.
61+ /// </summary>
62+ /// <param name="client"></param>
63+ /// <returns></returns>
64+ private async Task Accept ( TcpClient client )
65+ {
66+ clientConnectedCount ++ ;
67+
68+ await Task . Yield ( ) ;
69+ await HandleClientAsync ( client ) ;
70+ }
71+
4372 public void Stop ( )
4473 {
45- Listener ? . Stop ( ) ;
46- Listener = null ;
74+ listener . Stop ( ) ;
75+ listener = null ;
4776 }
4877
78+ /// <summary>
79+ /// Handle a single connection
80+ /// </summary>
81+ /// <param name="client">Client handled</param>
82+ /// <returns>Task</returns>
4983 private async Task HandleClientAsync ( TcpClient client )
5084 {
5185 NetworkStream stream = client . GetStream ( ) ;
5286
5387 byte [ ] buffer = new byte [ 1024 ] ;
5488 StringBuilder messageBuilder = new StringBuilder ( ) ;
5589
90+ byte [ ] response = new Petscii ( Pages . Pages . ShowWelcome ( clientConnectedCount ) ) . FromAscii ( ) ;
91+
92+ await stream . WriteAsync ( response , 0 , response . Length ) ;
93+
5694 // Receive data in a loop until the client disconnects
5795 while ( true )
5896 {
@@ -61,6 +99,8 @@ private async Task HandleClientAsync(TcpClient client)
6199 if ( bytesRead == 0 )
62100 {
63101 OnMessageReceived ( $ "Client { client . Client . RemoteEndPoint } disconnected.") ;
102+
103+ clientConnectedCount -- ;
64104 break ; // Client disconnected
65105 }
66106
@@ -74,12 +114,6 @@ private async Task HandleClientAsync(TcpClient client)
74114 // Raise the MessageReceived event
75115 OnMessageReceived ( $ "{ client . Client . RemoteEndPoint } : { receivedMessage } ") ;
76116
77- var encoder = new Petscii ( "<yellow>Hello <red><revon>world!<revoff>" ) ;
78-
79- byte [ ] response = encoder . FromAscii ( ) ;
80-
81- await stream . WriteAsync ( response , 0 , response . Length ) ;
82-
83117 messageBuilder . Clear ( ) ;
84118 }
85119 }
0 commit comments