如何从网络流中同步读取数据?

发布于 2024-07-15 23:41:54 字数 406 浏览 7 评论 0原文

我想用C#从网络流中读取数据。

我有一个定期轮询的客户端列表,但是当我开始从一个客户端读取数据时,我必须读取整个 xml 消息,然后继续读取下一个客户端。 如果接收数据有一些延迟,我不应该去下一个客户端。 我应该等待一段时间并获取数据。 而且,我不应该无限期地等待。 只需超时并在 x 秒后继续处理下一个客户端...

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# 中优雅地执行此操作?

I want to read data from network stream in C#.

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 shouldn't 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 a way to to do this elegantly in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

飘过的浮云 2024-07-22 23:41:54

据我所知,没有办法做到这一点,所以你很可能最终会使用多个线程。 恕我直言,每个客户端使用一个线程首先是一个更干净的解决方案,然后您只需在流上调用 Read() 即可,并且可以根据需要花费多长时间,而其他线程正在为其他客户端执行相同的操作。

线程一开始可能有点可怕,特别是如果您使用 Windows 窗体(到处都是代理!)而不是控制台应用程序,但它们非常有用。 如果使用得当,它们可以提供很大帮助,尤其是在网络领域。

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.

丑疤怪 2024-07-22 23:41:54
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上的“同步客户端套接字示例”)

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)

猫瑾少女 2024-07-22 23:41:54

不,没有办法做到这一点。 TCP 不保证所有内容立即到达,因此您需要知道 XML 的大小才能知道所有内容是否都已到达。 而你不知道这一点。 正确的?

使用异步方法是可行的方法(并使用 XML 构建字符串)

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文