While creating a Secure Instant messenger in java , if there are many clients
for example
3 clients
client A,B,C
A wants to connect to B and C both. So do i need to create different socket connection for both of them separately?
If so than is not it is a restriction like if there are 10,000 clients and each wants to connect to rest of them so i will need million ports?
Yes, your solution would work. But when you add many more users, the instant messager will lag and be hard to maintain.
The better solution is to have one connection for each client, a connection to a server. clients will connect to this server (which will also handle authentication), and the server will sort out the messages and deliver them to another client(the messages destination).
Related
I am doing an android app allowing users to play online.
Currently, I use a TCP server: when two persons are connected, the server takes care of forwarding the packets between the two clients.
I would like to replace my server by a java servlet with google app engine. This new server will just be used to connect the two players.
It would work in that way:
Player A opens a server socket and then post to the server the connection details.
When a player B wants to play against A, he asks to the server the port number of A and he connects directly to A.
The problem is that I am not sure that it will work if player A is behind a NAT. When player A opens a server socket, that opens one port of its 192.168.x.y address, but does it ask to the box a port forwarding? I assume it doesn't...
So two questions:
Is it possible to make a direct connection TCP between two devices even when there is a NAT or a firewall (I don't know how firewalls work on Android...)
If it isn't possible, what is the best solution: Is it possible to make a TCP server to ensure the exchange of the messages with app engine?
Thank you by advance.
game
Creating direct TCP connection between users under different NAT is mostly possible. There are 4 types of NAT. FC, ARC, PRC, Symmetric. If one of player A or B has symmetric NAT then it is impossible to create TCP P2P connection. In this case you will have to use a server in the middle for exchanging data between two players.
For other types of NAT combinations it is very much possible but not guaranteed. The technique that is used to create TCP P2P connection is called TCP hole punching. Read this answer to know in details about this technique.
Also creating TCP P2P connection is not related to any platform.
First, the device itself is probably not going to be the main problem. If they are at home and using WiFi, you will probably have to deal with a cable modem/DSL modem, which typically includes a firewall. Also if they are at work (or a hotel, conference center, etc.), there may be a corporate firewall to deal with.
I believe most home cable/DSL modems support uPnP (Universal Plug and Play), which includes the Internet Gateway Device Protocol (IGD) designed to let devices determine the external IP address and set up port mappings. In general you can look up NAT traversal for ways to handle connections through a home modem/firewall. I will note that corporate firewalls are a different matter and many of these techniques won't work.
So probably I would recommend you be ready for at least the following four scenarios
Direct connection with nothing creating problems. You can test this by having the server do a test connection when the player first contacts the server. If this works, things are simple.
Home NAT device that understands uPnP. If you have a 10.x.x.x, 172.16.x.x-172.31.x.x, or 192.168.x.x number (typical home WiFi), then you can try to set up the NAT traversal and if that works you can send the appropriate information to your server. It probably would be worthwhile for the server to do a test connection just to be sure that things work.
If you have a firewall that you can't get around, then make a note on the server regarding player A, and when B tries to join A's game, look and see if B will accept connections, and if so then arrange for A to connect to B instead.
If none of the above work, then have A and B both connect to the server and have the server relay messages between A and B.
If you don't want to program all those possibilities, then option 4 is the one that is most likely to work, even if it does mean extra traffic going to/from your server. But note that for corporate networks, they may simply have a rule blocking unknown connections, and there may not be much you can do.
Edit: I was able to get a simple TCP server working on Android without anything special regarding Android itself, so removed a comment saying I didn't know about that.
I want to implement a multi-threaded client socket in JAVA which will connect with multiple servers..
For eg..
The client will accept an array of numbers and split that array into two.. The two arrays will be sent to two servers and the result from the servers will be combined by the client to get the Final sorted array..
Any help guys???
Let's split the "client" meaning in 2:
client application, the app which you're creating which will communicate with one or more servers
client-socket, a client side of a communication channel, which can be connected to maximum one server at any time
As a side note, only server-sockets can handle multiple clients "at the same time"
Now, you can not have a client-socket connect to multiple servers, but you can have a client application connecting to multiple servers by having an instance of client-socket connect to each server.
So what your client application needs to do, is manage a list of client-sockets that connect to your servers, and upon receiving all the replies, aggregate the answer.
Apache hadoop is what you have to use in this scenario.
First of all sorry for the long winded title but i was unable to think of a suitable title, considering my question.
Now to the problem. I am creating a peer to peer chat application, which has the ability to send and receive files while also being able to chat to individual contacts.
I understand i can capture the ip of the client connecting to the server and store this, then when that user starts a chat session to another person. I can use that stored ip to create a connection between the two clients using the ServerSocket.
BUT i do not wish to pass one users ip to another users computer for security reasons so, what i am asking basically is there a way to connect two clients together without passing each client each others ip.
so for e.g
(all sockets have read / write buffers )
Client 1-- logs in --> Server ( a session ID 1 is created between the client 1 and server )
Client 2-- logs in --> Server ( a session ID 2 is created between the client 2 and server )
Client 1 --- Starts chat with client 2 ---> Server ( server connects session 1 and session 2)
Client 1 can then chat and send files to client two without passing it the ip.
I am sorry if this is a unclear question or even stupid but i could not think of a way to even Google this question.
You would need to run the connection through a server. You could use the server to buffer the connection between the two clients and connect their communications in a way that would seem nearly seamless.
For example you could create a thread that, as long as both clients are connected, waits for input from client 1 and immediately pipes it to client 2. And the same would be necessary vice-versa. Is this the kind of solution you were looking for?
I'm trying to make like a skype-instant messager, my idea for it is to have
one server which handles multiple connections for the clients. What I now have is a friend list etc, but now I want to create Threads both for server and client to handle a conversation. The problem is that I need multiple connections between a server and one client for every conversation(I think). but i dont think it's possible. Does someone have another way for doing this or maybe a way to make multiple connections between the server and a client?
Thanks for helping me out
PS: English is not my main language so please excuse me for my grammar.
I think the best is that you always make one tcp connection from each client to the server, that way if your client is behind a firewall or router the connection can be established anyway.
Then you need to define a protocol with control messages, like "create new conversation with ...". And the server can generate a guid for each new conversation, then client can receive and send messages togheter with the conversation id always through one connection.
Update:
To answer the original question: yes, you can make multiple connections between client and server. Each connection should be opened from the client to the server port, once established, each one will have a different port. You can make a thread to deal with each connection or have on thread dealing with all connection using non-blocking calls.
I am looking to build an instant messenger in Java.
Clients will connect to the server to log in.
They will start a conversation with one or more other clients.
They will then post messages to the server that will relay the messages to all the clients.
The client needs to be continually updated when users post messages or log in.
so the way I see it, the client needs to run a server itself in a separate thread so that the main server can send stuff to it. Otherwise the client will have to the poll the main server every xyz seconds to get the latest updates. And that would need a separate thread anayway, as that would be purely for getting updates whereas the 'main' thread would be used for when the client initiates actions such as posting messages/inviting others to conversations etc...
So anyone recommendations on how to write this instant messenger? Does it sound like a good idea to make the connection a 'two-way' connection where both the client and server act as servers? Or is polling a better option? Anyone know how the IRC protocol does this?
There's no real advantage of having 2 connections unless they can be handled independently (for example receiving / sending a file usually done in a separate connection). A connection itself is already a two-way communication channel so it can be used to both send and receive messages, events etc. You don't need to poll server since client is able to maintain persistent connection and just wait for data to appear (optionally sending periodic PING-like message to ensure connection is alive).
IRC uses a single connection to server to exchange text commands. For example one of the main commands:
PRIVMSG <msgtarget> <message>
This command can be originated either by client or by server. Client sends PRIVMSG to notify that it wants to deliver message to one or more destination (in IRC this either user(s) or channel(s)). Server's task here is to properly broadcast this message to appropriate clients.
If you're using raw InputOutput streams then yes this is a good way of doing it. You create one thread on the clientside that acts in a similar fashion as the server thread - waits for any incoming updates and when it does it updates the client. I wouldn't call it a server though. So you'd ideally have 2 TCP/UDP connections one for requests made by the client and one to notify the client of server changes.
This solution in an enterprise environment would probably be done through some kind of messaging framework such as Spring Integration but dig deep enough and it will essentially be a similar way to how you mentioned.
Do you need a fully custom protocol or would it be sufficient to use the XMPP? There are several open source libraries implementing XMPP.
http://xmpp.org/xmpp-software/libraries/
e.g. http://www.igniterealtime.org/projects/smack/
For me, to develop instant messaging service, I will use websocket protocol instead of normal java socket because the normal socket can not work well with HTTP protocol and moreover some network providers and firewalls banned custom ports. If you develop it in normal socket, your service could not be accessed by web clients.
Did you plan to develop the instant messaging service yourself? How about using other protocols such as Jabber?