C
C#•3mo ago
Outspending

TcpClient being Disposed

I am pretty new to C#'s Dispose system, i came from JVM stuff so i'm pretty familiar with OOP. Error:
Client Error: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
Client Error: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
Code:
public class ServerClient : IPacketable
{
public readonly TcpClient Client;
public readonly NetworkStream Stream;

public ServerClient(TcpClient client)
{
Client = client;
Stream = client.GetStream();

Thread clientThread = new Thread(Init);
clientThread.Start();
}

private void Init()
{
try
{
string clientAddress = ((IPEndPoint) Client.Client.RemoteEndPoint).Address.ToString();
Console.WriteLine("Handling client from: " + clientAddress);

new PacketListener(this);
SendHandshakePacket(HandshakePacket.ConnectionState.Login);
}
catch (Exception e)
{
Console.WriteLine("Client Error: " + e.Message);
}
}

public void SendHandshakePacket(HandshakePacket.ConnectionState state)
{
HandshakePacket packet = new HandshakePacket(
protocolVersion: 754,
serverAddress: "localhost",
serverPort: 25565,
nextState: state
);

SendPacket(packet);
}

public void SendPacket(IPacket packet)
{
byte[] packetBytes = packet.ToByteArray();
Stream.Write(packetBytes, 0, packetBytes.Length);
}
}
public class ServerClient : IPacketable
{
public readonly TcpClient Client;
public readonly NetworkStream Stream;

public ServerClient(TcpClient client)
{
Client = client;
Stream = client.GetStream();

Thread clientThread = new Thread(Init);
clientThread.Start();
}

private void Init()
{
try
{
string clientAddress = ((IPEndPoint) Client.Client.RemoteEndPoint).Address.ToString();
Console.WriteLine("Handling client from: " + clientAddress);

new PacketListener(this);
SendHandshakePacket(HandshakePacket.ConnectionState.Login);
}
catch (Exception e)
{
Console.WriteLine("Client Error: " + e.Message);
}
}

public void SendHandshakePacket(HandshakePacket.ConnectionState state)
{
HandshakePacket packet = new HandshakePacket(
protocolVersion: 754,
serverAddress: "localhost",
serverPort: 25565,
nextState: state
);

SendPacket(packet);
}

public void SendPacket(IPacket packet)
{
byte[] packetBytes = packet.ToByteArray();
Stream.Write(packetBytes, 0, packetBytes.Length);
}
}
8 Replies
Outspending
Outspending•3mo ago
its erroring from
Stream.Write(packetBytes, 0, packetBytes.Length);
Stream.Write(packetBytes, 0, packetBytes.Length);
when im trying to send the handshake packet
Jimmacle
Jimmacle•3mo ago
you aren't disposing the client anywhere here, where is the code that constructs one of these objects?
Outspending
Outspending•3mo ago
this is the class that is creating the ServerClient:
public class ServerConnection
{
private static bool _IsRunning;

private readonly TcpListener _listener;

public ServerConnection(IPAddress address, int port)
{
if (_IsRunning)
{
throw new Exception("Server is already running.");
}

_listener = new TcpListener(address, port);
_IsRunning = true;
}

public void Init()
{
try
{
_listener.Start();
Console.WriteLine("Server started. Waiting for connections...");

TcpClient client = _listener.AcceptTcpClient();
Console.WriteLine("Client connected.");

new ServerClient(client);
}
catch (Exception e)
{
Console.WriteLine("Server Error: " + e.Message);
}
}
}
public class ServerConnection
{
private static bool _IsRunning;

private readonly TcpListener _listener;

public ServerConnection(IPAddress address, int port)
{
if (_IsRunning)
{
throw new Exception("Server is already running.");
}

_listener = new TcpListener(address, port);
_IsRunning = true;
}

public void Init()
{
try
{
_listener.Start();
Console.WriteLine("Server started. Waiting for connections...");

TcpClient client = _listener.AcceptTcpClient();
Console.WriteLine("Client connected.");

new ServerClient(client);
}
catch (Exception e)
{
Console.WriteLine("Server Error: " + e.Message);
}
}
}
i thought it was just because i was storing the TcpStream inside the class but i tried just method and idk not sure why it ain't workin works fine up until i try to connect aka sending the HandshakePacket
Outspending
Outspending•3mo ago
No description
Jimmacle
Jimmacle•3mo ago
what code logs "client has disconnected"?
Outspending
Outspending•3mo ago
public class PacketListener
{
private bool _isRunning;

public PacketListener(ServerClient client)
{
_isRunning = true;

NetworkStream stream = client.Stream;
while (_isRunning)
{
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);

if (bytesRead > 0)
{
stream.Write(buffer, 0, bytesRead);
}
else
{
break;
}
}

client.Client.Close();
Console.WriteLine("Client has disconnected.");
}

public void Stop()
{
_isRunning = false;
}
}
public class PacketListener
{
private bool _isRunning;

public PacketListener(ServerClient client)
{
_isRunning = true;

NetworkStream stream = client.Stream;
while (_isRunning)
{
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);

if (bytesRead > 0)
{
stream.Write(buffer, 0, bytesRead);
}
else
{
break;
}
}

client.Client.Close();
Console.WriteLine("Client has disconnected.");
}

public void Stop()
{
_isRunning = false;
}
}
legit very messy but i just wanna understand why its doing this wait- maybe its breaking the loop... one sec it is 💀 thanks for the help, its disposing cuz im closing the connection i'm so dumb yep, i just had to send the handshake packet before i started listening for packets
Jimmacle
Jimmacle•3mo ago
:pepeOK: fyi, TcpClient and raw threads are kind of outdated Socket and Tasks are preferred instead
Outspending
Outspending•3mo ago
epic ty