views:

447

answers:

3

I want to read data from network stream in csharp.

I have a list of clients that I poll regularly but when I start reading data from one client, I have to read the whole xml message and then continue to the next client. If there is some delay in receiving data I should not go to the next client. I should wait for some time and get the data. Also, I shouldnt be waiting indefintely. Just time out and continue to next client after x seconds....

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. }

Is there good support from csharp language to do this elegantly....

Any help is appreciated. Thanks!!!

A: 
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;
    }
}

(taken from "Synchronous Client Socket example on msdn)

Arnshea
This just gives a syncrhonous client...But that is not exactly what I want. I want a syncrhonous client that timesout and continues.
+1  A: 

As far as I know there is no way to do this, so you will most likely end up using multiple threads. IMHO using one thread per client is a much cleaner solution in the first place, then you can just call Read() on the stream, and it can take as long as it wants, while the other threads are doing the same for the other clients.

Threading might be a bit scary at first, especially if you're using Windows Forms (delegates everywhere!) and not a console application, but they're very useful. If used correctly, they can help a lot, especially in the area of networking.

Aistina
Actually, look here: http://stackoverflow.com/questions/375374/many-threads-or-as-few-threads-as-possible Seems like a thread per client is NOT the way to go, because of context switching and all.
Erik van Brakel
A: 

Nope, no way to do that. TCP doesn't guarantee that everything arrives at once, thus you need to know the size of the XML to know if everything have arrived. And you don't know that. Right?

Using asynchronous methods is the way to go (and build a string with the XML)

jgauffin