How do I use the .NET NetworkStream and TcpClient to connect to a remote IP and wait for data?
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 the开发者_StackOverflow社区n 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.
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.
Do
Dim inStream(1024) As Byte
Dim recv = serverStream.Read(inStream, 0, inStream.Length)
Dim data = Encoding.GetEncoding("Windows-1252").GetString(inStream, 0, recv)
Loop While serverStream.DataAvailable
You might be interested in the BeginRead Method too.
精彩评论