如何将NetworkStream与TcpClient一起使用 [英] How do I use NetworkStream with TcpClient

查看:101
本文介绍了如何将NetworkStream与TcpClient一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

各位大家好,我在网络编码方面非常棒。

我的想法:

- 客户端向服务器发送请求

- 服务器接收,做某事并回复客户

- 客户收到回复并做一些事情

我建立服务器和客户端如下



我的服务器

Hello everyone, I'm totally noob in network coding.
My idea on this:
- Client send request to server
- Server receive, do something and response to client
- Client receive response and do something
I build server and client as below

My server

_tcpListener = new TcpListener(localEndPoint);
_tcpListener.Start(10);
// Data buffer for incoming data.
            int buffer = 1024;
            byte[] bytes = new Byte[buffer];

            // Start listening for connections.
            while (true)
            {
                TcpClient client = _tcpListener.AcceptTcpClient();

                Console.WriteLine(string.Format("Connection from :{0}", client.Client.RemoteEndPoint.ToString()));

                try
                {
                    using (NetworkStream ns = client.GetStream()) //networkstream is used to send/receive messages
                    {
                        List<byte> requestedBytes = new List<byte>();
                        while (client.Connected)  //while the client is connected, we look for incoming messages
                        {
                            bytes = new byte[buffer];

                            int bytesRec = ns.Read(bytes, 0, bytes.Length);
                            if (bytesRec == 0)
                                break;

                            Console.WriteLine("Data received: " + bytesRec);

                            requestedBytes.AddRange(bytes.ToList().Take(bytesRec));
                        }

                        Console.WriteLine("Data length: " + requestedBytes.Count.ToString("N0"));

                        if (NeedResponseBytes == null) // a delegate for object which use this listener to do some business
                            throw new Exception("NeedResponseBytes is not handled.");

                        // Receive byte content
                        byte[] responseBytes = NeedResponseBytes(requestedBytes.ToArray());

                        ns.Write(responseBytes, 0, responseBytes.Length);
                        ns.Flush();
                    }
                }
                catch { }

                client.Close();
            }
        }





和我的客户:





and My client:

IPEndPoint remoteEP = new IPEndPoint(ipAddress, _port);
            List<byte> responseBytes = new List<byte>();

            using (TcpClient client = new TcpClient())
            {
                client.Connect(remoteEP);
                using (NetworkStream stream = client.GetStream())
                {
                    // Send data to server
                    stream.Write(requestBytes, 0, requestBytes.Length);
                    stream.Flush();

                    // Read data from 
                    while (true)
                    {
                        byte[] buffer = new byte[1024];
                        int bytesRec = stream.Read(buffer, 0, 1024);
                        if (bytesRec == 0)
                        {
                            break;
                        }

                        responseBytes.AddRange(buffer.Take(bytesRec));
                    }
                }
            }





我的问题是客户来电后



And my problem is after client calls

stream.Flush();



服务器仍然继续从流中读取数据。



我试图将我的客户端代码更改为使用BinaryWriter(在一个使用块中)和BinaryReader(在另一个使用块中),例如


server still continues to read data from stream.

I tried to change my client code to using BinaryWriter (in one using-block) and BinaryReader (in another using-block), like

using (NetworkStream stream = client.GetStream())
{
    using(BinaryWriter writer = new BinaryWriter(stream))
    { .... write request and flush here .... }

    using(BinaryReader reader = new BinaryReader(stream))
    { .... read response here .... }
}





但是在部署NetworkStream时我无法使用BinaryReader。此外,我无法在服务器上进行太多更改,因为它与我的队友在java中的客户端完美配合,使用OutputStream和InputStream。我已经坚持了这个问题大约1天。



but I cannot using BinaryReader when NetworkStream is disposed. Moreover, I cannot change too much on server because that works perfectly with my teammate's client in java, using OutputStream and InputStream. I've got stuck on this problem for about 1 day.

推荐答案

请看我对这个问题的评论。显然,对于网络流,此方法不执行任何操作:

https://msdn.microsoft.com/en-us/library/system.io.stream.flush%28v=vs.110%29.aspx ,<无线电通信/>
https: //msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.flush%28v=vs.110%29.aspx

我无法想象为什么你会不会需要它用于网络流。为什么你会停止从流中读取数据?是什么让你觉得它可能与你可能误解的 Flush 相关?无需回答。



我知道您需要在服务和客户端之间实现灵活的通信逻辑,而不仅仅是交换固定大小的数据结构。但是这个问题通过应用层协议的设计得以解决。一个常见的错误是忽略了这样的事实,即即使在最自定义的网络应用程序上,这样的协议也总是存在,因此最好实现这一事实并有意识地设计这样的协议并在代码中明确表达它。在一些简单的情况下,协议可以发送一个固定大小的标题数据结构,允许其他通信方计算应该读取多少字节数据来获得其余数据。



另请参阅:

http://en.wikipedia.org/wiki/Transmission_Control_Protocol

http://en.wikipedia.org/wiki/Application_layer



-SA
Please see my comment to the question. Apparently, for a network stream, this method does nothing:
https://msdn.microsoft.com/en-us/library/system.io.stream.flush%28v=vs.110%29.aspx,
https://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.flush%28v=vs.110%29.aspx.
I cannot imagine why would you ever need it for a network stream. Why would you stop reading data from stream and what makes you thinking that it can possibly be related to Flush which you might have misunderstood? No need to answer.

I understand that you need to implement flexible communication logic between the service and clients, not just exchange of the fixed-size data structure. But this problem is resolved by the design of your application-layer protocol. One common mistake is ignoring the fact that such protocol always virtually exist even on the most custom network applications, so it's better to realize this fact and consciously design such protocol and explicitly express it in your code. In some simple cases, the protocol can send a fixed-size "header" data structure which allows the other communicating side to calculate how much bytes of data should be read to get the rest.

See also:
http://en.wikipedia.org/wiki/Transmission_Control_Protocol,
http://en.wikipedia.org/wiki/Application_layer.

—SA


这篇关于如何将NetworkStream与TcpClient一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆