2014-09-27 2 views
1

Я пишу клиентское серверное приложение, использующее protobuf для сериализации, и TCPClient/TCPListener для передачи данных.protobuf-net closed tcpclient

Приложение было написано для отправки сообщения от клиента для разрыва, которое затем отправляет ответ. Затем он должен спать 2 секунды и повторять.

Все работает нормально для первого цикла, но когда он повторяет попытку во второй раз, он генерирует исключение, что сокет закрыт.

Я думал, используя SerializeWithLengthPrefix/DeserializeWithLengthPrefix, что это хранилище открыто?

Полный код ниже:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Net.Sockets; 
using ProtoBuf; 
using System.Net; 
using System.Threading.Tasks; 

namespace SocketServer 
{ 
    [ProtoContract] 
    public class Message 
    { 
     [ProtoMember(1)] 
     public string Content { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      StartAcceptor(); 

      StartClient(); 

      Console.ReadKey(); 
     } 

     static void StartAcceptor() 
     { 
      ThreadPool.QueueUserWorkItem(x => 
       { 
        var ipAddress = IPAddress.Parse("127.0.0.1"); 
        TcpListener serverSocket = new TcpListener(ipAddress, 8888); 
        serverSocket.Start(); 
        Console.WriteLine("Server >> Started"); 

        while (true) 
        { 
         var clientSocket = serverSocket.AcceptTcpClient(); 
         Console.WriteLine("Server >> Client Connected"); 
         StartServerSocket(clientSocket); 
        } 
       }); 
     } 

     static void StartServerSocket(TcpClient clientSocket) 
     { 
      ThreadPool.QueueUserWorkItem(x => 
       { 
        while ((true)) 
        { 
         using (NetworkStream networkStream = clientSocket.GetStream()) 
         { 
          var message = Serializer.DeserializeWithLengthPrefix<Message>(networkStream, PrefixStyle.Base128); 
          Console.WriteLine(message.Content); 

          message.Content += " Received"; 
          Serializer.SerializeWithLengthPrefix(networkStream, message, PrefixStyle.Base128); 
         } 
        } 
       }); 
     } 

     static void StartClient() 
     { 
      ThreadPool.QueueUserWorkItem(x => 
       { 
        var client = new TcpClient(); 
        Console.WriteLine("Client >> Started"); 
        client.Connect("127.0.0.1", 8888); 
        Console.WriteLine("Client >> Connected To Server"); 

        while (true) 
        { 
         NetworkStream serverStream = client.GetStream(); 

         var message = new Message(); 
         message.Content = "Hello"; 

         Serializer.SerializeWithLengthPrefix(serverStream, message, PrefixStyle.Base128); 

         var messager = Serializer.DeserializeWithLengthPrefix<Message>(serverStream, PrefixStyle.Base128); 
         Console.WriteLine(messager.Content); 

         Thread.Sleep(2000); 
        } 
       }); 
     } 
    } 
} 

ответ

0

Это вы закрываете сокет. Restructure:

while(...) 
    using(...) 
     {...} 

Кому:

using(...) 
    while(...) 
     {...} 

В данный момент, его конец с использованием блока в первой итерации, которая закрывает сокет.