2010-09-05 14 views
8

द्वारा एक मौजूदा कनेक्शन जबरन बंद कर दिया गया था मेरे पास एक अद्यतन सर्वर है जो टीसीपी पोर्ट 12000 के माध्यम से क्लाइंट अपडेट भेजता है। एक फ़ाइल भेजने का केवल पहली बार सफल होता है, लेकिन उसके बाद मुझे सर्वर पर एक त्रुटि संदेश मिलता है "परिवहन कनेक्शन में डेटा लिखने में असमर्थ: रिमोट होस्ट द्वारा एक मौजूदा कनेक्शन जबरन बंद कर दिया गया था"। अगर मैं सर्वर पर अद्यतन सेवा को पुनरारंभ करता हूं, तो यह केवल एक बार फिर से काम करता है। मेरे पास सामान्य बहुप्रचारित विंडोज सेवा है।परिवहन कनेक्शन में डेटा लिखने में असमर्थ: रिमोट होस्ट

सर्वर कोड

namespace WSTSAU 
{ 
    public partial class ApplicationUpdater : ServiceBase 
    { 
     private Logger logger = LogManager.GetCurrentClassLogger(); 
     private int _listeningPort; 
     private int _ApplicationReceivingPort; 
     private string _setupFilename; 
     private string _startupPath; 
     public ApplicationUpdater() 
     { 
      InitializeComponent(); 
     } 

     protected override void OnStart(string[] args) 
     { 
      init(); 
      logger.Info("after init"); 
      Thread ListnerThread = new Thread(new ThreadStart(StartListener)); 
      ListnerThread.IsBackground = true; 
      ListnerThread.Start(); 
      logger.Info("after thread start"); 
     } 

     private void init() 
     { 
      _listeningPort = Convert.ToInt16(ConfigurationSettings.AppSettings["ListeningPort"]); 
      _setupFilename = ConfigurationSettings.AppSettings["SetupFilename"]; 
      _startupPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6); 
     } 

     private void StartListener() 
     { 
      try 
      { 
       logger.Info("Listening Started"); 
       ThreadPool.SetMinThreads(50, 50); 
       TcpListener listener = new TcpListener(_listeningPort); 
       listener.Start(); 
       while (true) 
       { 
        TcpClient c = listener.AcceptTcpClient(); 
        ThreadPool.QueueUserWorkItem(ProcessReceivedMessage, c); 
       } 
      } 
      catch (Exception ex) 
      { 
       logger.Error(ex.Message); 
      } 
     } 

     void ProcessReceivedMessage(object c) 
     { 
      try 
      { 
       TcpClient tcpClient = c as TcpClient; 
       NetworkStream Networkstream = tcpClient.GetStream(); 
       byte[] _data = new byte[1024]; 
       int _bytesRead = 0; 

       _bytesRead = Networkstream.Read(_data, 0, _data.Length); 

       MessageContainer messageContainer = new MessageContainer(); 
       messageContainer = SerializationManager.XmlFormatterByteArrayToObject(_data, messageContainer) as MessageContainer; 

       switch (messageContainer.messageType) 
       { 
        case MessageType.ApplicationUpdateMessage: 
         ApplicationUpdateMessage appUpdateMessage = new ApplicationUpdateMessage(); 
         appUpdateMessage = SerializationManager.XmlFormatterByteArrayToObject(messageContainer.messageContnet, appUpdateMessage) as ApplicationUpdateMessage; 
         Func<ApplicationUpdateMessage, bool> HandleUpdateRequestMethod = HandleUpdateRequest; 
         IAsyncResult cookie = HandleUpdateRequestMethod.BeginInvoke(appUpdateMessage, null, null); 
         bool WorkerThread = HandleUpdateRequestMethod.EndInvoke(cookie); 
         break; 
       } 
      } 
      catch (Exception ex) 
      { 
       logger.Error(ex.Message); 
      } 
     } 


     private bool HandleUpdateRequest(ApplicationUpdateMessage appUpdateMessage) 
     { 
      try 
      { 
       TcpClient tcpClient = new TcpClient(); 
       NetworkStream networkStream; 
       FileStream fileStream = null; 

       tcpClient.Connect(appUpdateMessage.receiverIpAddress, appUpdateMessage.receiverPortNumber); 
       networkStream = tcpClient.GetStream(); 

       fileStream = new FileStream(_startupPath + "\\" + _setupFilename, FileMode.Open, FileAccess.Read); 

       FileInfo fi = new FileInfo(_startupPath + "\\" + _setupFilename); 

       BinaryReader binFile = new BinaryReader(fileStream); 

       FileUpdateMessage fileUpdateMessage = new FileUpdateMessage(); 
       fileUpdateMessage.fileName = fi.Name; 
       fileUpdateMessage.fileSize = fi.Length; 

       MessageContainer messageContainer = new MessageContainer(); 
       messageContainer.messageType = MessageType.FileProperties; 
       messageContainer.messageContnet = SerializationManager.XmlFormatterObjectToByteArray(fileUpdateMessage); 

       byte[] messageByte = SerializationManager.XmlFormatterObjectToByteArray(messageContainer); 

       networkStream.Write(messageByte, 0, messageByte.Length); 

       int bytesSize = 0; 
       byte[] downBuffer = new byte[2048]; 

       while ((bytesSize = fileStream.Read(downBuffer, 0, downBuffer.Length)) > 0) 
       { 
        networkStream.Write(downBuffer, 0, bytesSize); 
       } 

       fileStream.Close(); 
       tcpClient.Close(); 
       networkStream.Close(); 

       return true; 
      } 
      catch (Exception ex) 
      { 
       logger.Info(ex.Message); 
       return false; 
      } 
      finally 
      { 
      } 
     } 


     protected override void OnStop() 
     { 
     } 
    } 

मैं कुछ है कि मेरे खिड़कियों सेवा (सर्वर) थ्रेड है ध्यान दें करने के लिए है।

+0

क्या आप आने वाले कनेक्शन सुनने के लिए 'tcpListener' (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx) का उपयोग कर रहे हैं, और फिर इन्हें अलग करने के लिए फ़ील्ड कर रहे हैं धागे? –

+0

हाँ, यह वही है जो मैं कर रहा हूं, मैं अपने मूल पोस्ट में अपना पूरा कोड पोस्ट कर रहा हूं, आपकी मदद के लिए धन्यवाद – xnoor

+0

क्या आपका क्लाइंट प्रोग्राम प्रत्येक अपडेट के लिए एक नया टीसीपी कनेक्शन खोल रहा है या पिछले एक को फिर से उपयोग करने का प्रयास कर रहा है ? क्या आपका क्लाइंट प्रोग्राम एक विशिष्ट स्थानीय बंदरगाह से जुड़ा है? –

उत्तर

0

प्राप्त करने के अंत में, कुछ और डेटा नहीं होने तक सुनने के लिए थोड़ी देर लूप सेट करें, फिर शानदार ढंग से बाहर निकलें: स्ट्रीम और क्लाइंट को बंद करें। ढांचा टीसीपी libs थ्रेड निकास पर एक कनेक्शन ठंडा ड्रॉप करने के लिए एक मुद्दा मानते हैं और इसलिए आप जो अपवाद देख रहे हैं उसे फेंक देंगे।

यह आपको एक इंटरमीटेंट समस्या से भी बचाएगा जो आपको वर्तमान में सही करने के बाद दिखाई देगा: स्ट्रीम। लंबाई विनिर्देशक के साथ पढ़ें हमेशा आपको अपना पूरा बफर नहीं देगा। ऐसा लगता है कि आप 2kb भाग भेज रहे हैं और एक (एकल-शॉट) 1kb बफर में किसी भी तरह से प्राप्त कर रहे हैं ताकि आप एक्सएमएल अपवाद भी प्राप्त कर सकें।

यदि यह पर्याप्त विवरण नहीं है, तो पूछें और मैं कुछ पुराने टीसीपी क्लाइंट कोड खोद दूंगा।

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