Jump to content
  • Advertisement
Sign in to follow this  
FantasyVI

sending packet 6300 times every second !

This topic is 2425 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[size="5"]Old post ---- scroll down to my last post #13

Hello everyone

I'm a network newbie and not long ago i started learning Winsock.

anyways I have a structer that contain player X and Y position and and this structure is being send from the server to the client 6300 times every second. I tried to send it 60 times every second but there was a 1 sec delay from when I pressed Up key to move in the server side till the client respond and moved up.

I had to send the packet 6300 time so there would be no delay. I was just wounding isn't that a bit high. I read that sending packet 200times every second was enough. if that is true then why do I need to send my packet 6300 times ever second for it to not have any delay ?

Server Code:-

#include "Networking.h"
#include "Player.h"

struct PlayerMovment {
int PlayerXPos;
int PlayerYPos;
};

PlayerMovment PlayerPos;
Player P;

Networking::Networking()
{
SendSocket = INVALID_SOCKET;
Port = 27015;
P.SetPosition();
}

Networking::~Networking()
{
}

void Networking::NetworkPlayerPosition(sf::RenderWindow &Window)
{
P.Movment(Window);
PlayerPos.PlayerXPos = P.GetPlayerX();
PlayerPos.PlayerYPos = P.GetPlayerY();
}

void Networking::Init()
{
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
wprintf(L"WSAStartup failed with error: %d\n", iResult);

SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SendSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
}
}

void Networking::SendData()
{
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

//wprintf(L"Sending data...");
iResult == sendto(SendSocket, (char*)&PlayerPos, sizeof(PlayerPos), 0, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));

if (iResult == SOCKET_ERROR) {
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
closesocket(SendSocket);
WSACleanup();
}
}

void Networking::CloseSocket()
{
wprintf(L"Finished sending. Closing socket.\n");
iResult = closesocket(SendSocket);

if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
WSACleanup();
}
}

void Networking::CleanUp()
{
wprintf(L"Exiting.\n");
WSACleanup();
}



Main Server Code:-

#include "Networking.h"
#include "Player.h"

int main()
{
Networking N;
Player P;

sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Network Test with SFML");

N.Init();

P.LoadFile();
P.SetPosition();
sf::Clock Clock;

while (Window.IsOpened())
{
sf::Event Event;
Window.SetFramerateLimit(60);
float ElapsedTime = Window.GetFrameTime();
while (Window.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
Window.Close();
}
N.NetworkPlayerPosition(Window);
int Timer = Clock.GetElapsedTime();

for(int i = 0; i<100; i++)
{
N.SendData(); // sending data 100times * 63FPS = 6300 times every second
}


P.Movment(Window);

Window.Clear();
P.Draw(Window);
Window.Display();
}
N.CloseSocket();
N.CleanUp();
return 0;
}


/----------------------------------------------

Client Code:-

#include "Networking.h"

struct PlayerMovment {
int PlayerXPos;
int PlayerYPos;
};

PlayerMovment PlayerPos;

Networking::Networking()
{
iResult = 0;
Port = 27015;
SenderAddrSize = sizeof (SenderAddr);
}

Networking::~Networking()
{
}

void Networking::Init()
{
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error %d\n", iResult);
}

RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error %d\n", WSAGetLastError());
}
}

void Networking::Bind()
{
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);

iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));

if (iResult != 0) {
wprintf(L"bind failed with error %d\n", WSAGetLastError());
}
}

void Networking::RcevData()
{
//wprintf(L"Receiving datagrams...\n");

iResult = recvfrom(RecvSocket, (char*)&PlayerPos, sizeof(PlayerPos), 0, (SOCKADDR *) & SenderAddr, &SenderAddrSize);

if (iResult == SOCKET_ERROR) {
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
}
}

void Networking::CloseSocket()
{
wprintf(L"Finished receiving. Closing socket.\n");
iResult = closesocket(RecvSocket);

if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
}
}

void Networking::CleanUp()
{
wprintf(L"Exiting.\n");
WSACleanup();
}

int Networking::GetPlayerX()
{
return PlayerPos.PlayerXPos;
}

int Networking::GetPlayerY()
{
return PlayerPos.PlayerYPos;
}


Main Client Code:-

#include "Networking.h"
#include "Player.h"

int main()
{
Networking N;
Player P;

sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Network Test with SFML");

N.Init();
N.Bind();

P.LoadFile();

while (Window.IsOpened())
{
sf::Event Event;
Window.SetFramerateLimit(60);
while (Window.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
Window.Close();
}

for(int i = 0; i<100; i++)
{
N.RcevData(); // receving data 100times * 63FPS = 6300 times every second
}

P.SetPosition(N.GetPlayerX(), N.GetPlayerY());
Window.Clear();
P.Draw(Window);
Window.Display();
}
N.CloseSocket();
N.CleanUp();
return 0;
}

Share this post


Link to post
Share on other sites
Advertisement

Hello everyone

I'm a network newbie and not long ago i started learning Winsock.

anyways I have a structer that contain player X and Y position and and this structure is being send from the server to the client 6300 times every second. I tried to send it 60 times every second but there was a 1 sec delay from when I pressed Up key to move in the server side till the client respond and moved up.

I had to send the packet 6300 time so there would be no delay. I was just wounding isn't that a bit high. I read that sending packet 200times every second was enough. if that is true then why do I need to send my packet 6300 times ever second for it to not have any delay ?

Server Code:-

#include "Networking.h"
#include "Player.h"

struct PlayerMovment {
int PlayerXPos;
int PlayerYPos;
};

PlayerMovment PlayerPos;
Player P;

Networking::Networking()
{
SendSocket = INVALID_SOCKET;
Port = 27015;
P.SetPosition();
}

Networking::~Networking()
{
}

void Networking::NetworkPlayerPosition(sf::RenderWindow &Window)
{
P.Movment(Window);
PlayerPos.PlayerXPos = P.GetPlayerX();
PlayerPos.PlayerYPos = P.GetPlayerY();
}

void Networking::Init()
{
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
wprintf(L"WSAStartup failed with error: %d\n", iResult);

SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SendSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
}
}

void Networking::SendData()
{
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

//wprintf(L"Sending data...");
iResult == sendto(SendSocket, (char*)&PlayerPos, sizeof(PlayerPos), 0, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));

if (iResult == SOCKET_ERROR) {
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
closesocket(SendSocket);
WSACleanup();
}
}

void Networking::CloseSocket()
{
wprintf(L"Finished sending. Closing socket.\n");
iResult = closesocket(SendSocket);

if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
WSACleanup();
}
}

void Networking::CleanUp()
{
wprintf(L"Exiting.\n");
WSACleanup();
}



Main Server Code:-

#include "Networking.h"
#include "Player.h"

int main()
{
Networking N;
Player P;

sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Network Test with SFML");

N.Init();

P.LoadFile();
P.SetPosition();
sf::Clock Clock;

while (Window.IsOpened())
{
sf::Event Event;
Window.SetFramerateLimit(60);
float ElapsedTime = Window.GetFrameTime();
while (Window.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
Window.Close();
}
N.NetworkPlayerPosition(Window);
int Timer = Clock.GetElapsedTime();

for(int i = 0; i<100; i++)
{
N.SendData(); // sending data 100times * 63FPS = 6300 times every second
}


P.Movment(Window);

Window.Clear();
P.Draw(Window);
Window.Display();
}
N.CloseSocket();
N.CleanUp();
return 0;
}


/----------------------------------------------

Client Code:-

#include "Networking.h"

struct PlayerMovment {
int PlayerXPos;
int PlayerYPos;
};

PlayerMovment PlayerPos;

Networking::Networking()
{
iResult = 0;
Port = 27015;
SenderAddrSize = sizeof (SenderAddr);
}

Networking::~Networking()
{
}

void Networking::Init()
{
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error %d\n", iResult);
}

RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error %d\n", WSAGetLastError());
}
}

void Networking::Bind()
{
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);

iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));

if (iResult != 0) {
wprintf(L"bind failed with error %d\n", WSAGetLastError());
}
}

void Networking::RcevData()
{
//wprintf(L"Receiving datagrams...\n");

iResult = recvfrom(RecvSocket, (char*)&PlayerPos, sizeof(PlayerPos), 0, (SOCKADDR *) & SenderAddr, &SenderAddrSize);

if (iResult == SOCKET_ERROR) {
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
}
}

void Networking::CloseSocket()
{
wprintf(L"Finished receiving. Closing socket.\n");
iResult = closesocket(RecvSocket);

if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
}
}

void Networking::CleanUp()
{
wprintf(L"Exiting.\n");
WSACleanup();
}

int Networking::GetPlayerX()
{
return PlayerPos.PlayerXPos;
}

int Networking::GetPlayerY()
{
return PlayerPos.PlayerYPos;
}


Main Client Code:-

#include "Networking.h"
#include "Player.h"

int main()
{
Networking N;
Player P;

sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Network Test with SFML");

N.Init();
N.Bind();

P.LoadFile();

while (Window.IsOpened())
{
sf::Event Event;
Window.SetFramerateLimit(60);
while (Window.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
Window.Close();
}

for(int i = 0; i<100; i++)
{
N.RcevData(); // receving data 100times * 63FPS = 6300 times every second
}

P.SetPosition(N.GetPlayerX(), N.GetPlayerY());
Window.Clear();
P.Draw(Window);
Window.Display();
}
N.CloseSocket();
N.CleanUp();
return 0;
}



Don't recieve data a fixed number of times per frame, recieve all packets that are pending each frame instead (on both client and server), otherwise you run the risk of flooding the buffer if the framerate drops and send the data once per frame on both aswell, (Sending the same data 100 times per frame is pointless).

To hide the latency you should allow the client to move as soon as it presses the button, other players will lag behind slightly but if you stop flooding the buffers it will only be a few milliseconds.

Share this post


Link to post
Share on other sites
thank you for the replay.

as i said i'm a network newbie :D and i just have few more questions.


recieve all packets that are pending each frame instead (on both client and server),


how do i do that exacly ?


otherwise you run the risk of flooding the buffer if the framerate drops and send the data once per frame on both aswell

i didn't understand you. Can you please explain it more.


To hide the latency you should allow the client to move as soon as it presses the button

how do i do that too ?

sorry i know that I'm asking way too much but i really don't know that much about network programing.
thank you

Share this post


Link to post
Share on other sites
It seems that you are truly sending the same data 100 times per iteration and receiving the same data 100 times per iteration and finally you set the position just once per iteration. This doesn't make sense.

Probably your networking API waits a certain buffer to get full before sending it. It may have something to do with so called "Nagle's algorithm" which you should disable.
So practically you aren't sending 6000 packets per second.

There is always more or less of latency when transmitting data and that's one thing to over come.

Cheers!

Share this post


Link to post
Share on other sites

thank you for the replay.

as i said i'm a network newbie :D and i just have few more questions.

[quote name='SimonForsman' timestamp='1323780719' post='4893474']
recieve all packets that are pending each frame instead (on both client and server),


how do i do that exacly ?
[/quote]

You are sending the exact same data 100 times each frame here:



while (Window.IsOpened())
{

...

for(int i = 0; i<100; i++)
{
N.SendData(); // sending data 100times * 63FPS = 6300 times every second
}

...



The same goes for receiving. Remove the for-loop around it, and you'll send your data once each frame.


Also, I would suggest that you calculate the speed of the moving object on the client. Add this speed to your old character position and you have the new position. (You could calculate that by measuring the distance between two position updates divided by the time needed to travel that distance). Don't forget to compare the interpolated position with the actual position from time to time to make sure it is still correct.

That way the character of a player moves more fluent on the screen of another player even with a rather low rate of received network updates.




EDIT: ARGH kauna was faster ;)


Share this post


Link to post
Share on other sites
You don't need to send so much that, that is overkill, you can just interpolate/extrapolate values.
Check this:
www.mindcontrol.org/~hplus/epic/

Share this post


Link to post
Share on other sites

thank you for the replay.

as i said i'm a network newbie :D and i just have few more questions.

[quote name='SimonForsman' timestamp='1323780719' post='4893474']
recieve all packets that are pending each frame instead (on both client and server),


how do i do that exacly ?
[/quote]
http://msdn.microsof...v=vs.85%29.aspx


otherwise you run the risk of flooding the buffer if the framerate drops and send the data once per frame on both aswell

i didn't understand you. Can you please explain it more.
[/quote]
Right now you're sending a fixed number of packets per iteration on the server and reading a fixed number of packets per iteration on the client, if the framerate on the client drops even a tiny bit below that of the server you will send data faster than you are recieving it and the clients buffers will get full.


To hide the latency you should allow the client to move as soon as it presses the button

how do i do that too ?

sorry i know that I'm asking way too much but i really don't know that much about network programing.
thank you
[/quote]
You do that in exactly the same way as you would for a singleplayer game.

Share this post


Link to post
Share on other sites

anyways I have a structer that contain player X and Y position and and this structure is being send from the server to the client 6300 times every second. I tried to send it 60 times every second but there was a 1 sec delay from when I pressed Up key to move in the server side till the client respond and moved up.


60 times per second is probably too much -- a successful FPS game like HALO only sends packets 15 times a second. But 60 times a second is doable. 6300 is not.

The problem you're running into is quite likely related to TCP_NODELAY, and is described in the FAQ for this forum. Once you set that option on your socket, you should be fine wiht 60 times a second. Or 20.

Share this post


Link to post
Share on other sites
Many games can get away with rates as low as 10 times per second with relatively high latency -- which is about right for the average connection speed in the US as a worst-case-scenario. I recall reading somewhere that this is even a requirement for Xbox Live certification -- that a game has to be relatively playable at 10 packets/s with 200ms latency or somesuch. You'll likely experience greater rates than that in practice online, and greater still in a LAN environment, but you want to work at those rates, even if it means gracefully degrading the quality of the client-side experience for that player.

Google "dead reckoning" to read about how to reduce apparent client-side latency.

Share this post


Link to post
Share on other sites

[quote name='FantasyVI' timestamp='1323779847' post='4893473']
anyways I have a structer that contain player X and Y position and and this structure is being send from the server to the client 6300 times every second. I tried to send it 60 times every second but there was a 1 sec delay from when I pressed Up key to move in the server side till the client respond and moved up.


60 times per second is probably too much -- a successful FPS game like HALO only sends packets 15 times a second. But 60 times a second is doable. 6300 is not.

The problem you're running into is quite likely related to TCP_NODELAY, and is described in the FAQ for this forum. Once you set that option on your socket, you should be fine wiht 60 times a second. Or 20.
[/quote]

It can't be a Nagle issue since he's using UDP. That should be sending the packet every time he calls sendto.

OP, you really should just send movement data once, and, when receiving data, make a call to select to check if there's data on the socket. if so, read it out and process it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!