2010-09-05 42 views
8

Tôi có một máy chủ cập nhật gửi các cập nhật của máy khách thông qua cổng TCP 12000. Việc gửi một tệp thành công chỉ lần đầu tiên, nhưng sau đó tôi nhận được thông báo lỗi trên máy chủ "Không thể ghi dữ liệu vào kết nối truyền tải: Kết nối hiện có bị đóng bởi máy chủ từ xa". Nếu tôi khởi động lại dịch vụ cập nhật trên máy chủ, nó hoạt động lại chỉ một lần. Tôi có dịch vụ windows đa luồng bình thường.Không thể ghi dữ liệu vào kết nối truyền tải: Kết nối hiện có bị đóng bởi máy chủ từ xa

MÁY CHỦ MÃ

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() 
     { 
     } 
    } 

tôi phải lưu ý cái gì mà dịch vụ cửa sổ của tôi (máy chủ) là đa luồng.

+0

Bạn đang sử dụng một 'TcpListener' (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx) để nghe các kết nối đến, và sau đó fielding các off để tách chủ đề? –

+0

vâng, đây là chính xác những gì im đang làm, im đăng mã đầy đủ của tôi trong bài viết gốc của tôi, cảm ơn bạn đã giúp đỡ ur – xnoor

+0

Là chương trình khách hàng của bạn mở một kết nối TCP mới cho mỗi bản cập nhật nó gửi hoặc cố gắng tái sử dụng trước đó ? Chương trình khách hàng của bạn có ràng buộc với một cổng nội bộ cụ thể không? –

Trả lời

0

Khi kết thúc nhận, hãy thiết lập vòng lặp while để nghe cho đến khi không còn dữ liệu nữa, sau đó thoát ra một cách duyên dáng: đóng luồng và ứng dụng khách. Khung thư viện libs lib coi nó là một vấn đề để thả một kết nối lạnh trên lối ra thread và do đó sẽ ném ngoại lệ bạn đang nhìn thấy.

Điều này cũng sẽ giúp bạn tiết kiệm từ một vấn đề liên tục bạn có thể sẽ thấy khi bạn sửa lỗi hiện tại: Luồng.Đọc với bộ định dạng độ dài sẽ không luôn cung cấp cho bạn bộ đệm đầy đủ mỗi lần. Dường như bạn đang gửi (tối đa) khối 2kb và nhận vào bộ đệm 1kb (một lần) bất kỳ cách nào để bạn cũng có thể bắt đầu nhận ngoại lệ XML.

Nếu đó không đủ chi tiết, hãy hỏi và tôi sẽ đào một số mã TcpClient cũ.

Các vấn đề liên quan