Tôi đang làm việc trên một nhỏ .dll dành riêng cho giao tiếp Tcp,Socket ObjectDisposed Exception
Trong dự án của tôi, tôi có một lớp máy chủ sử dụng TcpListener để chấp nhận các kết nối đến. Kết nối đến được lưu trữ trong Từ điển và được xử lý từ đó.
đang Mỗi kết nối trông giống như:
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);
}
}
* Xin lưu ý rằng Coder là một lớp chịu trách nhiệm giải mã và mã hóa các gói dữ liệu.
Ngoài việc trên, tôi đã có một TcpClient ổ cắm-based (mà tôi hy vọng để tái sử dụng sau với Silverlight), mã này như sau:
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);
}
}
tôi đã tạo ra một bộ kiểm tra đơn vị cho cả hai.
Trong một trong các thử nghiệm, tôi gửi dữ liệu từ máy khách đến máy chủ. Công trinh. Trong một thử nghiệm khác, tôi gửi dữ liệu từ kết nối của máy chủ đến máy khách. Epic thất bại. Tôi tiếp tục nhận được các ngoại lệ Socket ObjectDisposed trong On_data_received của Connection. Thành thật mà nói tôi không biết chuyện gì đang diễn ra - vì vậy tôi cần một chút trợ giúp.
Tôi đang sử dụng Net 4, VS 2010, hệ điều hành máy của tôi là Win7 (nếu thông tin này là của bất kỳ sự giúp đỡ)
Kính trọng, Maciek
Đó là điểm hợp lệ, tuy nhiên nó không giải quyết được vấn đề chính. Máy chủ - dữ liệu -> Khách hàng :(Vẫn đang vật lộn để thực hiện việc này – Maciek
Điểm tốt về "Lưu ý: Bạn nên đóng kết nối khi nhận được 0 byte" –