Как я могу читать данные из сетевого потока синхронно? - PullRequest
1 голос
/ 21 марта 2009

Я хочу прочитать данные из сетевого потока в 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 #?

Ответы [ 3 ]

1 голос
/ 21 марта 2009

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

Потоки могут поначалу быть немного пугающими, особенно если вы используете Windows Forms (везде делегаты!), А не консольное приложение, но они очень полезны. При правильном использовании они могут сильно помочь, особенно в области сетевых технологий.

0 голосов
/ 28 октября 2010

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

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

0 голосов
/ 21 марта 2009
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)

...