I just programmed a Java Server-Client Chat (with multiple clients) where they log in, chat and log out. The socket is always started and I listen in a loop.
Now I have to program this kind of chat where the connection isn't always open, so the the connection just stars "on request" (when someone sends a message).
How do I do this? Could you give me some keywords which I should google?
If you want to create a Server and Client that does not have a Open Connection (Correct me If I am wrong) you will have to Open and close the connection manually. As these "connections" represent Streams across the network.
Another Option you can consider is maybe using UDP, but this does not close and open a connection on request it only removes the overhead of TCP and it's reliability features.
From the Datagram Lesson on Oracle.com:
Some applications that you write to
communicate over the network will not
require the reliable, point-to-point
channel provided by TCP. Rather, your
applications might benefit from a mode
of communication that delivers
independent packages of information
whose arrival and order of arrival are
not guaranteed.
Related
I am completely new to creating a network connection in java so I apologize if this is a stupid question.
I am trying to create a D&D companion in java that will allow a player to create their character and then send it to the DM so that they can view it and make changes and send it back to the player. I want to be able to make it so that any time a field is changed on one computer it will also be changed on the other computer.
After a bunch of research online I have been able to create a socket connection between the DM(server) and the player(client) and pass a message between the two but I am not sure how a socket connection works after this initial connection is made. My research has not been very clear on this. I have found many resources that have said that java closes the socket after a message has been passed and many that say that the socket stays open.
If java closes the socket then my problem is easy enough to solve because then I will just have to open a new socket every time I need to pass data making sure that I pass the IP address of the client to the server the first time I make a connection.
My real questions come in when a socket stays open.
If the socket stays open and multiple clients connect to the server, will the server just shout over the network whenever it transmits a message so that all clients receive the message? (If this is the case then I know I can just attach a username to the front of the message so that the client can determine if the server is talking to it.)
If the server does not shout then how do I specify which client I want the server to talk to?
Will I have to add a loop to my receive methods so that the client/server is constantly listening for a transmission from the server/client or will java automatically do so after I run the method the first time?
I have found many resources that have said that java closes the socket after a message has been passed
You found them where?
and many that say that the socket stays open.
All those are correct. Java never closes connections. The application closes connections.
If java closes the socket then my problem is easy enough to solve because then I will just have to open a new socket every time I need to pass data making sure that I pass the IP address of the client to the server the first time I make a connection.
It doesn't.
My real questions come in when a socket stays open.
If the socket stays open and multiple clients connect to the server, will the server just shout over the network whenever it transmits a message so that all clients receive the message?
No. It will respond via the socket that is connected to the corresponding client.
(If this is the case then I know I can just attach a username to the front of the message so that the client can determine if the server is talking to it.)
Unnecessary.
If the server does not shout then how do I specify which client I want the server to talk to?
The server responds via the same socket it read the request from.
Will I have to add a loop to my receive methods so that the client/server is constantly listening for a transmission from the server/client
No, you will have to add a thread per accepted socket, that loops reading requests until end of stream.
or will java automatically do so after I run the method the first time?
No.
You seem to have been reading some truly appalling drivel. Take a look at the Custom Networking section of the Java Tutorial.
Adding to EJP's wise answer, it might be worth clarifying:
Sounds like you (wisely) use TCP, so your Socket represents a connection between 1 server and 1 client. No "shouting". In examples such as this , when connection is established (namely, client obtains a Socket by calling "new Socket" and server obtains a Socket by calling "accept"), those Sockets are dedicated to those 2 specific endpoints. So if 10 clients connect to 1 server, the server will keep 10 Sockets and won't mix them up. A bit like a poor secretary that has 10 phones on his desk and answers them all - despite the mess, each earpiece is clearly connected to 1 customer.
The connection can hold for a while & serve several messages. It will terminate when either one of the sides calls 'socket.close', or it can be terminated by underlying 3rd parties (operating system, proxies, firewalls).
For your first version, or for simple business requirements, it's probably enough to converse over this 1 simple connection. However, for commercial critical data that requires 'assurance of delivery', you might need to invest some careful thought & possibly tools such as RabbitMQ.
Good luck:)
I am facing a problem regarding designing my app with datagram socket. My app needs to communicate with different servers using udp connections. now I am not sure which of the following will be good. Is there any advantage of any of the following ( by performance or by other measures ). or is there any better option?
Option 1
create a single Datagram socket, and create a single thread to receive data of that. While sending to different servers set the address of the datagram packets. and in the receiving thread check the address and process data accordingly
Option 2
create different datagram sockets to communicate with servers. use socket.connet() to connect to the relevant server. And create threads for every socket to receive data.
N.B. I am actually working on an android app. if you have any query you can ask in comment
Unless you are we are talking about 100000 of connections, I would create single socket per thread. It speeds up application and guarantee the thread safety of sockets and that receaved data wont get mixed up.
The most important is however, that if one channel will fail or latency will get high, it will have no influence on other channels (sockets).
The drawback is that you are consuming more resources.
All depends on purpose of app.
My opinion is you can create a single socket to because creating more socket will bring down your app.
I need to send a continuous flow of messages (simple TextMessages with a timestamp and x/y coordinates) over a wireless network from a moving computer. There will be a lot of these short messages (like 200 per sec) and unfortunately the network connection is most likely unreliable since the sending device will leave the WLAN area from time to time... When the connection is not available, all upcoming messages should be buffered until the connection is back up again. The order of the transmitted messages does not matter, since they contain a timestamp, but ALL messages must be transferred.
What would be a simple but reliable method for sending these telegrams? Would it be possible to just use a "plain" TCP or UDP socket connection? Would messages be buffered when the connection is temporarily down and send afterwards automatically? Or is the connection loss directly detected and reported, thus I could buffer the messages and try to reconnect periodically on my own? Do libraries like Netty help here?
I also thought about using a broker to broker communication (e.g. ActiveMQ network of brokers) as an alternative. Would the overhead too big here?! Would you suggest another messaging middleware in this case?
TCP is guaranteed delivery (When it's connected that is) - You should check if the connection went down and put messages in a queue while it is retrying the connection. Once it sees that connection is back up dump the queue into the TCP socket.
Also look into TCP Keepalive for recognition of a down connection: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
Seems like you could use a message wrapper like Java JMS using a "Assured persistent" reliability mode. I have not done this myself, in the context of text messages, but this idea may lead you to the right answer. Also, there may be an Apache library already written that handles what you need, such as Qpid .
I need to implement client/server instant messenger using pure sockets in Java lang.
The server should serve large number of clients and I need to decide which sockets should I use - TCP or UDP.
Thanks, Costa.
TCP
Reason:
TCP: "There is absolute guarantee that the data transferred remains intact and arrives in the same order in which it was sent."
UDP: "There is no guarantee that the messages or packets sent would reach at all."
Learn more at: http://www.diffen.com/difference/TCP_vs_UDP
Would you want your chat message possibly lost?
Edit: I missed the part about "large chat program". I think because of the nature of the chat program it needs to be a TCP server, I cannot imagine the actual text content sent by users over a UDP protocol.
The max limit for TCP servers is 65536 connections at the same time. If you really need to go past that number you could create a dispatcher server that would send incoming connects to the appropriate server depending on current server loads.
You could use both. Use TCP for exchanging the actual messages, (so no data lost and streaming large messages, (eg. containing jpegs etc), is possible. Use UDP only for sending short 'connectNow' messages to clients for which there are messages queued. The clients could have states like (NotLoggedIn, TCPconnected, TCPdisconnected, LoggedOut) with various timeouts to control the state transitions as well as the normal message-exchange events. The UDP 'connectNow' message would instruct clients in 'TCPdisconnected' to connect and so move to 'TCPconnected', where they would stay, exchanging messages, until some inactivity timer instructs the client to disconnect for now. This would, of course, be unreliable and so you may wish to repeat the 'connectNow' message every X seconds for N times until the client connects. The client should, in any case, attempt a poll every X minutes, just in case...
It depends whether the user needs to know if the messages have been delivered to the server. UDP packets have no inherent acknowledgement. If the client sends an IM message to the server and it gets lost in transit, neither the client or the server will know about it.
(The short answer is "use TCP" ... but it is worth thinking through the design implications for yourself.)
TCP would give you reliability, which is certainly desirable when during instant messaging -- you would not want messages to be dropped during converstation.
However, if you intend on using group messaging, then you might end up using mulitcast. For such cases, UDP would be the right chioce since UDP can handle point to multipoint. Using TCP for multicast applications would be hard since now the sender would have to keep track of retransmissions/sending rate for multiple receivers. One alternative could be to use TCP for point-to-point chat and use UDP for group messaging.
I'm making a java program & I want this to be both as server and a client (using sockets). How is this best achieved?
If you mean that you want to both send and receive data, a single regular socket (on each computer) will do just fine. See Socket.getInputStream and Socket.getOutputStream.
The usual "server" / "client" distinction just boils down which host is listening for incoming connections, and which hosts connect to those hosts. Once the connection is setup, you can both send and receive from both ends.
If you want both hosts to listen for incoming connections, then just set up a ServerSocket and call accept on both hosts.
Related links:
Official trail: The Java™ Tutorials, Lesson: All About Sockets
If you want each station to function as a server and a client, like a p2p chat,
you should implement a thread with a ServerSocket, listening for incoming connections, and once it got a connection, open a new thread to handle it so the current one will keep on listening for new connections.
For it to be able to connect to others, simple use SocketAddress and Socket, in a different thread to try to connect to a specified server address (e.g. by a list of the user's friends)
you can find plenty of chat examples by googling.
cheers.
If you want the program to perform the same operations regardless of whether it is a server or a client for a certain connection, I could imagine handing off both the client Socket and the ServerSocket.accept()-produced socket to the same method for processing.
Have a look at jgroups it's a library that allows the creation of groups of processes whose members can send messages to each other. Another option would be to use hazelcast...
You may also look at this question.
The best way to do this is to run the server on a thread:
You run server.accept() therefore while your program is listening for a connection on that thread you can do whatever you want on the main thread, even connect to another server therefore making the program both a server & a client.