Professional Documents
Culture Documents
Reinstating This Question With A Bounty! I Need An Example That Stays Online, Like A Real Instant Message
Reinstating This Question With A Bounty! I Need An Example That Stays Online, Like A Real Instant Message
Supuhstar
7,0022525 gold badges9898 silver badges168168 bronze badges
closed as too broad by meagar♦ May 5 '16 at 13:06
Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.
Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question.If
this question can be reworded to fit the rules in the help center, please edit the question.
1
This is not to difficult, but it is unclear if you are talking about a direct peer-to-peer connection or
running a centralized IM server. Either way, one or more parties has to act as a server (listening for
socket connections) and others have to act as clients. IMO the simplest model is the central server
listening on a well-known (to the clients at least) IP and port. The rest is trivial. – Keith Layne Dec 17 '11
at 4:28
what about two computers, both with peer and socket duties, so there is no central hub? and if it is
trivial, please post it as an answer! – Supuhstar Dec 17 '11 at 4:34
1
Dude, you're confusing terms. I think you mean "both with client and server duties". I'm not posting
code because I don't do Java. Somebody should be along to give you some code. It is not difficult, but
it won't be that short of a program. Sorry I couldn't be of more help. – Keith Layne Dec 17 '11 at 4:41
yeah, sorry... I'm switching between several tasks and it's hard to get my mind straight
^^; – Supuhstar Dec 17 '11 at 4:51
add a comment
6 Answers
activeoldest votes
13
When this question was first asked and answered back in 2011, it was simply "Looking online, all
resources I found are either useless tutorials, dead threads, or tell the programmer to use
external APIs.". The provided links below met the criteria at the time. Further discussion follows
in the comments.
First few Google results for "java socket chat":
http://cs.lmu.edu/~ray/notes/javanetexamples/
simple chatting program in java usings socket class
http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-
server.html
http://www.cise.ufl.edu/~amyles/tutorials/tcpchat/
http://ashishmyles.com/tutorials/tcpchat/index.html
Internet Archive link to fix missing Java source file
downloads: https://web.archive.org/web/20150623102646/http://ashishmyles.com/
tutorials/tcpchat/index.html
Or from "java 8 chat client":
https://gist.github.com/alex-zykov/b4052e3c1b6891081897
Many, many results following in the search. Pick one that suits your needs. You can even modify
the Google search to only show results from the past year, if you wish.
Community♦
111 silver badge
answered Dec 17 '11 at 4:48
ziesemer
24.8k77 gold badges6969 silver badges8888 bronze badges
Why google? Supuhstar said: "Looking online, all resources I found are either useless tutorials, dead
threads, or tell the programmer to use external APIs". – Pingwin Tux Jan 12 '15 at 16:33
2
@PingwinTux - it is unclear as to what search terms were originally used, but sometimes a valid
solution is just finding a better search query. I did not only provide the search terms and a matching
link, but also results that I had reviewed and validated to be in-line with what I understood to be the
original request. – ziesemer Feb 5 '15 at 16:23
1
@Supuhstar - you're still working on this? For what it's worth, the source code is still accessible by the
Internet Archive (answer updated to include). Also, even dated code is still completely valid for your
purposes here. Get the simple examples working first - and then you can update to make use of Java
8 features, etc., as you wish. – ziesemer Apr 29 '16 at 2:08
2
You would run one "common" host, then connect multiple clients. What you're looking to achieve will
probably not be as simple as you are hoping for. Start SIMPLE, then build from there. – ziesemer Apr
29 '16 at 3:24
1
@ziesemer Yet, it's unfortunately way too late for changing that. May I suggest that you add a small
introduction to your answer resuming OP's original question? This way, future readers of the updated
question would better understand how your answer relates to OP's question as they see
it… – jwatkins May 4 '16 at 18:36
show 9 more comments
8
I've done this when I was learning Java, something around 10 years ago. It works:
Constantes.java:
package jsc;
}
ControladorThread.java
package jsc;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;
try{
mcSocket = new MulticastSocket(MULTICAST_PORTA);
mcSocket.joinGroup(InetAddress.getByName(MULTICAST_IP));
} catch(IOException e){
e.printStackTrace();
}
}
public void run(){
while(true){
try{
byte[] buffer = receberPacote();
processar(buffer);
removerUsuariosOciosos();
atualizarListaUsuarios();
} catch(IOException e){
e.printStackTrace();
}
}
}
if(t1.equals(ESTOUONLINE))
atualizarEstadoUsuario(t2);
else if(t1.equals(DESCONECTANDO))
desconectarUsuario(t2);
else if(t1.equals(PRIVADO)){
String t3 = tokens.nextToken();
String t4 = tokens.nextToken();
if(t3.equals(main.getNick())){
receberMensagemPrivada(t2, t4);
}
}
else
main.setTextoEntrada(t1 + " diz: " + t2);
}
public Usuario(){}
package jsc;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
System.out.println(saida);
sleep(ESPERA);
}
catch(InterruptedException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
}
}
MensagemPrivadaFrame.java
package jsc;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
try {
mcSocket = new MulticastSocket();
} catch (IOException e) {
e.printStackTrace();
}
iniciarComponentes();
estouVivo = true;
}
}
};
entrada = new TextArea("[JSC] Bate papo privado entre " + nick + " e " +
paraUsuario + "\n");
entrada.setEditable(false);
addWindowListener(frameListener);
setLayout(new BorderLayout());
int x = (int) (Math.random() * 500);
int y = (int) (Math.random() * 500);
setBounds(x, y, 400, 300);
System.out.println(x + " " + y);
add("Center", entrada);
add("South", saida);
setVisible(true);
saida.requestFocus();
}
package jsc;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.ScrollPane;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
this.nick = nick;
try{
mcSocket = new MulticastSocket();
}
catch(IOException e){
e.printStackTrace();
}
iniciarComponentes();
new EstouOnlineThread(nick).start();
new ControladorThread(this).start();
}
saida.addActionListener(saidaListener);
usuariosOnline.addMouseListener(listListener);
usuariosOnline.setMinimumSize(new Dimension(60, 250));
addWindowListener(mainListener);
setSize(400, 300);
setLayout(new BorderLayout());
add("North", new JLabel("Java Socket ChatO"));
add("Center", entrada);
add("South", saida);
add("East", usuariosOnlineScroll);
setVisible(true);
requestFocus();
}
if(mensagem != null)
janela.setTextoEntrada("(" + paraUsuario + " diz) " + mensagem);
listaJanelasAbertas.add(janela);
//janela.requestFocus();
}
Edit:
As some have suggested, I've made some code improvements (refactoring) and post the project
on GitHub: https://github.com/jaumzera/javasocketchat
shareimprove this answer
edited May 29 '16 at 21:56
answered May 3 '16 at 1:36
Jaumzera
1,3641515 silver badges3535 bronze badges
Goodness! Maybe you should make a Github repo just for this answer! XD – Supuhstar May 3 '16 at
15:04
1
I'm planning to take some time to refact this code and post in GitHub. BTW, thank you. – Jaumzera May
3 '16 at 15:07
@Zimano. First of all, I've been working with IT for something around 12 or 13 years and I've never
seen an author suggesting that English should be the unique idiom you'd use for coding. Secondly, I
am Brazilian and I speak Portuguese. It's my native language and although it seems hard to learn,
write, read and speak, I like it and I'm proud of it. And last, but not less important, this code has more
than ten years. I was in university, my teacher was also Brazilian, my colleagues were Brazilians and
so there was no reason to write it in English, once it was just a class exercise. – Jaumzera May 30 '16 at
15:35
1
@Juamzera I apologize for what I said. I shouldn't have phrased it like that, as I can see it came off as
pretty rude. I should have probably just said that it made the code less interpretable/reusable from my
side. But that's actually a problem for me to deal with, not yours. :-) – Zimano May 30 '16 at 20:46
add a comment
2
Hm, I was tempted to direct you to a java implementation of a server implementing imap protocol
(eg. gavamail). But this, of cources, might also qualify as "old" code and for sure would kill your
expectation (for being a non-standard solution). Nevertheless it is a proper reference fulfilling
your (terse) specification.
What do we have?
We need a solution that should be in java. It must implement an basic instant messaging system.
The later is problematic as it covers a really broad range of functionality. But "basic" seem to
allow for a minimum solution.
We leave out more complex semantics like having different users or messages being related to a
system of categories or tags.
1. POST_MESSAGE
receive a mesage form a client and store it for later retrieval
This immediatley is asking the question of where to store such messages (in a database or
filesystem for persistency or simply within memory for a "messages live as long as the
server is up" semantics)
2. LOOKUP_MESSAGE
select a suitable message from the stored ones (preferrably an unread one) and return to
caller.
This could also return a set of messages (but think of restricting such set for cases where a
caller has a severe backlog of messages)
It might be necessary to keep track of the messages already having been read, either by
marking the messages or by maintaining seen status at the client. This could even be as
simple as keeping time or ordinal of last message seen and send this information along with
the LOOKUP_MESSAGE request.
A client needs to interact with a user on one hand and the service on the other hand.
It will take gat a new message from the user (likely on explicit request (e.g. send button) and call
the POST_MESSAGE service at the related server.
It also will (likely regularly, could also be on explicit request (e.g. user is starting client)) poll the
server for new messages. (Alternatively, you could devise a separate notification service that is
used by the server to notify the client of new messages. What suits your "needs" is beyond your
question.)
That's it.
So any example of a TCP based client/server application will form a perfect starting point for a
straight implementation.
I should also mention that you could cut the specification logic within the client and delegate user
interaction to a standard browser and implement the client application logic into a (web-)server
instance (together or separate from the server part). Nevertheless, you still will have both
(client/server) logical functionality according to above minimum specification.
rpy
3,71722 gold badges1313 silver badges2929 bronze badges
add a comment
2
I am not even sure if this question is still being used or what but I liked the task and I thought:
why not?
Here is my implementation, as simple as it gets but without forgetting fundamental parts. Written
in pure Java, makes use of, among the rest, Sockets, Threads and SynchronizedList:
SimpleChat.java (Main)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
try {
receiver = new Receiver(Integer.parseInt(args[1]));
sender = new Sender(args[0], args[2], Integer.parseInt(args[3]));
} catch (InterruptedException e) {
showUsage();
}
if(input.equals("\\exit")){
receiver.stop();
sender.stop();
isRunning = false;
} else {
sender.sendMessage(input);
}
}
}
}
Receiver.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(listeningPort);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));
while(isRunning) {
try {
System.out.println(in.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
new Thread(receiverT).start();
}
}
Sender.java
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
while(isRunning) {
synchronized(msgs){
Iterator<String> it = msgs.iterator();
while(it.hasNext()){
out.println(username + ": " + it.next());
}
out.close();
socket.close();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
new Thread(senderT).start();
}
N3sh
62977 silver badges2929 bronze badges
add a comment
1
I think you should clarify some details regarding what exactly you mean by a "basic instant
messaging program" and what your objectives actually are regarding this project.
In a 2011 comment, you mentioned that there should be no "central hub", but in a more recent
comment, you say that you would like something more in line with Skype or iMessage, where
users do not have to know which peer is the server... It is technically possible (using protocols
such as mdns, dlna or ssdp) for the program to transparently search the local network for potential
existing server nodes and have it either connect to the server peer if there is one, or establish itself
as a local server for other nodes to connect to it. That is for example how Apple iChat's Bonjour
protocol used to work. This is however a rather complex solution to implement right, and is
definitely not in line with what is done by current mass market messaging programs.
Also establishing direct peer-to-peer communication between users pose several practical issues
(particularly because of firewalls and NAT, but there are also concerns of confidentiality and
security). Most protocols therefore relay most messages through the central server, and negotiate
a direct connection only for the purpose of file transfers and audio/video calls.
For all these reasons, unless you are looking merely for an example of local network
communication between two hosts, you most certainly want two distinct programs: a server and a
client.
Then, assuming my assumption is correct, there are two other questions that need to be clarified.
First, do you have an actual reason to conceive the protocol by yourself, or would it be acceptable
to rather implement an existing protocol (such as XMPP, IRC, SIMPLE... there are tons). Even
though these protocols might looks highly complex at first, it is almost always possible to
implement only a subset these protocol's features/messages. Designing a naive network protocol
by yourself isn't that difficult, but there are tons of potential mistakes (mostly inefficiencies,
incompleteness and other minor issues) that you will have to go through. Maybe that is indeed
what you are specifically aiming for (that is, gaining experience at designing a network protocol
from scratch), but unless it is so, you should seriously opt for implementing an existing protocol.
Indeed, working with an existing protocol will not only avoid such design mistakes, but better
yet, you will gain significant knowledge from how others (generally experienced protocol
designers) actually resolved problems they met along the way. Using an existing protocol will
also make it much easier and more interesting for you to develop that program, given that you
will for example be able to test your client and server programs independently by connecting
from/to an official client/server implementation. You will also be able to exploit exiting protocol-
decoders in traffic sniffing tools in order to debug messages going through.
The second important question is how realistic you would like the server program to be, and most
importantly in regard to persistance. Should the server maintain a persistant list of users and
authenticate them? Should the server store a list of allowed contacts for each user? Should the
server allow store messages aimed at a peer that is currently offline or that can't be reached at that
exact moment? Real messaging server programs generally do such things, and though
implementing such mechanisms isn't highly difficult, it is best considered early in the design of a
program's architecture. For example, should you decide that these features are indeed desirable,
then it might turn out to be much more interesting for you to immediately design your server
around a persistant message queue engine, such as ActiveMQ...
I know this is not the examples you were asking for, but I still hope these thoughts may help you.
jwatkins
1,91288 silver badges2121 bronze badges
1
Thanks for all the knowledge! I'm really glad you've straightened stuff out. I'll consider all this, rethink
my approach, and edit my question accordingly (and answering your question) soon. – Supuhstar May
6 '16 at 2:52
add a comment
0
As said before, there is a lot of things that you need to put a real chat to work.
But i belive that you want something to start. And if you know the address and the port of the
other "client" it is easy.
Extreme simple "chat" implementation
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;