I am making a multiplayer networking game. Now to connect to the server, client needs the ip address of the server.
So, the way I implement this is as follows.
Client Broadcasts its ip address at Broadcast IP and a port say A.
Server listens to it over A, and
Server creates a new UDP connection with the client behaving as a client say over port B. It sends all the important information required for the game including its IP.
Client is the server for this connection and receives the data from server over port B.
Now, A and B are constants. So when I need the server to listen for multiple clients in different threads I can put diff values to A and B for the threads but in the client file A and B are independent of these threads. So it gives me an error of
bind: Address already in use
What is the plausible solution for this?
First of all, having the client broadcast its address sounds pretty horrible, at least to me. Broadcasting means that it'll only work if the server is on the local subnet, as well as polluting the network with a lot of unnecessary traffic.
I'd have the client find the server via DNS Service Discovery (DNS-SD). This has the advantage that you can use multicast DNS as long as your server is on the local subnet, and transition to a wide-area server using normal administered DNS, without making any changes to the client at all.
Second, the server should not dedicate a thread to each client. While this model can be made to work to some degree, it has quite a bit of overhead and scales really poorly.
Finally, to (what I think was) your original question: instead of a different port for each client, I'd have one port for all clients. Each request from a client will carry enough information for the server to carry out whatever request it contains. The server simply listens on its single port, and services each request as it arrives. You might dedicate more than one thread to this, but it should be a generic thread pool -- i.e., the number of threads involved is simply a matter of configuration, with no logical implication to the overall design (i.e., the identity of a particular thread has no significance -- if you move to a bigger server with 8 times as man cores, adding more threads is a simple matter of configuring more threads, not changing the overall design).
Related
I am not clearly understanding the difference between using TCP socket with client connecting to 127.0.0.1 server address and other IPC such as message queues. Since both are used for communication within the same host, why at all someone would go for socket approach leaving the message queue one, as in this case, sockets will cause more overhead compared to the queues.
The differences that I am seeing:-
In case of sockets we can see the contents in wireshark, in queues there is no such way.
The point of the loopback interface / address is not that you write programs to use it specifically.
The point is that it lets you talk to network services running on the local computer in the same way that you would talk to network services running on a remote host. For instance, if I'm developing a website, I can start up a test instance of its server on my local computer and then point my browser at http://127.0.0.1/ and there it is. I don't have to modify the code of my browser to talk over AF_UNIX sockets or whatever first. Similarly, if I am writing an application that needs a database, I might start out with the database running on the same computer as the application, talking to it over loopback, but then later when the database gets bigger I can move it to a dedicated host and I don't have to change anything other than the connection configuration.
You are absolutely correct that local IPC has lower overhead, and should be used when the two processes that need to communicate will always be on the same machine.
TCP and IPC both approach we use for inter process communication in distributed architecture. If processes are running in same machine we will go for message queue but surely not TCP. But suppose one application is running in one box and another application is running in a different box definitely we have to go for TCP for inter process communication. Even web services also internally implement TCP for communicating to a remote application.
But still we need a TCP base communication in the same machine between two process where synchronize communication is must. For example if you send a request for an account information of a client and waiting for the response you need this approach. But if you just need to send a client information to a server to store it in a table and you don't need an answer from that server whether your records has been stored successfully or not you just go for a queue only to drop the message.
There's already a question How exactly does a remote program like team viewer work which gives a basic description, but I'm interested in how the comms works once the client has registered with the server. If the client is behind a NAT then it won't have its own IP address so how can the server (or another client) send a message to it? Or does the client just keep polling the server to see if its got any requests?
Are there any open source equivalents of LogMeIn or TeamViewer?
The simplest and most reliable way (although not always the most efficient) is to have each client make an outgoing TCP connection to a well-known server somewhere and keep that connection open. As long as the TCP connection is open, data can pass over that TCP connection in either direction at any time. It appears that both LogMeIn and TeamViewer use this method, at least as a fall-back. The main drawbacks for this technique are that all data has to pass through a TeamViewer/LogMeIn company server (which can become a bottleneck), and that TCP doesn't handle dropped packets very well -- it will stall and wait for the dropped packets to be resent, rather than giving up on them and sending newer data instead.
The other technique that they can sometimes use (in order to get better performance) is UDP hole-punching. That technique relies on the fact that many firewalls will accept incoming UDP packets from remote hosts that the firewalled-host has recently sent an outgoing UDP packet to. Given that, the TeamViewer/LogMeIn company's server can tell both clients to send an outgoing packet to the IP address of the other client's firewall, and after that (hopefully) each firewall will accept UDP packets from the other client's Internet-facing IP address. This doesn't always work, though, since different firewalls work in different ways and may not include the aforementioned UDP-allowing logic.
Firstly, please excuse my probable butchering the technical terminology. I've been thrown into socket IO with little formal education and I know that I am bungling words left and right.
I'm trying to build a client and server in C that enables multiple clients to connect to one another. The general procedure goes something like this:
1) Server has one port that is constantly listening and accepting connections
2) A client connects on that port
3) Server creates a new socket (same address, different port number), tells the client to connect to that socket, and closes the connection with the client.
4) The client connects to the designated socket and provides the server with a channel it would like to be on
5) Server places that socket on the designated channel
6) Repeat steps 2 through 5 for each client that connects to the server
/* all of the above has been coded already */
7) Once a channel has 2 or more members, I'd like to have each member port be able to broadcast to all other ports in the same channel (and thus the clients communicate with each other)
In this situation, all involved sockets on the same channel have the same address and DIFFERENT port numbers. Everything I've read and researched about broadcasting and multicasting revolves around each communicator having the same port number and different addresses.
Is there a way to do the communication that I'm hoping to do, in C?
I would think you want to use the listen() and accept() functions for TCP. You can do what you describe and have clients talk to each other, but all traffic will run through the server as a hub.
If you want all clients to be able to talk to every other client, you have a few options:
Server is the hub for all data and passes it between clients for you
Clients maintain direct connections to the other clients and pass data to each other in order to facilitate the hub. This means lots of data copying.
Broadcast or multicast (UDP). This is only possible over a local network, as internet routers will block multicast and broadcast traffic.
I would probably go with #1.
Remember that each client has it's own IP address, so for a client to communicate with another client, and not involving the server, it would need to open a new connection with the other client, send data and then close the connection. While doable, I do not think this idea would scale very well.
I do agree with Syplex that having the server act as a relay hub is probably the best, and certainly has the potential to scale well. So the data-flow would be something like this:
a client receives a message that is to be retransmitted to all the other clients.
this message is passed to all other instances of your server process
each of these instances of your server process sends out the message.
The issue becomes how you are implementing you server, and you do have two models that fit what you describe:
(1) you are using a multi-treaded server, in which each new connection causes a thread to be spawned to handle the communication between the client and the server.
(2) you are using a forking server, in which the server forks a new process to communicate with the client.
In case (1) you would be interested in intra-process communication (message queue for example) while in case (2) you would be interested in inter-process communication (named pipes or shared memory for example).
At this point there are two many variables to give a concise answer. I hope this helps gets you started and at least gives you somewhere to start looking.
The Tcp server need to serve many clients, If one client one server port and one server thread to listen the port, I want to know weather it is faster ?
If one port is good, could someone explain the different between one port and multiple ports in this case, thanks!
The problem with using multiple ports to achieve this is that each of your clients will each have a specific port number. Depending on the number of clients there could be a tremendous amount of bookkeeping involved.
Typically, for a tcp server that is to serve multiple clients, you have a "main" thread which listens to a port and accepts connections on that port. That thread then passes the connected socket off to another thread for processing and goes back to listening.
For a wealth of Unix network programming knowledge check out "The Stevens Book"
Generally speaking* the server will allocate it's own outgoing sockets for each connected client (and you don't need to be aware of those numbers). Each client connection handle will hold it's port references.
When defining the servers connection port, you will allocate a socket for incoming clients to connect to. There is no performance benefit using multiple sockets, in fact allocating additional sockets will show a performance hit (although for each port it will be tiny.)
update...
By the way, assigning multiple incoming ports (particularly a large range) for clients to connect to is also insane. From the perspective of making the service usable and maintainable.
Let me explain my scenario before asking the question.
I am in creation phase of 17 different multiplayer games that can be played online, directly from browser.
To accomplish this, I have choosed Silverlight.
Communication will be done using Sockets.
Image 17 different type of games like Chess, Backgammon, Pool and hundred of online users communicating between client app and server app using Sockets binded to the same PORT number.
Wouldn't be faster (for my server) if every different type of game will use another PORT number ? Chess will use 4502, Backgammon will use 4503, Pool 4504.
Will this make a difference ? Or should I use the same PORT number 4502 for all games with no fear that something bad can happen ?
A socket that has been established as a server can accept connection requests from multiple clients. The original server socket does not become part of the connection. The accept method makes a new socket which participates in the connection and returns this socket. The server's original socket remains available for listening for further connection requests.
So it has no advantage to use different server ports. After all web servers get all their requests on port 80 and handle this very well.
As far as speed of processing on your server goes it will most likely make very little difference whether you receive all your communications on one socket or 17. The one socket approach would be a tiny bit faster since your server application will probably have fewer threads to switch between. However there will be other things that will have a higher overhead such as actually processing the game moves or authorising client requests etc.
As for the question of whether to use one or multiple sockets the bigest thing you should think about is deployment constraints. The TCP port numbers that Silverlight is allowed to use a non-standard (i.e not 80 or 443) and if there is a firewall or proxy between your client and server you may be better sticking to a single port to make the access control list on the firewall simpler.