Error when compiling cannont access class - java

Trying to compilie this AuctionClientMain.java and this is the error I get and can't figur it out:
AuctionClientMain.java:16: cannot access AuctionClient
bad class file: .\AuctionClient.class
class file contains wrong class: Assignment.AuctionClient
Please remove or make sure it appears in the correct subdirectory of the classpath.
AuctionClient a = new AuctionClient(args[0],args[1],port);
I have included AuctionClientMain.java
import Auction.*;
import java.io.*;
public class AuctionClientMain
{
//Create the client
public static void main (String args[]) throws IOException
{
if(args.length!=3)
{
throw new RuntimeException ("Syntax: java AuctionClient <name> <serverhost> <port>");
}
//Convert port taken in as string to an integer
int port = Integer.parseInt(args[2]);
AuctionClient a = new AuctionClient(args[0],args[1],port);
}
}
And the Auction Client
package Auction;
import java.io.*;
import java.net.*;
public class AuctionClient
{
public AuctionGui gui;
private Socket socket;
private DataInputStream dataIn;
private DataOutputStream dataOut;
//Auction Client constructor String name used as identifier for each client to allow server to pick the winning bidder
public AuctionClient(String name,String server, int port)
{
//Create a new gui
gui = new AuctionGui("Bidomatic 5000");
//Add the key listener to the input field
gui.input.addKeyListener (new EnterListener(this,gui));
//Add the exit listener to the window
gui.addWindowListener(new ExitListener(this));
try
{
//Create a new socket with server name and port number provided
socket = new Socket(server, port);
//Create new data input stream
dataIn = new DataInputStream(socket.getInputStream());
//Create new data outpit stream
dataOut = new DataOutputStream(socket.getOutputStream());
dataOut.writeUTF(name);
while (true)
{
gui.output.append("\n"+dataIn.readUTF());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
//Send bid to output stream
public void sentBid(String bid)
{
try
{
//Write bid out
dataOut.writeUTF(bid);
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void disconnect()
{
try
{
socket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}

Your AuctionClientMain class seems to be in the default package. The AuctionClient class is in package Auction. The .class file for AuctionClient needs to be in a subdirectory named Auction relative to AuctionClientMain.
Alternatively, put AuctionClient in the default package or put AuctionClientMain in package Auction.
On a side note, Java conventions are that package names are all lower case. It would be better to use package auction; instead of package Auction;.

Because AuctionClient is in the Auction pacakge, the compiler expects to find the Java source file in a directroy called Auction.

Related

ClassLoader serializable?

I've been trying to make some sort of alpha key system for my game. I thought in order to prevent people from decompiling my jar and changing around some code to bypass the system and get straight into my game, I thought about making it so after some verification, the server would send a serialized copy of a ClassLoader object to the client, which the client can then use to load the required files off an external host to start running the game.
Turns out it's not working at all.. ClassLoader seems to be non-serializeable. Are there any suggestions on how I could make a simliar system, or some way to somehow be able to ram that ClassLoader object through?
Source code:
Server.java:
package org.arno;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import org.arno.Packet.ClassLoaderPacket;
public class InitServer {
private static ObjectOutputStream out;
private static ObjectInputStream in;
private static ServerSocket server;
private static Socket connection;
private static final float HANDSHAKE_UID = 9678;
public static void main(String[] args) {
startServer();
}
private static void startServer() {
try {
server = new ServerSocket(7799,100);
System.out.println("[LoginServer] Initiated");
while (true) {
waitForClientConnection();
setStreams();
waitForHandShake();
sendData();
closeClientConnection();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void closeClientConnection() throws Exception {
out.close();
in.close();
connection.close();
}
private static void waitForHandShake() throws Exception{
float handshake = (float) in.readObject();
System.out.println(handshake == HANDSHAKE_UID? "Handshakes match UID" : "Wrong handshake sent");
}
private static void sendData() throws Exception {
ClassLoaderPacket.writeObject(new ClassLoaderPacket(out));
System.out.println("DATA SEND");
}
private static void waitForClientConnection() throws Exception {
connection = server.accept();
System.out.println("[LoginServer] Connection made from IP ["
+ connection.getInetAddress().getHostAddress() + "]");
}
private static void setStreams() throws Exception {
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
}
}
ClassLoaderPacket.java:
package org.arno.Packet;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* #author arno
* File: ClassLoaderPacket.java
*/
public class ClassLoaderPacket implements Serializable {
static ObjectOutputStream out;
private transient ClassLoader cL;
private static final String GAME_URL = "https://dl.dropboxusercontent.com/u/9385659/Avalonpk718.jar";
public ClassLoaderPacket(ObjectOutputStream out) throws MalformedURLException {
this.out = out;
cL = new URLClassLoader(new URL[] { new URL(GAME_URL) });
}
public ClassLoader getClassLoaderContext() {
return cL;
}
public static void writeObject(ClassLoaderPacket packet) throws IOException {
out.writeObject(packet.getClassLoaderContext());
}
}
Client sided reading:
public void receiveData() throws Exception {
gameLoader = (ClassLoader) in.readObject();
}
I think there are too much of complex fields in the ClassLoader in order to serialize it. Additionally, it should implement Serializable interface and have serialVersionUID in the serializable class.
Would it be enough just to obfuscate the code? I think there are plenty of tools which may help you to conceal your code.
Here is the useful thread about java code obfuscation/protection: Best Java obfuscator?

How to read/write an object that has linked lists in a file

I have these classes: "MyClass1", "MyClass2", "MyClass3" and "MyMainClass",
public class MyMainClass implements Serializable {
private String att1, att2, att3;
private int att4, att5, att6;
private LinkedList <MyClass1> myClass1List = new LinkedList<MyClass1>();
private LinkedList <MyClass2> myClass2List = new LinkedList<MyClass2>();
private LinkedList <MyClass3> myClass3List = new LinkedList<MyClass3>();
}
My program create registers (Objects) of "MyMainClass" and deposit it in a LinkedList. I want to save the LinkedList of the objects in a file to get them after i reopen my program. What's the way to do it? I have tried with ObjectOutputStream, but doesn't work. Thanks.
Edit:
My code to add an object(I just read an example and tried):
public static void addObject (MyMainClass p) {
try {
outputStream = new ObjectOutputStream(new FileOutputStream("myfile.dat"));
outputStream.writeObject(p);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
System.exit(1);
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
} finally {
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
}
}
}
Note: "MyClass1", "MyClass2", "MyClass3" are Serializable.
I would make "myClass1", "myClass2", and "myClass3" Serializable, then wrap myClass1List, myClass2List, and myClass3List (and any other data you want to save) in another serializable class so you can use serialization/deserialization to save and restore all of the program state at once.
Unless myMainClass is that wrapper, in which case you need to declare that they all implement Serializable.
myMainClass isn't marked Serializable. Also, are myClass1, myClass2, and myClass3 serializable as well? If not, they should be.
On another note, please follow Java naming conventions; class name should start with an uppercase letter.
UPDATE
Are you sure that it's not writing to the file, or is it that the code is throwing exceptions that you cannot see?
In all your catch blocks, you have System.exit(1), which gives you absolutely no information about any exceptions that are happening; you're essentially swallowing them. You should at least print out the stacktrace (ex.printStackTrace()) so you can see what is going wrong.
I used following for my highschool project long time ago. Due to my poor English skills I do not really understand what class you wish to save and load (LinkedList or myMainClass), but I used this solution to successfully store and load any of my custom objects. I hope you find it handy.
Usage:
myMainClass object;
//
// ... your code fillin up the content of object
//
MyIO io = new MyIO();
io.save("", "myfile.dat", object); // "" as first argument will make java use current working directory
// to load the object:
myMainObject object = (myMainObject) io.load("", "myfile.dat");
Source:
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
public class MyIO {
// String path - path to the directory where the file is supposed to be saved.
// String filename - the name of the file
// Object data - object that you wish to save in the file. In your case "myMainClass"
public void save(String path, String filename, Object data) {
try {
FileOutputStream fos = new FileOutputStream(path + filename, false);
GZIPOutputStream gzos = new GZIPOutputStream(fos);
ObjectOutputStream out = new ObjectOutputStream(gzos);
out.writeObject(data);
out.flush();
out.close();
} catch (IOException e) {
System.out.println(e);
}
}
// String path - path to the directory where the file is stored
// String filename - the name of the file
// The function returns java object which can be cast to myMainClass.
public Object load(String path, String filename) {
try {
FileInputStream fis = new FileInputStream(path + filename);
GZIPInputStream gzis = new GZIPInputStream(fis);
ObjectInputStream in = new ObjectInputStream(gzis);
Object data = in.readObject();
in.close();
return data;
} catch (Exception e) {
System.out.println(e);
}
return null;
}
}

Understanding public static void main(String[] args)

I am a PHP/Mysql programmer trying to learn Java and I'm stuck on how to complile a file with this in it:
public static void main(String[] args)
Here is example code:
import java.net.*;
import java.io.*;
public class GreetingClient
{
public static void main(String [] args)
{
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try
{
System.out.println("Connecting to " + serverName
+ " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
out.writeUTF("Hello from "
+ client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
When run the try to use the javac command in Windows Command prompt to compile this from a .java file into a .class file to be called in a webpage, I get an error saying:
bad class file: .\String.java
file does not contain class String
Please remove or make sure it appears in the correct subdirectory of the classpath.
public static void main(String[] args) {
If a compile a .java file like this one:
import java.applet.Applet;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;
public class applet_test extends Applet {
private InetAddress addr = null;
public void init() {
try {
addr = InetAddress.getLocalHost();
}
catch (UnknownHostException e) {
System.exit(0);
}
}
public InetAddress getLHost() {
return addr;
}
}
I get no errors, the .java file compiles into a .class file and I am able to use the .class file in a webpage just fine.
Not sure what I'm doing wrong.
Thanks guys!
Ok, so now, when I run this command:
C:\ > javac GreetingClient.java
I get this:
GreetingClient.java:9: cannot find symbol
symbol : method parseInt(GreetingClient)
location: class java.lang.Integer
int port = Integer.parseInt(args[1]);
^
GreetingClient.java:14: cannot find symbol
symbol : constructor Socket(GreetingClient,int)
location: class java.net.Socket
Socket client = new Socket(serverName, port);
^
2 errors
Again, I only seem to get errors when running the javac command on a file with this line in it:
public static void main(String[] args)
I know I'm missing something, any help would be appreciated it.
Since your file contains class GreetingClient, it must be named GreetingClient.java. Java requires that the name of the file match the name of the class defined inside it.
In Java, your main class must contains public static void main(String[] args) to initialize it.
If you have more than one class, the other will be just class Class_Name {} and, as Greg Hewgill said: your Java File must be named equal your main class name

How to make a basic instant messaging program in pure Java [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Reinstating this question with a bounty! I need an example that stays online, like a real instant messenger! It needs to always be ready to receive or send a message to an arbitrary address over an arbitrary port, using TCP. The program must not quit after sending/receiving a message.
Bounty goes to whoever can give the best example of a real, usable instant messenger.
Looking online, all resources I found are either useless tutorials, dead threads, dead tutorials, ancient examples, or tell the programmer to use external APIs. How can I create a basic instant messenger from the ground up, only using Java SE?
There must be a way to do this, and some sample code would be appreciated. It only needs to perform the simplest tasks: Check if a compatible client is online on another computer (IP will be provided by the user) and send a TCP packet to that client, which will receive and display its contents.
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.
I've done this when I was learning Java, something around 10 years ago. It works:
Constantes.java:
package jsc;
public interface Constantes {
public static final String MULTICAST_IP = "224.0.0.1";
public static final int MULTICAST_PORTA = 3333;
public static final String SEPARADOR = "[>>>]";
public static final int TAMANHO_MENSAGEM = 1024;
public static final long ESPERA = 3000;
public static final String ESTOUONLINE = "EstouOnline";
public static final String DESCONECTANDO = "Desconectando";
public static final String PRIVADO = "Privado";
}
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;
public class ControladorThread extends Thread implements Constantes{
private MulticastSocket mcSocket;
private Main main;
private Vector<Usuario> listaUsuarios; // lista de usuários ativos
public ControladorThread(Main main){
super("ReceptoraThread_" + main.getNick());
listaUsuarios = new Vector<Usuario>();
listaUsuarios.add(new Usuario(main.getNick(), new Date().getTime()));
this.main = main;
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();
}
}
}
public byte [] receberPacote() throws IOException{
byte[] buffer = new byte[TAMANHO_MENSAGEM];
DatagramPacket pacote = new DatagramPacket(buffer, buffer.length);
mcSocket.receive(pacote);
return buffer;
}
public void processar(byte[] buffer){
String mensagem = new String(buffer);
mensagem = mensagem.trim();
StringTokenizer tokens = new StringTokenizer(mensagem, SEPARADOR);
String t1 = tokens.nextToken();
String t2 = tokens.nextToken();
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 void receberMensagemPrivada(String deUsuario, String mensagem){
main.abrirChatPrivado(main.getNick(), deUsuario, mensagem);
}
public boolean atualizarEstadoUsuario(String nomeUsuario){
int pos;
for(Iterator i = listaUsuarios.iterator(); i.hasNext(); ){
Usuario uAux = (Usuario) i.next();
if(uAux.getNome().equals(nomeUsuario)){
pos = listaUsuarios.indexOf(uAux);
listaUsuarios.remove(uAux);
uAux.setTempoInicio(new Date().getTime());
listaUsuarios.add(pos, uAux);
return true;
}
}
listaUsuarios.add(new Usuario(nomeUsuario, new Date().getTime()));
return false;
}
public void removerUsuariosOciosos(){
Usuario usuario = null;
for(Iterator i = listaUsuarios.iterator(); i.hasNext(); ){
usuario = (Usuario) i.next();
if(new Date().getTime() - usuario.getTempoInicio() > ESPERA){
desconectarUsuario(usuario.getNome());
i = listaUsuarios.iterator();
}
}
}
public void desconectarUsuario(String nomeUsuario){
for(Iterator i = listaUsuarios.iterator(); i.hasNext(); ){
Usuario uAux = (Usuario) i.next();
if(uAux.getNome().equals(nomeUsuario)){
i.remove();
break;
}
}
}
public void atualizarListaUsuarios(){
Vector<String> sVector = new Vector<String>();
Usuario uAux = null;
System.out.println("\nOnline: ");
for(Iterator i = listaUsuarios.iterator(); i.hasNext(); ){
uAux = (Usuario) i.next();
System.out.print( uAux.getNome() + " ");
sVector.add(uAux.getNome());
}
main.setUsuariosOnline(sVector);
}
private class Usuario{
private String nome;
private long tempoInicio;
public Usuario(){}
public Usuario(String nome, long tempoInicio){
this.nome = nome;
this.tempoInicio = tempoInicio;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public long getTempoInicio() {
return tempoInicio;
}
public void setTempoInicio(long tempoInicio) {
this.tempoInicio = tempoInicio;
}
}
public void sair(){
try {
mcSocket.leaveGroup(InetAddress.getByName(MULTICAST_IP));
mcSocket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
EstouOnlineThread.java
package jsc;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class EstouOnlineThread extends Thread implements Constantes{
private MulticastSocket mcSocket;
private String nick;
private byte[] buffer;
public EstouOnlineThread(String nick){
super("EstouOnlineThread_" + nick);
this.nick = nick;
try {
mcSocket = new MulticastSocket();
} catch(IOException e) {
e.printStackTrace();
}
}
public void run(){
String saida = ESTOUONLINE + SEPARADOR + nick;
buffer = saida.getBytes();
while(true){
try{
DatagramPacket estouOnline = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(MULTICAST_IP), MULTICAST_PORTA);
mcSocket.send(estouOnline);
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;
public class MensagemPrivadaFrame extends Frame implements Constantes{
private static final long serialVersionUID = 1L;
private TextArea entrada;
private TextField saida;
private String nomeJanela;
private String nick;
private String paraUsuario;
private MulticastSocket mcSocket;
private ActionListener saidaListener;
private WindowAdapter frameListener;
private boolean estouVivo; // indica que a janela ainda está ativa
public MensagemPrivadaFrame(String nick, String paraUsuario){
super("JSC - Chat com " + paraUsuario);
setIconImage(Toolkit.getDefaultToolkit().getImage("icone.4"));
this.nick = nick;
this.paraUsuario = paraUsuario;
this.nomeJanela = nick + paraUsuario;
try {
mcSocket = new MulticastSocket();
} catch (IOException e) {
e.printStackTrace();
}
iniciarComponentes();
estouVivo = true;
}
public void setNomeJanela(String nomeJanela){
this.nomeJanela = nomeJanela;
}
public String getNomeJanela(){
return nomeJanela;
}
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
public boolean estouVivo(){
return estouVivo;
}
public void iniciarComponentes(){
saidaListener = new ActionListener(){
public void actionPerformed(ActionEvent e){
TextField origem = (TextField) e.getSource();
enviarMensagem(origem.getText());
entrada.append("\n(" + nick + " diz) " + origem.getText());
origem.setText("");
}
};
frameListener = new WindowAdapter(){
public void windowClosing(WindowEvent e){
estouVivo = false;
dispose();
}
};
entrada = new TextArea("[JSC] Bate papo privado entre " + nick + " e " + paraUsuario + "\n");
entrada.setEditable(false);
saida = new TextField();
saida.addActionListener(saidaListener);
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();
}
public void setTextoEntrada(String texto){
entrada.append("\n" + texto);
entrada.setCaretPosition(entrada.getText().length());
}
public void enviarMensagem(String mensagem){
try{
mensagem = PRIVADO + SEPARADOR + nick + SEPARADOR + paraUsuario + SEPARADOR + mensagem;
byte[] bMensagem = mensagem.getBytes();
DatagramPacket pacote = new DatagramPacket(bMensagem, bMensagem.length, InetAddress.getByName(MULTICAST_IP), MULTICAST_PORTA);
mcSocket.send(pacote);
}
catch(UnknownHostException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
}
Main.java
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;
public class Main extends Frame implements Constantes{
private static final long serialVersionUID = 1L;
private TextArea entrada;
private TextField saida;
private JList usuariosOnline;
private ScrollPane usuariosOnlineScroll;
private WindowAdapter mainListener;
private ActionListener saidaListener;
private MouseAdapter listListener;
private MulticastSocket mcSocket; // soquete para multicasting
private Vector<String> listaUsuariosOnline; // lista com os nomes de usuários online
private Vector<MensagemPrivadaFrame> listaJanelasAbertas; // janelas de conversação privadas abertas
private String nick; // nome do usuário no chat
public void setNick(String nick){
this.nick = nick;
}
public String getNick(){
return nick;
}
public Main(String nick){
super("Java Socket Chat [" + nick + "]");
setIconImage(Toolkit.getDefaultToolkit().getImage("icone.1"));
this.nick = nick;
listaUsuariosOnline = new Vector<String>();
listaUsuariosOnline.add(nick);
listaJanelasAbertas = new Vector<MensagemPrivadaFrame>();
try{
mcSocket = new MulticastSocket();
}
catch(IOException e){
e.printStackTrace();
}
iniciarComponentes();
new EstouOnlineThread(nick).start();
new ControladorThread(this).start();
}
public void iniciarComponentes(){
mainListener = new WindowAdapter(){
public void windowClosing(WindowEvent e){
sair();
}
};
saidaListener = new ActionListener(){
public void actionPerformed(ActionEvent e){
TextField origem = (TextField) e.getSource();
enviarMensagem(origem.getText());
origem.setText("");
}
};
listListener = new MouseAdapter(){
public void mouseClicked(MouseEvent e){
if( e.getClickCount() >= 2 ){
// abrir a janela para mensagens privadas e passar o id do usuário
JList jlAux = (JList) e.getSource();
String paraUsuario = (String) jlAux.getSelectedValue();
abrirChatPrivado(nick, paraUsuario, null);
}
}
};
usuariosOnline = new JList(listaUsuariosOnline);
usuariosOnline.setSize(new Dimension(60, 280));
usuariosOnlineScroll = new ScrollPane();
usuariosOnlineScroll.add(usuariosOnline);
entrada = new TextArea("Olá " + nick);
entrada.setEditable(false);
entrada.setSize(300,280);
saida = new TextField();
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();
}
public void enviarMensagem(String mensagem){
try{
mensagem = nick + SEPARADOR + mensagem;
byte[] bMensagem = mensagem.getBytes();
DatagramPacket pacote = new DatagramPacket(bMensagem, bMensagem.length, InetAddress.getByName(MULTICAST_IP), MULTICAST_PORTA);
mcSocket.send(pacote);
}
catch(UnknownHostException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
private void desconectando(){
try{
String mensagem = "Desconectando" + SEPARADOR + nick;
byte[] bMensagem = mensagem.getBytes();
DatagramPacket pacote = new DatagramPacket(bMensagem, bMensagem.length, InetAddress.getByName(MULTICAST_IP), MULTICAST_PORTA);
mcSocket.send(pacote);
}
catch(UnknownHostException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
public void abrirChatPrivado(String nick, String paraUsuario, String mensagem){
removerJanelasInativas();
if(nick.equals(paraUsuario)){
JOptionPane.showMessageDialog(null, "Você não pode abrir um janela de conversação para você mesmo!", "Burro!", JOptionPane.ERROR_MESSAGE);
return;
}
String nome = nick + paraUsuario;
MensagemPrivadaFrame janela = null;
for(Iterator i = listaJanelasAbertas.iterator(); i.hasNext();){
janela = (MensagemPrivadaFrame) i.next();
if(nome.equals(janela.getNomeJanela())){
System.out.println(nick + " - " + janela.getNomeJanela() + " - " + janela.toString());
janela.setTextoEntrada("(" + paraUsuario + " diz) " + mensagem);
//janela.requestFocus();
return;
}
}
janela = new MensagemPrivadaFrame(nick, paraUsuario);
if(mensagem != null)
janela.setTextoEntrada("(" + paraUsuario + " diz) " + mensagem);
listaJanelasAbertas.add(janela);
//janela.requestFocus();
}
public void removerJanelasInativas(){
MensagemPrivadaFrame janela = null;
for(Iterator i = listaJanelasAbertas.iterator(); i.hasNext(); ){
janela = (MensagemPrivadaFrame) i.next();
if( !janela.estouVivo()){
i.remove();
}
}
}
public void setTextoEntrada(String texto){
entrada.append("\n" + texto);
entrada.setCaretPosition(entrada.getText().length());
}
public void setUsuariosOnline(Vector<String> listaUsuariosOnline){
usuariosOnline.setListData(listaUsuariosOnline);
}
public void sair(){
desconectando();
dispose();
System.exit(0);
}
public static void main(String args[]){
String nick = JOptionPane.showInputDialog("Digite seu nome (max. 20 caracteres): ");
if(nick != null && !nick.equals("")){
if(nick.length() > 20)
nick = nick.substring(0, 20);
new Main(nick);
}
else
JOptionPane.showMessageDialog(null, "É necessário informar um nome para entrar no bate-papo");
//System.exit(0);
}
}
Nowadays I'm not proud of the code, but it really works.
Edit:
As some have suggested, I've made some code improvements (refactoring) and post the project on GitHub: https://github.com/jaumzera/javasocketchat
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.
So what is a minimum instant messaging system? Let's try with the following:
a client that is posting and retrieving messages.
a server that is storing posted messages for (later) retrieval
We also would need a policy of how a client would identify a proper server. Most trivial solution for the later aspect is using a "central" server with a well-known address. For more complex cases we would need to have the server and/or client functionality distributed across several instances and devise a scheme or policy for identifying the proper instance(s) for communication.
We leave out more complex semantics like having different users or messages being related to a system of categories or tags.
Now, we are down to having two components:
A server implementing two entry points:
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)
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.
Another aspect you should be aware of:
With some comments you mentioned "host" and "guest" attributions available in current messenger examples. This actually is a logical structure of a tagging system provided with those messengers. The messages are still sent from a client to a server and then being retrieved by other clients. Whether a client can see a message is determined by the client being eligible to the specific tag. E.g posting a message to a contact from yours (user b) just tags the message with the tag "for_user_b" and as such it is only visible to the poster and anybody that is also allowed to read "for_user_b" tag messages (user b in our example). So, please be aware that the logical structure of a messaging system is determined by the access and distribution policy and not by the physical distribution structure!
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;
public class SimpleChat {
private static boolean isRunning = true;
private static Sender sender;
private static Receiver receiver;
public static void main(String[] args) throws IOException {
if(args.length < 3){
showUsage();
}
try {
receiver = new Receiver(Integer.parseInt(args[1]));
sender = new Sender(args[0], args[2], Integer.parseInt(args[3]));
} catch (InterruptedException e) {
showUsage();
}
// Read user input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Chat started. Type '\\exit' to quit.");
while(isRunning) {
String input = br.readLine();
if(input.equals("\\exit")){
receiver.stop();
sender.stop();
isRunning = false;
} else {
sender.sendMessage(input);
}
}
}
static void showUsage(){
System.out.println("Usage: java SimpleChat.java listening_port target_IP target_port");
System.exit(1);
}
}
Receiver.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Receiver {
private boolean isRunning = true;
public Receiver(int listeningPort) throws IOException {
Runnable receiverT = new Runnable() {
public void run() {
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();
}
public void stop(){
isRunning = false;
}
}
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;
public class Sender {
private boolean isRunning = true;
private volatile List<String> msgs;
public Sender(String username, String targetIP, int targetPort) throws InterruptedException, UnknownHostException, IOException {
msgs = Collections.synchronizedList(new ArrayList<String>());
Runnable senderT = new Runnable() {
public void run() {
try {
Socket socket = new Socket(targetIP, targetPort);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while(isRunning) {
synchronized(msgs){
Iterator<String> it = msgs.iterator();
while(it.hasNext()){
out.println(username + ": " + it.next());
}
// Clear messages to send
msgs.clear();
}
}
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();
}
public void stop(){
isRunning = false;
}
public void sendMessage(String msg){
synchronized(msgs){
msgs.add(msg);
}
}
}
As the 'showUsage()' says, use this program as follows:
java SimpleChat.java username listening_port target_ip target_port
Example:
java SimpleChat.java Supuhstar 1234 127.0.0.1 1234
[To talk to yourself]
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.
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;
public class SimpleChat {
protected boolean running = true;
protected int port;
private Thread server;
public static void main(String... arg) {
//create 2 clients in the localhost to test
SimpleChat app1 = new SimpleChat(8989);
SimpleChat app2 = new SimpleChat(8988);
app1.sendMessage("localhost", 8988, "Message from app1 to app2");
app2.sendMessage("localhost", 8989, "Message from app2 to app1");
System.exit(0); // ugly way to kill the threads and exit
}
public SimpleChat(int port) {
this.port = port;
start();
}
public void start() {
server = new Thread(new Server());
server.start();
}
public boolean sendMessage(String host, int port, String message) {
try {
//Connect to a server on given host and port and "send" the message
InetSocketAddress destination
= new InetSocketAddress(host, port);
Socket s = SocketFactory.getDefault().createSocket();
s.connect(destination);
OutputStream out = s.getOutputStream();
out.write(message.getBytes());
out.flush();
out.close();
s.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void messageRecived(String message) {
System.out.println("Message recived: " + message);
}
public void stop() {
this.running = false; // only stop after a socked connection
}
class Server implements Runnable {
public void run() {
try {
//Create a server socket to recieve the connection
ServerSocket ss = ServerSocketFactory.getDefault()
.createServerSocket(port);
while (running) {
Socket s = ss.accept();
InputStream in = s.getInputStream();
StringBuilder message = new StringBuilder();
int len;
byte[] buf = new byte[2048];
while ((len = in.read(buf)) > -1) {
if (len > 0) {
message.append(new String(buf, 0, len));
}
}
messageRecived(message.toString());
}
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
}
}

Java programming accessing object variables

Helo, there are 3 files, CustomerClient.java, CustomerServer.java and Customer.java
PROBLEM: In the CustomerServer.java file, i get an error when I compile the CustomerServer.java at line : System.out.println(a[k].getName());
ERROR:
init:
deps-jar:
Compiling 1 source file to C:\Documents and Settings\TLNA\My Documents\NetBeansProjects\Server\build\classes
C:\Documents and Settings\TLNA\My Documents\NetBeansProjects\Server\src\CustomerServer.java:44: cannot find symbol
symbol : method getName()
location: class Customer
System.out.println(a[k].getName());
1 error
BUILD FAILED (total time: 0 seconds)
CustomerClient.java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CustomerClient extends JApplet {
private JTextField jtfName = new JTextField(32);
private JTextField jtfSeatNo = new JTextField(32);
// Button for sending a student to the server
private JButton jbtRegister = new JButton("Register to the Server");
// Indicate if it runs as application
private boolean isStandAlone = false;
// Host name or ip
String host = "localhost";
public void init() {
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(2, 1));
p1.add(new JLabel("Name"));
p1.add(jtfName);
p1.add(new JLabel("Seat No."));
p1.add(jtfSeatNo);
add(p1, BorderLayout.CENTER);
add(jbtRegister, BorderLayout.SOUTH);
// Register listener
jbtRegister.addActionListener(new ButtonListener());
// Find the IP address of the Web server
if (!isStandAlone) {
host = getCodeBase().getHost();
}
}
/** Handle button action */
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
// Establish connection with the server
Socket socket = new Socket(host, 8000);
// Create an output stream to the server
ObjectOutputStream toServer =
new ObjectOutputStream(socket.getOutputStream());
// Get text field
String name = jtfName.getText().trim();
String seatNo = jtfSeatNo.getText().trim();
// Create a Student object and send to the server
Customer s = new Customer(name, seatNo);
toServer.writeObject(s);
} catch (IOException ex) {
System.err.println(ex);
}
}
}
/** Run the applet as an application */
public static void main(String[] args) {
// Create a frame
JFrame frame = new JFrame("Register Student Client");
// Create an instance of the applet
CustomerClient applet = new CustomerClient();
applet.isStandAlone = true;
// Get host
if (args.length == 1) {
applet.host = args[0];
// Add the applet instance to the frame
}
frame.add(applet, BorderLayout.CENTER);
// Invoke init() and start()
applet.init();
applet.start();
// Display the frame
frame.pack();
frame.setVisible(true);
}
}
CustomerServer.java
import java.io.*;
import java.net.*;
public class CustomerServer {
private String name;
private int i;
private ObjectOutputStream outputToFile;
private ObjectInputStream inputFromClient;
public static void main(String[] args) {
new CustomerServer();
}
public CustomerServer() {
Customer[] a = new Customer[30];
try {
// Create a server socket
ServerSocket serverSocket = new ServerSocket(8000);
System.out.println("Server started ");
// Create an object ouput stream
outputToFile = new ObjectOutputStream(
new FileOutputStream("student.dat", true));
while (true) {
// Listen for a new connection request
Socket socket = serverSocket.accept();
// Create an input stream from the socket
inputFromClient =
new ObjectInputStream(socket.getInputStream());
// Read from input
//Object object = inputFromClient.readObject();
for (int k = 0; k <= 2; k++) {
if (a[k] == null) {
a[k] = (Customer) inputFromClient.readObject();
// Write to the file
outputToFile.writeObject(a[k]);
//System.out.println("A new student object is stored");
System.out.println(a[k].getName());
break;
}
if (k == 2) {
//fully booked
outputToFile.writeObject("All seats are booked");
break;
}
}
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
inputFromClient.close();
outputToFile.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
Customer.java
public class Customer implements java.io.Serializable {
private String name;
private String seatno;
public Customer(String name, String seatno) {
this.name = name;
this.seatno = seatno;
}
public String getName() {
return name;
}
public String getSeatNo() {
return seatno;
}
}
The build message says its only compiling one source file. Perhaps the Customer class changed to include the getName function and has not been recompiled since.
Did you try compiling all three source files at the same time?
Recompile the Customer.java and make sure you don't have duplicate versions of the class file hanging around. Use debugger (set breakpoint after the customer class de-serialization) for further debugging.

Categories

Resources