9 Replies - 401 Views - Last Post: 19 April 2013 - 07:10 AM Rate Topic: -----

#1 DorZ11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 11-April 13

Deserialize stuck when Im trying to change the thread.sleep

Posted 17 April 2013 - 09:00 PM

So in my final project I need to do unit testing to a client server tcp and in one of the tests im trying to send from client #1 to #2 same amount of messages with different range of time between the messages (my teacher ask it for me*)

when I put a variable in the thread.sleep, its send the messages but I dont recieve them from client #2, but when I put a fixed variable its work well
the send code:
try
            {

                testsArrTimeArrived = new double[1200];
                tcpObject.Command = Command.Test2;
                tcpObject.Source = 1;
                tcpObject.Destination = 2;
                byte[] junkMsg = new byte[10000];
                tcpObject.Data = junkMsg;
                sleepTime = 200;

                //Reset the avgTestsArrTimeArrived array
                for (int i = 0; i < avgTest1ArrTimeArrived.Length; i++)
                    avgTest1ArrTimeArrived[i] = 0;

                for (indexBetweenTheMessages = 1; indexBetweenTheMessages <= 5; indexBetweenTheMessages++)
                {
                    
                    for (numberOfTheMessages = 1; numberOfTheMessages <= 100; numberOfTheMessages++)
                    {
                        if (numberOfTheMessages == 100)
                        {
                            tcpObject.exactTime = 1;
                            sleepTime += 200;
                        }
                        else
                        {
                            tcpObject.exactTime = exactTime.ExactTime();
                        }
                        tcpObject.IDString = randomString();
                        WorkClient.Send(tcpObject);
                        Thread.Sleep(sleepTime);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


now its really weird problem, when I put the Thread.Sleep(sleepTime); in the code, client num 2 dont recieve, but when I put for example Thread.Sleep(200), its work.

***even when im not change the sleepTime and its allways on 200 still it isnt work.

***the server recieve and send the messages, its the client #2 that dont recieve them.

now for some of the codes:

the tcpObject:
    [Serializable] // can be sent over the network
    public enum Command
    {
        Login,
        Logout,
        Test1,
        Test2,
        Test3,
        Test4,
        Finish,
        Success,
        Null,
    }

    [Serializable]
    public class TcpObject
    {
        public Command Command { set; get; }
        public int Source { set; get; }
        public int Destination { set; get; }
        public double exactTime { set; get; }
        public Object Data { set; get; }
        public String IDString { set; get; }


        public TcpObject()
        {
            Command = Command.Null;
            Data = null;
        }

    
    }


the listener of client num2
while (Connected)
                {
                    TcpObject tcpObject = new TcpObject();
                    IFormatter formatter = new BinaryFormatter();
                    tcpObject = (TcpObject)formatter.Deserialize(ServerSocket);

                    //get the remainder of the time that the message got send and when the message got accepted.
                    double remainderTime = exactTime.ExactTime() - tcpObject.exactTime;
                    
                    Thread t3 = new Thread(() => Client2HandleMessages(tcpObject, remainderTime));
                    t3.Start();
                     

                }


the client handler of client num2:
public void Client2HandleMessages(TcpObject tcpObject, double remainderTime)
        {
            TcpObject succeedTcpObject = new TcpObject();
            succeedTcpObject.IDString = tcpObject.IDString;
            succeedTcpObject.Source = 2;
            succeedTcpObject.Destination = 1;
            Thread.Sleep(100);
            switch (tcpObject.Command)
            {
                    
               case Command.Test2:
                    if (tcpObject.exactTime == 1)
                    {
                        succeedTcpObject.Command = Command.Test2;
                        succeedTcpObject.exactTime = 1;
                        WorkClient.Send(succeedTcpObject);
                    }
                    else
                    {
                        succeedTcpObject.Command = Command.Test2;
                        succeedTcpObject.exactTime = remainderTime;
                        WorkClient.Send(succeedTcpObject);
                    }



now as I said I dont get into the client handler because I even dont recieve the messages..

here's the server listen:
public void Start()
    {
        running = true;

        serverSocket.Start();
        Console.WriteLine("Server has started.");

        while (running)
        {
            clientSocket = serverSocket.AcceptTcpClient();
                clientsList.Add(255, clientSocket); // add one value for the protocol and delete it afterwards

            Thread handleClient = new Thread(
                new ParameterizedThreadStart(HandleClient));
            handleClient.Start(clientSocket);
        }
    }



client handler of the server:
private void HandleClient(object tcpClient)
    {
        TcpClient tc = (TcpClient)tcpClient;
        try
        {
            while (clientsList.ContainsValue(tc))
            {
                NetworkStream networkStream = tc.GetStream();
                IFormatter formatter = new BinaryFormatter();
                TcpObject tcpObject = (TcpObject)formatter.Deserialize(networkStream);

                switch (tcpObject.Command)
                {
                    case Command.Login:
                            clientsList.Remove(255);
                        clientsList.Add(tcpObject.Source, tc);
                        connectedClients++;
                        Console.WriteLine(tcpObject.Source + " connected!");
                        break;
                    case Command.Logout:
                        foreach (var client in clientsList)
                        {
                            if (client.Value.Equals(tc))
                            {
                                Console.WriteLine("Client: " + client.Key + " Disconnected");
                                clientsList.Remove(client.Key);
                                break;
                            }
                        }
                        break;

                    default:
                        Console.WriteLine("Source: " + tcpObject.Source + " time: " + tcpObject.exactTime);
                        Thread message = new Thread(new ThreadStart(delegate
                        {
                            try
                            {
                                foreach (var client in clientsList)
                                {
                                    if (client.Key.Equals(tcpObject.Destination))
                                    {
                                        IFormatter newFormatter = new BinaryFormatter();
                                        newFormatter.Serialize(client.Value.GetStream(), tcpObject);

                                    }
                                }
                            }
                            catch (Exception ex) { Console.WriteLine(ex); }
                        }));
                        message.Start();
                        break;


                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            foreach (var client in clientsList)
            {
                if (client.Value.Equals(tc))
                {
                    clientsList.Remove(client.Key);
                    break;
                }
            }
        }
    }


thanks for advance!

This post has been edited by DorZ11: 17 April 2013 - 09:11 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Deserialize stuck when Im trying to change the thread.sleep

#2 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5675
  • View blog
  • Posts: 12,192
  • Joined: 02-June 10

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 18 April 2013 - 06:11 AM

Quote

when I put a variable in the thread.sleep, its send the messages but I dont recieve them from client #2,


Right. The thread is asleep. It doesn't do anything. Nothing. The command is thread.sleep not thread.WaitButStillRespondToEventsAndMessages

The simplest rule is: Don't use thread.sleep. Period. Don't use it. It is the most mis-understood and over-misused command I can think of.
If you are using it then you have a bad design. Period. C# is event driven. Don't sleep your threads. Respond to events. If there are no events your program should be sitting their idling at full speed just waiting for something to do. You certainly should never be sleeping threads used for communication. You program is literally asleep when the message comes in.
Was This Post Helpful? 1
  • +
  • -

#3 DorZ11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 11-April 13

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 18 April 2013 - 09:44 AM

hi there!
thanks for trying to help me but I need the project to be ready in 3days and I cant change it all now..
the basic of this test is that I need to send same amount of messages everytime but with different of the time range between the amount of the messages and the another one.. is there a easier way to do it?
Was This Post Helpful? 0
  • +
  • -

#4 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5675
  • View blog
  • Posts: 12,192
  • Joined: 02-June 10

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 18 April 2013 - 10:12 AM

Quote

thanks for trying to help me but I need the project to be ready in 3days and I cant change it all now..

Sorry to hear that you are completely boned on this project.

Quote

is there a easier way to do it?

Give up thinking in terms of easier and harder when it comes to coding. There is really only right and wrong. Planned well or not.
There isn't some magic trick to take a badly designed application and make it work like it was done correctly.

What you are left with is buying a lot of caffine and working straight through for the next 3 days to get it built the way it has to be architected to get the job done.

This is a prime example for the numerous times we try to beat into rookies to plan, plan some more, then plan again before they start banging on the keyboards. It is however a terrific learning experience and that what your time in school is for. Painting yourself into a corner is part of the learning process and I'm sure you've learned enough from this to not do it again.
Was This Post Helpful? 0
  • +
  • -

#5 DorZ11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 11-April 13

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 18 April 2013 - 10:44 AM

well u right I did learn a lot from this project but I wont start all over again in 3 days..ill just pass this test I got more 3 to go I prefer to get 55/100 than fail..I still dont get it why its not working when I put variable can u explain me please in another way so I will? thank you very much ur awesome and really good guy!

This post has been edited by DorZ11: 18 April 2013 - 10:44 AM

Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3662
  • View blog
  • Posts: 11,466
  • Joined: 05-May 12

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 18 April 2013 - 04:40 PM

View PosttlhIn`toq, on 18 April 2013 - 01:12 PM, said:

There isn't some magic trick to take a badly designed application and make it work like it was done correctly.


Very very true. There are techniques like refactoring that give you half a chance. Sometimes, though, if the basic design or algorithm is all wrong and everything is written with very tight coupling, it actually takes less time to start over than try to refactor the code.
Was This Post Helpful? 0
  • +
  • -

#7 DorZ11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 11-April 13

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 18 April 2013 - 04:51 PM

Very very true. There are techniques like refactoring that give you half a chance. Sometimes, though, if the basic design or algorithm is all wrong and everything is written with very tight coupling, it actually takes less time to start over than try to refactor the code.

If I knew how to build again with good basic design I would, but I dont know how.. thats the only way I know how to build server client

This post has been edited by tlhIn`toq: 19 April 2013 - 08:35 AM

Was This Post Helpful? 0
  • +
  • -

#8 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3662
  • View blog
  • Posts: 11,466
  • Joined: 05-May 12

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 18 April 2013 - 09:33 PM

As mentioned before, C# and the .NET Framework is targeted for writing event driven asynchronous code. You are already doing some multi threading. You may need to do a little bit more asynch programming.

One thing that you could do is change:
tcpObject = (TcpObject)formatter.Deserialize(ServerSocket);


where the Deserialize() call is doing a blocking call on the the ServerSocket stream. (Terrible name for a variable, BTW. It's a stream, not a socket -- you should name it as such.) You could call Stream.BeginRead(). In your callback for BeginRead(), that is where you would pass in the actual bytes read to Deserialize().

Still that doesn't really fix anything with your broken design with the Sleep() calls. You could have used timers easily. You should have been using a send queue. With some extra ingenuity, I think there is also a way to do things with wait handles.
Was This Post Helpful? 0
  • +
  • -

#9 DorZ11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 11-April 13

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 19 April 2013 - 05:29 AM

...quote removed...

well, I allready solve it by my self.. I just did tests and when I tryed to put thread.sleep before the loops its worked for me dont know why.. really wierd
anyway can u explain me why my basic design is bad?

This post has been edited by Skydiver: 19 April 2013 - 06:56 AM
Reason for edit:: Removed quote. When responding to a message that is directly above yours, do not use quotes.

Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3662
  • View blog
  • Posts: 11,466
  • Joined: 05-May 12

Re: Deserialize stuck when Im trying to change the thread.sleep

Posted 19 April 2013 - 07:10 AM

Congratulations on finding another band-aid fix.

As pointed out above by tlhIn`toq, using Sleep() in the middle of your code typically a bad idea. If you need to pick up an operation later, use a timer event. If you need to wait for a response, use an event or the asynchronous versions of blocking methods. Since you are using writing a console app, the effects of calling Sleep() is not obvious, but if you made it a GUI app, suddenly your program will look/feel "laggy".

Spoiler


Your design is very brittle as you've obviously discovered. If things working correctly is very dependent on whether you sleep before vs. after you send a message or expect to receive a message, it's an indicator that something is incorrect. What happens if your server suddenly decides to not wait 100 ms before sending a reply? What happens if the server waits 5 minutes and then sends all the replies back in one big batch? What happens if your are sending across the real network instead of the loopback on your machine and there is a 1 second latency?
Was This Post Helpful? 2
  • +
  • -

Page 1 of 1