Ich bin auf einem kleinen DLL zu TCP-Kommunikation gewidmet arbeiten,Sockel ObjectDisposed Exception
In meinem Projekt habe ich eine Serverklasse bekam, die eine TcpListener verwendet eingehende Verbindungen zu akzeptieren. Eingehende Verbindungen werden in einem Dictionary gespeichert und von dort bearbeitet.
jeden Code der Verbindung wie folgt aussieht:
public class Connection : ConnectionBase<Coder.Coder>
{
public Connection(TcpClient client, Guid id) : base()
{
Id = id;
Client = client;
}
public void Start()
{
IsConnected = true;
Client.Client.BeginReceive(m_message, 0, m_message.Length, SocketFlags.None, new AsyncCallback(on_data_received), null);
}
public void Stop()
{
try
{
Client.Close();
handle_connection_lost(new ConnectionLostArgs(Id));
}
catch
{ }
}
public void Send(byte[] data)
{
try
{
using (NetworkStream s = Client.GetStream())
{
using (BinaryWriter w = new BinaryWriter(s))
{
var buffer = m_coder.Encode(data);
w.Write(buffer);
w.Flush();
}
}
}
catch
{ handle_connection_lost(new ConnectionLostArgs(Id)); }
}
public Guid Id { get; set; }
public TcpClient Client { get; set; }
private byte[] m_message = new byte[1024];
private void on_data_received(IAsyncResult ar)
{
try
{
Client.Client.BeginReceive(m_message, 0, m_message.Length,
SocketFlags.None, new AsyncCallback(on_data_received), null);
int bytesRead = Client.Client.EndReceive(ar);
if (bytesRead > 0)
{
byte[] data = new byte[bytesRead];
Array.Copy(m_message, data, bytesRead);
m_coder.Push(data);
}
}
catch(Exception ex)
{
Console.WriteLine("Connection::on_data_received : {0}", ex.Message);
handle_connection_lost(new ConnectionLostArgs(Id));
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
try
{
Stop();
}
catch
{ }
}
base.Dispose(disposing);
}
}
* Bitte beachten Sie, dass der Coder ist eine Klasse verantwortlich für die Decodierung und Codierung von Datenpaketen.
Abgesehen von den oben, ich habe eine socket-basierte TcpClient (was ich hoffe, später mit Silverlight wiederzuverwenden) Der Code wird wie folgt dar:
public class TcpSocketClient : TcpClientBase<Coder.Coder>
{
public static TcpSocketClient Create(string host, int port)
{
if (port == 0)
return null;
return new TcpSocketClient(host, port);
}
private TcpSocketClient(string host, int port) : base()
{
IsConnected = false;
RemoteEndpoint = new DnsEndPoint(host, port);
}
public void Start()
{
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte[] buffer = new byte[1024];
SocketAsyncEventArgs e = new SocketAsyncEventArgs()
{
RemoteEndPoint = RemoteEndpoint,
UserToken = m_socket,
};
e.SetBuffer(buffer, 0, buffer.Length);
e.Completed += new EventHandler<SocketAsyncEventArgs>(handle_socket_connect_completed);
m_socket.ConnectAsync(e);
}
public void Stop()
{
try
{
m_socket.Close();
m_socket.Dispose();
}
catch (ObjectDisposedException)
{ }
}
public void Send(byte[] data)
{
try
{
var buffer = m_coder.Encode(data);
SocketAsyncEventArgs e = new SocketAsyncEventArgs()
{
BufferList = new List<ArraySegment<byte>>() { new ArraySegment<byte>(buffer) },
UserToken = m_socket
};
m_socket.SendAsync(e);
}
catch (Exception ex)
{ handle_client_disconnected(ex.Message); }
}
#region Properties
public DnsEndPoint RemoteEndpoint { get; private set; }
#endregion
#region Fields
Socket m_socket;
#endregion
void handle_socket_connect_completed(object sender, SocketAsyncEventArgs e)
{
if (!m_socket.Connected)
{
handle_client_disconnected("Failed to connect");
return;
}
e.Completed -= handle_socket_connect_completed;
e.Completed += new EventHandler<SocketAsyncEventArgs>(handle_socket_async_receive);
handle_client_connected();
m_socket.ReceiveAsync(e);
}
void handle_socket_async_receive(object sender, SocketAsyncEventArgs e)
{
if (e.BytesTransferred == 0)
{
handle_client_disconnected("Connection closed by the remote host");
try { m_socket.Close(); }
catch { }
return;
}
try
{
byte[] buffer = new byte[e.BytesTransferred];
Array.Copy(e.Buffer, buffer, e.BytesTransferred);
m_coder.Push(buffer);
}
catch { }
m_socket.ReceiveAsync(e);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
try
{
RemoteEndpoint = null;
m_socket.Close();
m_socket.Dispose();
}
catch
{ }
}
base.Dispose(disposing);
}
}
Ich habe eine Reihe erstellt Unit-Tests für beide.
In einem der Tests sende ich Daten vom Client an den Server. Funktioniert. In einem anderen Test sende ich Daten von der Verbindung des Servers zu einem Client. Episches Versagen. Ich bekomme Socket ObjectDisposed Ausnahmen in Connections on_data_received. Um ehrlich zu sein, ich habe keine Ahnung, was los ist - deshalb brauche ich etwas Hilfe.
Ich bin mit .NET 4, VS 2010 OS Meine Maschine ist Win7 (wenn diese Informationen von irgendeiner Hilfe ist)
Grüße, Maciek
Das ist ein gültiger Punkt, aber es hat das Hauptproblem nicht gelöst. Server - Daten -> Client :(Immer noch kämpfen, um dies zu tun – Maciek
Guter Punkt über "Hinweis: Sie sollten Ihre Verbindung schließen, wenn Sie 0 Bytes empfangen" –