2009-03-20 2 views
1

Я хочу прочитать данные из сетевого потока в C#.Как я могу читать данные из сетевого потока синхронно?

У меня есть список клиентов, которые я регулярно опроса, но когда я начинаю читать данные с одного клиента, мне нужно прочитать все XML-сообщение, а затем перейти к следующему клиенту. Если есть некоторая задержка в получении данных, я не должен идти к следующему клиенту. Я должен подождать некоторое время и получить данные. Кроме того, я не должен ждать неопределенно. Просто тайм-аут и продолжить к следующему клиенту после й секунд ....

if(s.Available > 0) 
{ 
//read data till i get the whole message. 
//timeout and continue with other clients if I dont recieve the whole message 
//within x seconds. 
} 

Есть ли способ сделать это элегантно в C#?

ответ

0
using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 

public class SynchronousSocketClient { 

    public static void StartClient() { 
     // Data buffer for incoming data. 
     byte[] bytes = new byte[1024]; 

     // Connect to a remote device. 
     try { 
      // Establish the remote endpoint for the socket. 
      // This example uses port 11000 on the local computer. 
      IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()) 
      IPAddress ipAddress = ipHostInfo.AddressList[0]; 
      IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000); 

      // Create a TCP/IP socket. 
      Socket sender = new Socket(AddressFamily.InterNetwork, 
       SocketType.Stream, ProtocolType.Tcp); 

      // Connect the socket to the remote endpoint. Catch any errors. 
      try { 
       sender.Connect(remoteEP); 

       Console.WriteLine("Socket connected to {0}", 
        sender.RemoteEndPoint.ToString()); 

       // Encode the data string into a byte array. 
       byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>"); 

       // Send the data through the socket. 
       int bytesSent = sender.Send(msg); 

       // Receive the response from the remote device. 
       int bytesRec = sender.Receive(bytes); 
       Console.WriteLine("Echoed test = {0}", 
        Encoding.ASCII.GetString(bytes,0,bytesRec)); 

       // Release the socket. 
       sender.Shutdown(SocketShutdown.Both); 
       sender.Close(); 

      } catch (ArgumentNullException ane) { 
       Console.WriteLine("ArgumentNullException : {0}",ane.ToString()); 
      } catch (SocketException se) { 
       Console.WriteLine("SocketException : {0}",se.ToString()); 
      } catch (Exception e) { 
       Console.WriteLine("Unexpected exception : {0}", e.ToString()); 
      } 

     } catch (Exception e) { 
      Console.WriteLine(e.ToString()); 
     } 
    } 

    public static int Main(String[] args) { 
     StartClient(); 
     return 0; 
    } 
} 

(взято из «Синхронный примера сокет клиента на MSDN)

+0

Это просто дает syncrhonous клиента ... Но это не совсем то, что я хочу. Я хочу, чтобы syncrhonous клиент занимал время и продолжал. –

1

Насколько я знаю, нет никакого способа сделать это, так что вы, скорее всего, в конечном итоге, используя несколько потоков. ИМХО, используя одну нить на клиенте, в первую очередь, это гораздо более чистое решение, тогда вы можете просто вызвать Read() в потоке, и он может занять столько времени, сколько захочет, в то время как другие потоки делают то же самое для других клиентов.

Вначале Threading может быть немного страшным, особенно если вы используете Windows Forms (делегаты везде!), А не консольное приложение, но они очень полезны. правильно, они могут многое помочь, особенно в области сетевого взаимодействия.

+0

Собственно, посмотрите здесь: http://stackoverflow.com/questions/375374/many-threads-or-as-few-threads-as-possible Кажется, что поток на одного клиента не является тем способом, из-за переключения контекста и все. –

0

Нет, нет способа сделать это. TCP не гарантирует, что все поступит сразу, поэтому вам нужно знать размер XML, чтобы узнать, все ли пришло. И ты этого не знаешь. Правильно?

Использование асинхронных методов является способ пойти (и построить строку с XML)

Смежные вопросы