2011-07-14 13 views
5

बंद करता हूं तो Async सॉकेट क्रैश हो जाता है नीचे दिखाया गया कोड लगभग काम करता प्रतीत होता है। अगर मैं इसका उदाहरण बनाता हूं और "कनेक्ट" को कॉल करता हूं तो सभी ठीक काम करता है। जब मैं "डिस्कनेक्ट" कहता हूं, कभी-कभी सबकुछ ठीक होता है (मुख्य रूप से यदि मैं ब्रेकपॉइंट जोड़ता हूं और धीरे-धीरे फ़ंक्शन के माध्यम से कदम उठाता हूं)। यदि मैं ब्रेकपॉइंट का उपयोग नहीं करता हूं तो क्लास (जीत फॉर्म ऐप के रूप में होस्ट किया जा रहा है) गायब हो जाता है (फॉर्म करता है) लेकिन विजुअल स्टूडियो अभी भी सोचता है कि यह चल रहा है। विजुअल स्टूडियो की आउटपुट विंडो में मुझे "सिस्टम का पहला मौका अपवाद" System.ObjectDisposedException 'System.dll में हुआ "मिलता है। क्या कोई यह बता सकता है कि मैं क्या गलत कर रहा हूं?जब मैं सॉकेट

// State object for reading client data asynchronously 
public class StateObject 
{ 
    private Guid ID = Guid.NewGuid(); 
    // Client socket. 
    public Socket workSocket = null; 
    // Size of receive buffer. 
    public const int BufferSize = 1024; 
    // Receive buffer. 
    public byte[] buffer = new byte[BufferSize]; 
} 

public class NetworkComms : IBasePanel 
{ 
    private static ILog _log = LogManager.GetCurrentClassLogger(); 

    // ManualResetEvent instances signal completion. 
    private static ManualResetEvent connectDone = new ManualResetEvent(false); 
    private static ManualResetEvent sendDone = new ManualResetEvent(false); 
    private static ManualResetEvent receiveDone = new ManualResetEvent(false); 

    private static Socket _client = null; 
    private static IPEndPoint _endpoint = null; 

    public event ReceiveMessageEventHandler OnReceiveMessage; 

    public NetworkComms(string address, int port) 
    { 
     _endpoint = new IPEndPoint(GetIPAddress(address), port); 
    } 

    private IPAddress GetIPAddress(string address) 
    { 
     IPAddress ipAddress = null; 

     if (IPAddress.TryParse(address, out ipAddress)) 
     { 
      return ipAddress; 
     } 
     else 
     { 
      IPHostEntry ipHostInfo = Dns.GetHostEntry(address); 
      return ipHostInfo.AddressList[ipHostInfo.AddressList.Count() - 1]; 
     } 
    } 

    private void ConnectCallback(IAsyncResult ar) 
    { 
     // Retrieve the socket from the state object. 
     Socket client = (Socket)ar.AsyncState; 

     // Complete the connection. 
     client.EndConnect(ar); 

     _log.DebugFormat("Socket connected to {0}", client.RemoteEndPoint.ToString()); 

     // Signal that the connection has been made. 
     connectDone.Set(); 
    } 

    private void Receive() 
    { 
     // Create the state object. 
     StateObject state = new StateObject(); 
     state.workSocket = _client; 

     // Begin receiving the data from the remote device. 
     _client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); 
    } 

    private void ReceiveCallback(IAsyncResult ar) 
    { 
     // Retrieve the state object and the client socket 
     // from the asynchronous state object. 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket client = state.workSocket; 

     // Read data from the remote device. 
     int bytesRead = client.EndReceive(ar); 

     if (bytesRead > 0) 
     { 
      // There might be more data, so store the data received so far. 
      ReceivedNewMessage(Encoding.Default.GetString(state.buffer, 0, bytesRead)); 

      // Get the rest of the data. 
      client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); 
     } 
     else 
     { 
      // Signal that all bytes have been received. 
      receiveDone.Set(); 
     } 
    } 

    private static void SendCallback(IAsyncResult ar) 
    { 
     // Retrieve the socket from the state object. 
     Socket client = (Socket)ar.AsyncState; 

     // Complete sending the data to the remote device. 
     int bytesSent = client.EndSend(ar); 
     _log.DebugFormat("Sent {0} bytes to server.", bytesSent); 

     // Signal that all bytes have been sent. 
     sendDone.Set(); 
    } 

    public void SendMessage(byte[] message) 
    { 
     _client.BeginSend(message, 0, message.Length, 0, new AsyncCallback(SendCallback), _client); 
     sendDone.WaitOne(); 
    } 

    public void Connect() 
    { 
     _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     _client.BeginConnect(_endpoint, new AsyncCallback(ConnectCallback), _client); 
     connectDone.WaitOne(); 

     Receive(); 
    } 

    public void Disconnect() 
    { 
     try 
     { 
      _client.Shutdown(SocketShutdown.Both); 
      _client.Close(); 
     } 
     finally 
     { 
      _client = null; 

      connectDone.Reset(); 
      sendDone.Reset(); 
      receiveDone.Reset(); 
     } 
    } 

    private void ReceivedNewMessage(string message) 
    { 
     if (this.OnReceiveMessage != null) 
     { 
      this.OnReceiveMessage(message); 
     } 
    } 

    public bool IsConnected 
    { 
     get 
     { 
      if (_client == null) return false; 
      return _client.Connected; 
     } 
    } 
} 
+0

स्थिर और आवृत्ति सदस्यों का आपका मिश्रित उपयोग बल्कि परेशान है। क्या आप इस ऑब्जेक्ट को एकाधिक थ्रेड से उपयोग कर रहे हैं? – ChaosPandion

+0

मैंने अब सभी "statics" को हटा दिया है क्योंकि इन्हें मूल कोड से हटा दिया गया था, जिन पर मैंने अपने परिवर्तनों पर आधारित था। फिर भी वही समस्या देखें। – Retrocoder

+0

अगर मैं _client.Close() को कॉल नहीं करता हूं तो एप्लिकेशन ठीक काम करता है। जैसे ही मैं इस कमांड का उपयोग करता हूं, मुझे "डिसप्लेयरिंग" समस्या दिखाई देती है। – Retrocoder

उत्तर

1

आपके सभी कॉलबैक को अपवादों को संभालने की आवश्यकता है, जो नेटवर्क प्रोग्रामिंग में सापेक्ष रूप से आम हैं।

इस मामले में शायद यह हो रहा है कि client.EndReceive(ar); ऑब्जेक्ट डिस्प्ले अपवाद को फेंक रहा है क्योंकि सॉकेट को पहले ही बंद कर दिया गया है।

+0

जैसा कि आप वर्णन करते हैं, मुझे एक समस्या थी: 'EndReceive' एक अपवाद फेंक रहा था, और मैं' ऑब्जेक्टडिस्प्लेक्स अपवाद 'के बजाय अपने' try' block 'में' सॉकेट अपवाद 'के लिए लेखांकन कर रहा था। हालांकि, दुर्भाग्यपूर्ण यह है कि इस तरह के एएनसीसी कोड में अपवाद सरल आउटपुट संदेशों के लिए चुप हो जाते हैं (वे प्रचार नहीं करते हैं और कहीं स्टैक ट्रेस दिखाते हैं) लेकिन ** अभी भी मेरे प्रोग्राम ** को समाप्त कर देते हैं! – nh2

संबंधित मुद्दे