Click here to Skip to main content
15,896,063 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I've pinched some code from the msdn website for tcp client class.

But it's not quite doing what I want it to do, I've played around with it to get it to pretty much work. but every 2nd job it receives it simply misses information, or doesn't get picked up at all.

When I do it locally on the computer, it works fine, but it seems doing it over the network it hits issues.

Is there anyway within this tcp class that there can be a check in place to make sure all information has been received from the sender?

Maybe there is a better way to write what I have done? I have thought about separating the tcp class into 2 separate functions. One that accepts the client, and then one that receives the information. Perhaps this is the go? I'll just need to learn how to use events etc.


VB
Private Sub tcp()
        Dim server As TcpListener
        server = Nothing

        Do

            Try

                ' Set the TcpListener on port 13000.1
                Dim port As Int32 = 22490
                Dim localAddr As IPAddress = IPAddress.Parse("192.168.1.100")

                server = New TcpListener(localAddr, port)

                ' Start listening for client requests.



                ' Buffer for reading data
                Dim bytes(1024) As Byte
                Dim data As String = Nothing
                server.Start()



                ' Enter the listening loop.
                While True

                    Dim client As TcpClient = server.AcceptTcpClient()
                    ' Perform a blocking call to accept requests.
                    ' You could also user server.AcceptSocket() here.

                    Sleep(2000)

                    data = Nothing

                    ' Get a stream object for reading and writing
                    Dim stream As NetworkStream = client.GetStream()

                    Dim i As Int32


                    i = stream.Read(bytes, 0, bytes.Length)
                    '      Sleep(2000)
                    ' Loop to receive all the data sent by the client.



                    While (i <> 0)


                        'translate data bytes to a ASCII string.

                        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)

                        'process the data sent by the client.
                        Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(data)

                        '                 stream.Read(bytes, 0, bytes.Length)

                        'send back a response.
                        stream.Write(msg, 0, msg.Length)

                        datastring = data
                        txtboxcreate(datastring, currenttb)
                        i = 0
                    End While


                    ' Shutdown and end connection

                    client.Close()


                End While


            Catch e As SocketException
            Finally

                server.Stop()
            End Try
        Loop
    End Sub 'Main
Posted
Comments
Sergey Alexandrovich Kryukov 7-Jul-14 1:52am    
This is not fair. This is what happens when you try to use code take from who-knows-where instead of writing what you really need by yourself. Why should we even look at... who knows what? The quality of this code is that bad so it does not deserve considering. And you did not explain your real goals, so this question makes little to no sense.

In all cases, you should not do anything like that. Hard-coded address (you could use IPAddress.Any; I doubt the service-part host has more than one IP addresses); the loop with Sleep — everything is unacceptable...

—SA
Mendaharin 7-Jul-14 2:04am    
What's not fair? The reason I have taken the code from MSDN is because I'm unsure of where to start when it comes to TCP, I have been able to fashion this code into something workable for myself...
I would have imagined the code coming from MSDN would be alright?

I'm learning. Show a little sympathy... The quality - blame Microsoft, stripped directly from their website --> http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener(v=vs.110).aspx ...
Sergey Alexandrovich Kryukov 7-Jul-14 2:16am    
Did you really get if from MSDN? Anyway, thank you for the reference. But I cannot imagine the code you should can be used in practice. Microsoft or not — names don't impress me, only facts...

Oh, I see what is that. Well, the code is not exactly what you are showing. I would say, it is not meant to be used in any working application. In most cases, taking some code is much less productive then writing your own. You analyze your requirements and design exactly what you need to achieve.

If you explain what exactly do you want to achieve, I'll try to help you.

—SA
Mendaharin 7-Jul-14 2:28am    
It seems as if my program is just running to quickly, before it has had a chance to receive all of the information. I've tried putting in sleep keywords, and seems to have helped a little bit. But its very intermittent when receiving the data. Sometimes it receives all, sometimes it splits the job.

I think I'm just going to have to sit here and throw a network sniffer on the network and just see exactly how it's being sent across to the program. Perhaps it's a control char somewhere closing the connection. I'm not a fan of TCP. I think I'm gonna have a look through some of the example projects and see what exactly is required... I agree with you - If I have a bit more knowledge on what some of those statements do, I will probably have a bit more of an idea as to what to try.

Sergey Alexandrovich Kryukov 7-Jul-14 2:38am    
"Running too quickly" and "sometimes" would mean race condition, a big disaster. The whole idea of depending on time of execution is totally wrong, as well as your delay. That's why I said above that the code is too bad to consider. This is not how such things are done/

No, don't do network sniffer and other shaky things. You need to decided what do you want to achieve and thoroughly plan it. Again, if you describe what do you want to achieve, I'll try to help you.

—SA

1 solution

i = stream.Read(bytes, 0, bytes.Length)
That's dangerous with TCP. Instead of returning an empty array and i=0, it may simply hang. Better find out if the end of the message has already been reached by parsing the received data, and make that result your stop criterion.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 7-Jul-14 2:40am    
Of course, but this is just one of the many detail which make the shown code 100% unacceptable.
OP needs to define some application-level protocol which establishes how a size of data should be determined; this is one of the critical elements of any protocol. But listening in the loop with the delay is also unacceptable. OP reports something which looks like race condition, but one glance at this code reveals how terrifying it is.
I voted 5 anyway.
—SA
Bernhard Hiller 8-Jul-14 2:13am    
Thanks. When I had a project with IMAP, I also started with such WTFs (slow connection to server). Over long time, several versions of the "end of message" data had to be found out (by customers reporting errors - yes, in reality, IMAP is not well defined) and the code was adjusted to them. So it would be better if the OP would tell us about the background of his work.
Sergey Alexandrovich Kryukov 8-Jul-14 2:57am    
So far, he is resisting, as you can see from our discussion in comments to the question... :-)
—SA
Mendaharin 10-Jul-14 23:46pm    
Sorry for seeming like I'm resisting. I just don't know how to put it correctly so everyone understands. I don't want to sound silly :(

It's a Kitchen Video System (Still playing around with this Sergey its been fun...)

I've got the majority of the programming working. When it receives the data it reads through for particular strings to remove, checks for particular chars to change height/font/colour of the text prior to appending to a richtextbox. Timer event for when it wants to flick to a warning colour.

The issue is the client connection (I hope that's the right word)
It always connects everything is perfect, but when it receives the data, unless I step through it I miss information. Which I believe Sergey has attributed to race condition. I have found by putting in sleep commands it does help it a little bit, but from what I'm reading this is a bad way to do it.

The easiest way to explain what I am doing is to tell you the way I'm testing I think.

Setup a windows printer driver using generic/text. This points to an I.P address and port number. At the moment, when it receives the data, it misses parts of it, it's intermittent at times.
When I'm testing on the local machine, to the loopback address it works a treat, but as soon as I use another computer to send the print job, I'm losing information.

I agree with everyone the above is incorrect - I'm trying to write something myself at the moment but as I'm still learning (I'm having a lot of trouble understanding delegates and eventhandlers etc) I'm only able to get this to work using simple things like if statements, rather than on event do xyz. Pain in the *** is my listener is in a separate thread. Once it reads through the if statement, it stops listening....
I'm trying to re-write the tcp part so everything is within a separate procedure (Listen, read, encode to ascii) and then pass the data from the encode procedure to the procedure that will put the text into a dynamically created textbox.

I truly hope this makes sense.
Mendaharin 10-Jul-14 23:50pm    
With the form that has the textboxes, these are tiled across the screen. When new data is received, it then creates a new textbox and puts that into a flowlayoutpanel.
So - with each print from your windows printer you should see a new textbox flowing to the right created with all the information received in the new textbox.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900