如何使用.NET NetworkStream和TcpClient连接到远程IP并等待数据?
我在这段代码上遇到了很大的困难,我正试图开始工作。我已成功将 TcpClient 对象连接到两台单独的远程计算机并向它们传输数据。本质上,我正在尝试连接到端口 80 上的计算机 1 并发送 GET 请求。发送请求后,我希望保持连接处于活动状态,以便另一端的软件可以在准备好时向我发送数据。如何保持连接打开并在每次流中可用时读取数据?我尝试过使用 NetworkStream.Read 和 BeginRead 但没有成功。我最接近的是每 30 秒休眠一次线程,然后执行另一个不需要的 GET 请求。这是我从流中读取的当前代码。我知道我需要在此处的某处循环:
注意:RemoteSocket 是我在这一点连接的 TcpClient 对象
Dim serverStream As NetworkStream = RemoteSocket.GetStream()
rqst = "GET /Control/Clip_Forwarding_Stream?CameraName=" & URL_Encode(Name) & " HTTP/1.0" & vbCrLf & vbCrLf
Dim stream As Byte() = Encoding.GetEncoding("Windows-1252").GetBytes(rqst)
serverStream.Write(stream, 0, stream.Length)
Dim inStream(1024) As Byte
Dim recv = serverStream.Read(inStream, 0, inStream.Length)
Dim data = Encoding.GetEncoding("Windows-1252").GetString(inStream, 0, recv)
我对数据所做的是将其传递给此方法:
注意:ForwardSocket 是我在这一点连接的另一个 TcpClient 对象
Dim serverStream As NetworkStream = ForwardSocket.GetStream()
Dim stream As Byte() = Encoding.GetEncoding("Windows-1252").GetBytes(data)
serverStream.Write(stream, 0, stream.Length)
Any示例可以使用 C# 或 VB 编写,因为我对 C# 最满意,只需用 VB 编写即可。
I am struggling a lot with this code I am trying to get to work. I have successfully made a connection with the TcpClient object to two separate remote machines and transmitted data to them. Essentially, I'm trying to connect to Machine 1 on port 80 and send a GET request. Once I send the request I want to keep the connection alive so that the software on the other side can send me data when it is ready. How do I keep the connection open and read data in each time it is made available in the stream? I have tried and tried using NetworkStream.Read and BeginRead to no avail. The closest I have come was sleeping my thread every 30 seconds and then doing another GET request which is not needed. Here is the current code I have for reading from the stream. I know I need a loop in here somewhere:
Note: RemoteSocket is my TcpClient object that is connected by this point
Dim serverStream As NetworkStream = RemoteSocket.GetStream()
rqst = "GET /Control/Clip_Forwarding_Stream?CameraName=" & URL_Encode(Name) & " HTTP/1.0" & vbCrLf & vbCrLf
Dim stream As Byte() = Encoding.GetEncoding("Windows-1252").GetBytes(rqst)
serverStream.Write(stream, 0, stream.Length)
Dim inStream(1024) As Byte
Dim recv = serverStream.Read(inStream, 0, inStream.Length)
Dim data = Encoding.GetEncoding("Windows-1252").GetString(inStream, 0, recv)
What I do with data is pass it to this method:
Note: ForwardSocket is my other TcpClient object that is connected by this point
Dim serverStream As NetworkStream = ForwardSocket.GetStream()
Dim stream As Byte() = Encoding.GetEncoding("Windows-1252").GetBytes(data)
serverStream.Write(stream, 0, stream.Length)
Any examples can be in C# or VB as I'm most comfortable with C# just had to write this all in VB.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要在循环内阅读(类似于 NoAlias 的答案)。但是你不应该只是循环直到 DataAvailable 为 false,因为如果出于争论的目的,你输入了 4K 数据,那么会有一个小暂停(网络拥塞,等等),然后另外 2K 数据输入,你就会丢失数据结束,因为在该暂停期间 DataAvailable 将为 false。
相反,您需要依赖更高级别的协议,在本例中为 HTTP。 HTTP 使用一个名为 Content-Length 的标头,它可以准确地告诉您正文中将存在多少字节。您需要循环直到收到一定数量的内容(或者当然达到超时值,除非您想永远等待)。
编辑1
再次阅读您的问题后,您似乎正在获取内容长度未知的数据。 HTTP 支持使用 multipart 分块发送数据。手动编码并不有趣,您可能需要考虑使用 HttpRequest 和 HttpResponse 类来为您处理这个问题。它仍然为您提供包含您的内容的流,但会为您处理 HTTP。
You need to read within a loop (similar to NoAlias's answer). But you should not just loop until DataAvailable is false because if, for the sake of arguement you had 4K of data come in, then there is a small pause (network congestion, whatever) and then another 2K of data came in you would loose the end of your data because DataAvailable would have been false in that pause.
Instead, you need to rely on the higher-level protocol, which in this case is HTTP. HTTP uses a header called Content-Length that will tell you exactly how many bytes will be present in the body. You need to loop until you have received that amount of content (or have reached a timeout value of course, unless you want to wait forever).
EDIT1
Upon reading your question again, it looks like you may be fetching data that has no known content length. HTTP supports sending data in chunks using multipart. This isn't fun to hand-code, you may want to look at using HttpRequest and HttpResponse classes instead to handle this for you. It still makes available to you a stream with your content but deals with HTTP for you.
您可能对 BeginRead 感兴趣方法也。
You might be interested in the BeginRead Method too.