Simulating Internet Lag
Hi gang,
I have a working server (IOCP) and client (asynchronous sockets) system that is working well. I can run the server and client on my machine and everything works fine.
In many instances, though, when the client is run on a remote machine, there are problems. Inevitably, these problems are related to lag, and the fact that stale packets are arriving and screwing things up.
For instance:
Client sends news request packet
No response from server for > 1 second
Client sends news request packet
Server (belatedly) gets first request and sends out news packet
Client gets news packet and displays. Moves on to the next task.
Server gets the second news request and sends out news packet
Client gets news packet again. Because it has already moved on, this can sometimes cause the program to go wonky.
Now, I''m catching these sorts of things as I get reports about them, one by one. They''re not hard to fix, but there are so many ways for this sort of thing to happen, I need a better solution.
So, is there any way to simulate a lag effect so I can see these problems first hand before they go out to testers? I can think of one or two possibilities, but they require some pretty serious modifications to the server and client systems. It would be nice if I could turn on and off the simulated lag easily.
Any advice?
-Ron
Creation is an act of sheer will
Why not put some code in at the receiver that puts the messages in a queue, delayed by a random amount of time?
I once wrote a few classes that simulated internet lag.
One class held a linked list of packets that simulated the packets that were currently on their way to their destination.
I also had a class that simulated a sender and a receiver, with a linked list of received packets.
The internet class would take a sent packet and insert it into its linked list, and arriving packets would be inserted into the client's receive packets.
When a packet is sent, I immediately calculate its arrival time, whether or not the packet will arrive at all, a random huge lag spike, or even being sent multiple times (rare, but possible). One other possibility that I did not account for was the packet becoming garbled.
The variables for each client are connection speed and connection reliability.
It was a nice way to code for stability without needing an actual internet connection. I was hoping to have two client screens that showed the effects of lag from one to the other, but I never got that far.
That example allows simulation of lag with a program and communicates only with itself.
I don't know of any way of simulating internet lag over a LAN or on the same machine between two separate processes unless you have a mediating forwarding program that affects the arrival time of the packets for you.
rypyr's solution would work, too.
[edited by - Waverider on August 23, 2003 1:37:42 PM]
One class held a linked list of packets that simulated the packets that were currently on their way to their destination.
I also had a class that simulated a sender and a receiver, with a linked list of received packets.
The internet class would take a sent packet and insert it into its linked list, and arriving packets would be inserted into the client's receive packets.
When a packet is sent, I immediately calculate its arrival time, whether or not the packet will arrive at all, a random huge lag spike, or even being sent multiple times (rare, but possible). One other possibility that I did not account for was the packet becoming garbled.
The variables for each client are connection speed and connection reliability.
It was a nice way to code for stability without needing an actual internet connection. I was hoping to have two client screens that showed the effects of lag from one to the other, but I never got that far.
That example allows simulation of lag with a program and communicates only with itself.
I don't know of any way of simulating internet lag over a LAN or on the same machine between two separate processes unless you have a mediating forwarding program that affects the arrival time of the packets for you.
rypyr's solution would work, too.
[edited by - Waverider on August 23, 2003 1:37:42 PM]
It's not what you're taught, it's what you learn.
I would recommend that if your client is asking for the updates to have it send a unique identifier such as client number and request number and then have the server send back the same number. This way both would be able to sync with each other about the item. Remember when going over a network though... always try to keep things a small as possible. A single char would be enough for the machine, and maybe a int for the request number.
My name is my sig.
You could play tricks with your apps'' use of Winsock and delay and remove packets with an LSP (Layered Service Provider), something that sits between your apps and the real Winsock. I think this is how DP8SIM.DLL, the DirectPlay simulator does it. Maybe there are commercial LSPs out there that do this already ?
Packet Filtering with iphlpapi.dll, Windows Developer''s Journal, Ton Plooy, Windows Developers Journal, October, 2000, Volume 11, Number 10.
-cb
Packet Filtering with iphlpapi.dll, Windows Developer''s Journal, Ton Plooy, Windows Developers Journal, October, 2000, Volume 11, Number 10.
-cb
One of the easiest ways I can think of handling this would be to keep a simple running track of all packets sent and recieved.
For instance, client sends a packet that it expects rsponse from. Tag an extra field onto this one (a char or short int or something small). Keep track of that number. On the receiver side, if you recieve a packet that the client expects direct input from then you mark the packet number (probably the time sent). This way you can just ignore many duplicate packets if you know they have already been handled.
I''m using this kind of system and it seems to be working now. I have a small lan that it''s running on and the server with a few clients have been running for a few hours now. I''m currently servicing 6.4 millionth+ packets and counting. Granted, it''s not a full blown application and other problems may arise but so far it''s working quite well.
What I am doing is comparing the IP address when I recieve and the stamp. If it''s a combination that I have already handled then I decide what to do. If its the final packet in the system then I just ignore it. If it''s something that keeps getting sent by the other side because it''s awaiting a response then obviously the first response was never received so I just send the response again. If the old responses arrive later (at least within a reasonable time period) then they just get dumped and ignored.
Also, the client and server both are aware of a state so if for instance the client recieves a very old "trade executed" and it doesn''t currently have any open trades in waiting then the packet is simply ignored.
Works fine so far.
Webby
For instance, client sends a packet that it expects rsponse from. Tag an extra field onto this one (a char or short int or something small). Keep track of that number. On the receiver side, if you recieve a packet that the client expects direct input from then you mark the packet number (probably the time sent). This way you can just ignore many duplicate packets if you know they have already been handled.
I''m using this kind of system and it seems to be working now. I have a small lan that it''s running on and the server with a few clients have been running for a few hours now. I''m currently servicing 6.4 millionth+ packets and counting. Granted, it''s not a full blown application and other problems may arise but so far it''s working quite well.
What I am doing is comparing the IP address when I recieve and the stamp. If it''s a combination that I have already handled then I decide what to do. If its the final packet in the system then I just ignore it. If it''s something that keeps getting sent by the other side because it''s awaiting a response then obviously the first response was never received so I just send the response again. If the old responses arrive later (at least within a reasonable time period) then they just get dumped and ignored.
Also, the client and server both are aware of a state so if for instance the client recieves a very old "trade executed" and it doesn''t currently have any open trades in waiting then the packet is simply ignored.
Works fine so far.
Webby
In all cases where you want to simulate non-normal behaviour in a network i recommend (by own experience) Nistnet - http://snad.ncsl.nist.gov/itg/nistnet/
It isn''t the easiest to setup, but it gives you a very easy way to simulate stuff like package loss, out of order delivery, lag etc etc etc.. very handy
-Mårten
It isn''t the easiest to setup, but it gives you a very easy way to simulate stuff like package loss, out of order delivery, lag etc etc etc.. very handy
-Mårten
Thanks guys, interesting ideas. Of the bunch, I guess rypyr is the most readily codable. It was along the ideas I was thinking anyway ![](smile.gif)
My packets are already stored in a queue as they are recieved, in a "to be processed" sort of scheme. I suppose I could simply throw a random timer offset value into them and not process them until the time has expired. That should give me out of order packets, repeat requests, and all the lag induced effects I am looking for.
I suppose I should use conditional compiling for implementing the lag simulator, as I don''t want any extra artificial delays in code that goes out, I only want it for internal testing![](smile.gif)
As it turns out I corrected two more of these issues today, and I''ve gotten reports that all is now working well. Yay. I''m sure the issue will pop up again, though, before all the coding is said and done.
![](smile.gif)
My packets are already stored in a queue as they are recieved, in a "to be processed" sort of scheme. I suppose I could simply throw a random timer offset value into them and not process them until the time has expired. That should give me out of order packets, repeat requests, and all the lag induced effects I am looking for.
I suppose I should use conditional compiling for implementing the lag simulator, as I don''t want any extra artificial delays in code that goes out, I only want it for internal testing
![](smile.gif)
As it turns out I corrected two more of these issues today, and I''ve gotten reports that all is now working well. Yay. I''m sure the issue will pop up again, though, before all the coding is said and done.
Creation is an act of sheer will
Sleep(100);
Sleeps for 100 miliseconds... This would create quite a lag in your program.
Sleeps for 100 miliseconds... This would create quite a lag in your program.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement