Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Varonth

Pages: [1]
1
Network / Re: Are the send and receive methods of sf::UdpSocket threadsafe?
« on: November 25, 2015, 01:47:43 am »
After some quick googling and looking at the implementation of the functions, I would say... it depends on how you call it.

To start, the actual data transfering is done by the standard function sendto() and recvfrom() which should be atomic.

The thing is the in receive remoteAddress and remotePort are called by reference so is remoteAddress in send.

Receive will also change the value of remoteAddress twice, clearing it at the beginning of the function and fill it at the end with the remoteAddress of the received datagram.

So if you use the same IpAddress instance for the remoteAddress of send and receive, you send could get the address changed when the thread is stopped and the value being changed then by receive. Besides these function arguments, everything in the two function appears to be self contained.

Atleast that is what I see at the first glance at almost 2am. Might dig into that a bit deeper tomorrow.

2
Network / Re: server can only receive 1 message
« on: November 22, 2015, 05:54:45 pm »
On the serverside:

The TcpSocket you create in your while loop lifetime expires at the end of the loop. Since that one is initialised on the stack, it will only live as long as it's scope is active (so until the while finished its current loop). Once the loop is done, it will get destroyed and the space on the stack will be freed for the next loop iteration. The destructor will clean up the TcpSocket just fine, by disconnecting it properly. The loop will then iterate and accept another client for a single message.

You need to have the client sockets on the heap (using "new"), and keep track of them with some container.

You might want to start looking at the SocketSelector class. It also has an example in it:
http://www.sfml-dev.org/documentation/2.0/classsf_1_1SocketSelector.php

3
Network / Re: Multiplayer Game Example
« on: March 31, 2013, 07:36:15 pm »
TcpSockets are bidirectional, and you just have to open port and forward ports to establish a connection. That's what the TcpListener is for, and that is just needed on the server side in most cases (unless you want a Peer-to-Peer topology).
Once a TcpSocket connects to a server, which is listening on a specific port and will accept connections, there will be some handshakes which will establish a connection on a ephemeral port.
So once connected you can send and receive data from a TcpSocket, and you just have to manage these TcpSocket objects, so that it sends data to the right client, and can distinguish which TcpSocket on the server is which client.

If you want to handle multiple clients with SFML you might want to take a look at the SocketSelector class, which also includes a nice example.

If you use UDP and want to use it bidirectional, then yeah you must also open ports on the client side.

4
Network / Re: Sending several times without receive
« on: March 31, 2013, 05:39:30 pm »
It depends on how much data you are sending inbetween each subsequent receive call.

Each TcpSocket has a receive buffer, which will store data until it is read by it's recv function. If the buffer is full the other sides send will either wait until the it can actually send more data in case of a blocking socket, or in non-blocking mode return EWOULDBLOCK or EAGAIN.

The size of the Tcp buffer is depending on the system, for example MSDN says the standard receive buffer size in windows is 8192 bytes.

Edit:
Forgot to mention what a UDP socket does, but I guess that is pretty clear.
Cannot fit into the buffer? Well then... drop it ^^

Edit2:
Just looked at the SocketImpl at it appears that in case of an EWOULDBLOCK (and its windows equivalent WSAEWOULDBLOCK) error from the Socket, the SFML status would be Socket::NotReady, and in case of EAGAIN it would just be Socket::Error.

5
Network / Re: TCP Lag Reduction Techniques?
« on: March 30, 2013, 11:01:35 pm »
I don't know how your code works exactly. For example I don't know how often you send the map and object data, who gets which data etc.

If it is just once per second per client, with the numbers above this would be 5200*20 = 104000 bytes in a worst case scenario. That is 101.5625 kbyte/s or in terms of upstreams, 812.5kbit/s, just for this data. If you map/world can be indexed with 65,536 different states you might also switch to sf:UInt16 for your map and object chunks. But would basically halve the size of these sends (not actually 50% because of overhead by Tcp and IP but it would be so close, that you could say it is halved).

On top of that you might consider data compression before you send the data.
The packet documentation has some informtions on that topic, and there are several open source libraries for compression, like zLib.

It is probably one of the best advices I can give to you. Keep your packets as small as possible.
You often have to send this data multiple times, sometimes (or depending on the game always) to everyone connected to the game. Saving 20 bytes of data in a packet ends up being hundreds of bytes that you don't have to send.

6
Network / Re: TCP Lag Reduction Techniques?
« on: March 30, 2013, 10:35:22 pm »
Int in like 32bit standard integers?
Because one of these 20*20 packets would be 20*20*32/8 = 1600 bytes.
The 30*30 packets would be 30*30*32/8 = 3600 bytes.

Also you are sending the character name with each move?
If so, that is alot of bandwidth wasted.

If you need a way to distinguish the different move request for each character, you should consider using a sf:Uint8 or sf:Uint16 as an ID number, and give every single player a unique ID for that playsession, which allows every client to know which character entity is moved by each move request.

You should try to make packets as small as possible, as 1kb packets send to 20 people, perhaps multiple times per seconds, takes alot of bandwidth pretty fast.

And while most home connections have a good downstreams, the upstreams are often limited in speed.

7
Network / Re: TCP Lag Reduction Techniques?
« on: March 30, 2013, 09:42:53 pm »
May I ask what exactly are you sending there?
5-20s sounds like you are sending something huge.

8
Network / Re: After tcplistener.close() I have to restart the server?
« on: March 30, 2013, 05:08:07 pm »
Oh well, I think I might know what is going on.

Could you try netstat again, after shutting down, but instead of getting all listening ports you should look for TcpSockets in the state "TIME_WAIT".

If it is still there, you might just have to wait a few minutes until you can restart your server application.

Just remove the -l argument from netstat, or add -a to it.

Normally netstat will not display listening ports, thats what the -l does. -a shows all Sockets.

Edit:
A nice article about TIME_WAIT and TcpSockets http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html

9
Network / Re: After tcplistener.close() I have to restart the server?
« on: March 30, 2013, 04:36:50 pm »
It just shows one listening socket, which is probably listening on port 22 (that's the standard for SSH).

If so, that is kinda weird considering how many processes use sockets for inter-process communications on localhost.

You could always try different arguments aswell for netstat.

10
Network / Re: After tcplistener.close() I have to restart the server?
« on: March 30, 2013, 04:13:20 pm »
Ah ok, that makes a bit more sense now.

Ever took a look at netstat after closing your server application?

Try
sudo netstat -npl

It should show you all listening socket including the process they belong to.

11
Network / Re: After tcplistener.close() I have to restart the server?
« on: March 30, 2013, 03:34:32 pm »
So do I get this right?
When the client application gets closed, you are calling ::close on the TcpListener of your server application?

If that's the case, yeah your server cannot accept new connections.
The TcpListener willl create a new TcpSocket using the Socket object given as argument. That Socket will then handle all the connections received by that client. The TcpListener can then continue to listen on it's port, while the client socket is now bound to another free port. That allows you to accept multiple connections with just one listener. The client therefore just has to know the port of the TcpListener, and the server will then establish a TcpConnection on a free port. In case of a game for example, you just have to tell other players the port the TcpListener is listening on, and you also just have to forward connection request of that port in router and firewall settings etc. The port forwarding isn't needed for established connections, just for accepting incoming connection.

Now if the client closes his connection your server should close and handle the disconnect from the client socket. The TcpListener should be unaffected and should just be closed once it isn't needed anymore, so once your server should no longer accept new connections.

TL;DR (hopefully you did)
You should not close your listener port, unless you don't want to accept new connections. On client disconnect you just close the client socket given as argument to sf::TcpListener::accept

Pages: [1]
anything