So, i am trying to create a Client Server chat program. Since, i don't have an external server so my client and server will be hosted in my computer. Now, i was following online tutorials and created the Server side of the chat program but then i get an error while i test the Server side of the program. When i create the server socket, what port number should i put if i am using my computer. I used a random number and i get the following errors:-
Can someone please help me to fix the error or suggest me what should i do? Thanks
This is my Server class:-
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.io.*;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Server extends JFrame {
private JTextField usertext;
private JTextArea chatwindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
public Server()
{
super("Missy's Instant Messenger");//This sets the title of the messenger window
usertext = new JTextField(); //this is for creating the textfield where the user will enter data
usertext.setEditable(false);//this is set to false such that the user can only send message if he is connected to someone
usertext.addActionListener( //this activity is for sending the message when the user clicks on enter
new ActionListener(){
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand());
usertext.setText(" ");
}
/* private void sendMessage(String string) {
// TODO Auto-generated method stub
}*/
});
add(usertext,BorderLayout.NORTH);
chatwindow = new JTextArea();
add(new JScrollPane(chatwindow));
setSize(500,500);
}
public void startrunning(){
try {
server = new ServerSocket(6800,100);
//6789 is the port number and 100 is the number of people that can wait in the queue to connect to the server
while(true)
{
try{
waitforConnection();//this is to connect to the server
setupStreams();//setting up the input and output streams to send and receive messages
whilechatting();//this is allow to send messages using the input and output streams
}catch (Exception e)
{
showMessage("Connection has ended");//this will be displayed when the connection is ended by the server
}finally{
closecrap(); //close all the streams and sockets
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void waitforConnection() throws IOException
{
showMessage("waiting for someone to connect.....");
connection = server.accept(); //this will connect the server and the client
showMessage("Now connected to "+connection.getInetAddress().getHostName());
}
private void setupStreams() throws IOException
{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("Your streams are now set up......");
}
private void whilechatting() throws IOException
{
String message = "You are now connected";
sendMessage(message);
abletotype(true);
do{
try{
message = (String)input.readObject();
showMessage("\n" +message);
}catch(ClassNotFoundException e)
{
showMessage("wtf is that");
}
}while(!message.equals("CLIENT END"));
}
private void showMessage(final String a)
{
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
chatwindow.append(a);
}
}
);
// System.out.println(a);
}
public void closecrap()
{
showMessage("\n Connections closing .....");
abletotype(false);
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException)
{
ioException.printStackTrace();
}
}
public void sendMessage(String message)
{
try{
output.writeObject("SERVER - "+message);//this is where you put the message in the output stream
output.flush(); //flush out the junk if there is any left
showMessage("\nSERVER -"+message); //show Message in the chat window
}catch(Exception e)
{
chatwindow.append("\n ERROR sending the message dude");
}
}
private void abletotype(final Boolean t)
{
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
usertext.setEditable(t);
}
}
);
}
}
Servertest class:-
import javax.swing.*;
public class ServerTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Server st = new Server();
st.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
st.startrunning();
}
}
References:- ThenewBoston.com
I am going to summarize what has been said in some of the comments, and add my own thoughts.
First and foremost, the port is likely already in use. Its probably not in use by your program from what you said, however some other program is using it or has it reserved. As far as I know there is no official use for port 100, so it is likely just another program you have installed on your machine. Also from the comments it seems you have fixed this by swapping to a different port.
Connection.close() should work fine for closing the connection. For more information check out this link: How can I close the socket in a proper way?
As far as your most recent comment goes - if the program is running but the UI is not appearing, you likely have another issue with the code unrelated to your posted issue. I might suggest attempting to debug it on your own from here now that the server is starting without the JVM_BIND error and see what you come up with.
Related
I created a chat app in Java it worked when i open server and clients on different terminals but same computer. Today i gave it to my friend to test it over internet and its not working(Connection timed out ,yes i am using muiltithreads). I have allowed port (i am using 4242) in my firewall and my friends. But still not working.
I have read couple of similar question asked on internet but each has different steps (none working) and also i am not getting all steps though.
Some said that router is hiding my ip address so i need to enable port forwarding (i dont know how) . Also there must be a way without it. Many software works like this but doesnt need us to enable port forwarding. Will using a mobile hotspot instead of modem work(I am so DUMB!).
i am noob in this area, studied networking in JAVA yesterday and made app yesterday night. Help me run my app over internet in simple language. Will be gratefull if it works without port forwarding and static ip address. Let me know if you need to see my code.
Server Side:
import java.io.*;
import java.net.*;
import java.util.*;
class DailyAdviceS
{
ArrayList<PrintWriter> Clients=new ArrayList<PrintWriter>();
Socket sock;
public static void main(String args[])
{
DailyAdviceS ad= new DailyAdviceS();
ad.go();
}
private void go()
{
try
{
ServerSocket server= new ServerSocket(4242);
InetAddress ip;
ip = InetAddress.getLocalHost();
System.out.println("Current IP address : " + ip.getHostAddress());
while(true)
{
sock=server.accept();
PrintWriter writer = new PrintWriter(sock.getOutputStream());
Clients.add(writer);
Thread foundR= new Thread(new nodeR(sock));
foundR.start();
System.out.println("got a connection");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void SendAll(String Chat,String name)
{
Iterator it=Clients.iterator();
while(it.hasNext())
{
try
{
PrintWriter writer= (PrintWriter)it.next();
writer.println(name+" /t "+Chat);
writer.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
class nodeR implements Runnable //recieve message from clients
{
private String hostName;
private BufferedReader reader;
public nodeR(Socket s)
{
try
{
String hostName = s.getInetAddress().getHostName();
System.out.println(hostName);
InputStreamReader in= new InputStreamReader(s.getInputStream());
reader = new BufferedReader(in);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
String Message;
try
{
String Name=InetAddress.getLocalHost().getCanonicalHostName();
SendAll(Name+" Ready","");
while(true)
{
while ((Message=reader.readLine())!=null)
{
SendAll(Message,Name);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
CLient Side:
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.text.*;
class DailyAdvice
{
private JTextArea ar= new JTextArea(100,100);
private JTextField field = new JTextField(17);
private JButton button;
private Socket chat;
private InputStreamReader stream;
private BufferedReader reader;
private PrintWriter writer;
public static void main(String args[])
{
DailyAdvice ad= new DailyAdvice();
ad.setnw();
ad.go();
}
private void go()
{
JFrame frame= new JFrame("Chat with RedHead");
JPanel panel= new JPanel();
ar.setLineWrap(true);
ar.setWrapStyleWord(true);
ar.setEditable(false);
JScrollPane scroll= new JScrollPane(ar);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
panel.add(field);
DefaultCaret caret = (DefaultCaret) ar.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
button= new JButton("Send");
panel.add(button);
frame.getRootPane().setDefaultButton(button);
frame.add(scroll,BorderLayout.CENTER);
frame.add(panel,BorderLayout.SOUTH);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setBounds(50,50,300,300);
frame.setVisible(true);
Runnable r= new Recieve();
Thread send= new Thread(new Send());
Thread recieve= new Thread(r);
send.start();
recieve.start();
}
private void setnw()
{
try
{
chat = new Socket("122.176.8.153",4242);
stream= new InputStreamReader(chat.getInputStream());
reader= new BufferedReader(stream);
writer = new PrintWriter(chat.getOutputStream());
System.out.println("connection established");
}
catch(Exception e)
{
e.printStackTrace();
}
}
class Send implements Runnable
{
public void run()
{
button.addActionListener(new timetosend());
}
class timetosend implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
try
{
String msg =field.getText();
writer.println(msg);
writer.flush();
}
catch (Exception ex)
{
ex.printStackTrace();
}
field.setText("");
}
}
}
class Recieve implements Runnable
{
public void run()
{
try
{
String input;
while ((input= reader.readLine())!=null)
{
String[] result=input.split("/t");
ar.append(result[0]+" : "+result[1]+'\n');
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
Please make sure your application is not using the private IP to connect to your server if accessing over the internet. you can check your PC's public IP from the site below which is currently allocated to your PC, and can use this in your client apps.
And also make sure you have configure the port in port forwarding in your switch/router and if it is not allowed by your ISP, you can use any port forwarding software on your PC to do that.
http://www.get-myip.com/
I want to ask why the server is showing only the first time one of the clients send data ,my intent is to have two clients and just want to send some integer ,the server to read it and then send it back to the other client and then to wait the this client to send info and send it to the other client (toggling them).But only the first time the data is sended ,it is read on the server ?
Server :
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket serv;
private DataInputStream inFromClient1;
private DataOutputStream outToClient1;
private DataInputStream inFromClient2;
private DataOutputStream outToClient2;
public Server(){
try {
serv=new ServerSocket(8000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void listen() throws IOException{
System.out.println("Listening for connections");
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
Socket sock1;
Socket sock2;
try {
sock1 = serv.accept();
sock2=serv.accept();
handleSession(sock1,sock2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
public void handleSession(Socket s1,Socket s2) throws IOException{
DataInputStream in1=new DataInputStream(s1.getInputStream());
DataOutputStream out1=new DataOutputStream(s1.getOutputStream());
DataInputStream in2=new DataInputStream(s1.getInputStream());
DataOutputStream out2=new DataOutputStream(s1.getOutputStream());
while(true){
int inint1=in1.readInt();
System.out.println("Recived from 1 " + inint1);
System.out.println("Sending to 2 ");
out2.writeInt(in1.readInt());
int inint2=in2.readInt();
System.out.println("Recived from 2 " + inint2);
System.out.println("Sending to 1 ");
out1.writeInt(inint2);
}
}
public static void main(String[] args) throws IOException {
new Server().listen();
}
}
Client :
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Client extends JFrame implements ActionListener{
private JPanel mainPanel;
private JButton[] buttons;
private Socket socket;
private int number;
private DataInputStream fromServer;
private DataOutputStream toServer;
private boolean myTurn=true;
public Client() throws UnknownHostException, IOException{
mainPanel=new JPanel(new GridLayout(3,3));
socket=new Socket("localhost",8000);
add(mainPanel);
addbuttons();
setSize(new Dimension(500,400));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void addbuttons(){
buttons=new JButton[9];
for(int i=1;i<10;i++){
buttons[i-1]=new JButton("Rectangle " + i);
buttons[i-1].addActionListener(this);
mainPanel.add(buttons[i-1]);
}
}
public void actionPerformed(ActionEvent arg0) {
JButton butt=(JButton) arg0.getSource();
String str=butt.getText();
String[] splitStr=str.split(" ");
number=Integer.parseInt(splitStr[1]);
System.out.println(number);
}
public void start() throws IOException{
fromServer=new DataInputStream(socket.getInputStream());
toServer=new DataOutputStream(socket.getOutputStream());
new Thread(new Runnable() {
#Override
public void run() {
Scanner in=new Scanner(System.in);
while(true){
System.out.println("Write some integer");
int inint=in.nextInt();
System.out.println("Before " + myTurn);
if(myTurn){
try {
toServer.writeInt(inint);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myTurn=false;
}
else{
int fromServint=0;
try {
fromServint=fromServer.readInt();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Recived integer " + fromServint);
buttons[fromServint].setText("Some new Text");
myTurn=true;
}
System.out.println("After " + myTurn);
}
}
}).start();
}
public static void main(String[] args) throws UnknownHostException, IOException {
new Client().start();
}
}
Looks like you're reading 2 integers from client 1 (guessing it's a typo) so
try changing
out2.writeInt(in1.readInt());
to
out2.writeInt(inint1);
Also, as #JohnBollinger mentioned,
Separate Data*Streams are created, but both sets are connected to socket s1, instead of one set to each socket.
DataInputStream in1=new DataInputStream(s1.getInputStream());
DataOutputStream out1=new DataOutputStream(s1.getOutputStream());
DataInputStream in2=new DataInputStream(s1.getInputStream());
DataOutputStream out2=new DataOutputStream(s1.getOutputStream());
All streams here are referencing the same client.
You are using blocking sockets. For that reason, when you call any kind of "read" method, it will block until data is received from the client.
So, one thread is not enough. The first read will block, the second read will never be executed unless the first client actually sent something.
Solution 1: Use one thread per socket connection (recommended, because easier).
Solution 2: Use non-blocking sockets (not recommended, difficult but good for certain performance critical scenarios).
Look here:
int inint1=in1.readInt();
System.out.println("Recived from 1 " + inint1);
System.out.println("Sending to 2 ");
out2.writeInt(in1.readInt());
First you read an int from the first client. Then you print some stuff and read a second int from the same client. But the client waits for a int from the server and therefore sends no second, so the server blocks.
Replace the last line of the code above with out2.writeInt(inint1); and see if it works. I haven't read all of the code, so I am not sure if there is another mistake.
I watched a tutorial on simple Java networking, and the tutorial showed the server and client application running on the same computer and it worked, I was wondering if there's a way to make it work on different computers in different homes using port forwarding or something else; Here is my code:
Server.java:
package com.cloud.server;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* The Server class extends JFrame and contains all of the code pertaining to the GUI and the server
*
* #author mcjcloud
*
*/
public class Server extends JFrame
{
private JTextField userInput;
private JTextArea convo;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server; // establishes server
private Socket connection; // establishes connection with other computer
/**
* Constructor (basically just sets up the GUI and actionListener(s)
*/
public Server()
{
super("Cloud Messenger");
userInput = new JTextField();
userInput.setEditable(false);
userInput.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
sendMessage(e.getActionCommand());
userInput.setText("");
}
});
add(userInput, BorderLayout.SOUTH);
// set up convo (JTextArea)
convo = new JTextArea();
add(new JScrollPane(convo));
setSize(500, 700);
setLocationRelativeTo(null);
setVisible(true);
}
/**
* startServer() method waits for connection, sets up connection and manages chat
*/
public void startServer()
{
try
{
server = new ServerSocket(6789, 100, InetAddress.getByName("0.0.0.0")); // (port number, backlog) backlog (aka qlength) = "how many people can connect at a time"
while(true) // infinite loop
{
try
{
waitForConnection(); // first set up the connection
setupStreams(); // set up the streams
chat(); // enable the chat and things
}
catch(EOFException eofe) // EOF = EndOfStream (meaning the input/output stream ended)
{
showMessage("Connection terminated.");
}
finally
{
cleanUpConnection();
}
}
}
catch(IOException io)
{
io.printStackTrace();
}
}
/**
* waitForConnection() method will wait for the connection, then display connection info
*
* #throws IOException
*/
private void waitForConnection() throws IOException
{
showMessage("Waiting for connection...");
connection = server.accept(); // listens for a connection
showMessage("Now connected to " + connection.getInetAddress().getHostName());
}
/**
* setupStream() method gets a stream to send/recieve data
*/
private void setupStreams() throws IOException
{
// setup output stream
output = new ObjectOutputStream(connection.getOutputStream()); // create pathway to allow us to connect to the computer the socket is connected to
output.flush();
// setup input stream
input = new ObjectInputStream(connection.getInputStream()); // create pathway to receive messages
showMessage("Stream setup success.");
}
/**
* chat() method code runs during conversation
*/
private void chat() throws IOException
{
String message = "Chatting enabled";
showMessage(message);
setCanType(true);
do
{
try
{
message = (String) input.readObject();
showMessage(message);
}
catch(ClassNotFoundException cnfe)
{
showMessage("Message recieve failed (Other person's problem)");
}
}
while(!message.equals("CLIENT - /terminate"));
}
/**
* cleanUpConnection() method cleans up the stream and things after the chat has ended
*/
private void cleanUpConnection()
{
showMessage("Closing connection...");
setCanType(false);
try
{
output.close();
input.close();
connection.close();
}
catch(IOException io)
{
io.printStackTrace();
}
}
/**
* sendMessage(String) method sends whatever message you type
*
* #param message is what is going to be shown
*/
private void sendMessage(String message)
{
try
{
output.writeObject("SERVER - " + message); // write the message to the outputstream
output.flush();
showMessage("SERVER - " + message);
}
catch(IOException io)
{
convo.append("ERROR: Message can't be sent.");
}
}
/**
* showMessage(String)shows whatever needs to be shown on the JTextArea
*/
private void showMessage(String message)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
convo.append(" " + message + "\n");
}
});
}
/**
* setCanType() method decides whether or not a user can type
*
* #param canType
*/
private void setCanType(boolean canType)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
userInput.setEditable(canType);
}
});
}
}
InvokeServer.java:
package com.cloud.server;
import javax.swing.JFrame;
public class InvokeServer
{
public static void main(String[] args)
{
Server server = new Server();
server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
server.startServer();
}
}
Client.java:
package com.cloud.client;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* Client class is the sister of the Server class in the server application, contains all the code to build GUI and send info to server and receive
*
* #author mcjcloud
*
*/
public class Client extends JFrame
{
private JTextField userInput;
private JTextArea convo;
private ObjectOutputStream output;
private ObjectInputStream input;
private String message = "";
private String serverIP; // connecting to a specific server
private Socket connection;
public Client(String host)
{
super("Cloud Messenger");
serverIP = host;
userInput = new JTextField();
userInput.setEditable(false);
userInput.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
sendMessage(e.getActionCommand());
userInput.setText("");
}
});
add(userInput, BorderLayout.SOUTH);
convo = new JTextArea();
add(new JScrollPane(convo));
setSize(500, 700);
setLocationRelativeTo(null);
setVisible(true);
}
/**
* startClient() method invokes the whole conversation
*/
public void startClient()
{
try
{
boolean connected = false;
showMessage("Connecting to server...");
while(!connected)
{
try
{
connected = connectToServer();
}
catch(ConnectException ce)
{
// do nothing
}
}
setupStreams();
chat();
}
catch(EOFException eofe)
{
sendMessage("Connection terminated.");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
finally
{
cleanUpConnection();
}
}
/**
* connectToServer() establishes connection with the server application
*
* #throws IOException
*/
private boolean connectToServer() throws IOException
{
connection = new Socket(InetAddress.getByName(serverIP), 6789);
showMessage("Now connected to " + connection.getInetAddress().getHostName());
return true;
}
/**
* setupStream() method gets a stream to send/recieve data
*/
private void setupStreams() throws IOException
{
// setup output stream
output = new ObjectOutputStream(connection.getOutputStream()); // create pathway to allow us to connect to the computer the socket is connected to
output.flush();
// setup input stream
input = new ObjectInputStream(connection.getInputStream()); // create pathway to receive messages
showMessage("Stream setup success.");
}
/**
* chat() method code runs during conversation
*/
private void chat() throws IOException
{
String message = "Chatting enabled";
showMessage(message);
setCanType(true);
do
{
try
{
message = (String) input.readObject();
showMessage(message);
}
catch(ClassNotFoundException cnfe)
{
showMessage("Message recieve failed (Other person's problem)");
}
}
while(!message.equals("SERVER - /terminate"));
}
/**
* cleanUpConnection() method cleans up the stream and things after the chat has ended
*/
private void cleanUpConnection()
{
showMessage("Closing connection...");
setCanType(false);
try
{
output.close();
input.close();
connection.close();
}
catch(IOException io)
{
io.printStackTrace();
}
}
/**
* sendMessage(String) method sends whatever message you type
*
* #param message is what is going to be shown
*/
private void sendMessage(String message)
{
try
{
output.writeObject("CLIENT - " + message); // write the message to the outputstream
output.flush();
showMessage("CLIENT - " + message);
}
catch(IOException io)
{
convo.append("ERROR: Message can't be sent.");
}
}
/**
* showMessage(String) shows whatever needs to be shown on the JTextArea
*/
private void showMessage(String message)
{
SwingUtilities.invokeLater(new Runnable() // USE THIS RUNNABLE TO UPDATE GUI
{
public void run()
{
convo.append(" " + message + "\n");
}
});
}
/**
* setCanType() method decides whether or not a user can type
*
* #param canType
*/
private void setCanType(boolean canType)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
userInput.setEditable(canType);
}
});
}
}
InvokeClient.java:
package com.cloud.client;
import javax.swing.JFrame;
public class InvokeClient
{
public static void main(String[] args)
{
Client client = new Client("99.25.233.116");
client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.startClient();
}
}
Note:
I tried setting up port forwarding on my home network with the port 6789 to one of my laptops, and that's the laptop I run the server application on.
I solved it. I just undid and redid the port forwarding again and it worked with the public IP address. Thank you all for your help
I have a problem using an ObjectInputStream and I have been struggling with it for 2 days now. I tried to search for a solution but unfortunately found no fitting answer.
I am trying to write a client/server application in which the client sends objects (in this case a configuration class) to the server. The idea is that connection keeps alive after sending the object so it is possible to send a new object if necessary.
Here are the important parts of my client code:
mSocket = new Socket("192.168.43.56", 1234);
mObjectIn = new ObjectInputStream(mSocket.getInputStream());
mObjectOut = new ObjectOutputStream(mSocket.getOutputStream());
mObjectOut.writeObject(stubConfig);
mObjectOut.flush();
In the above code, I left out some try/catch blocks to keep the code readable for you.
The server side looks as follows:
mHostServer = new ServerSocket(port);
mSocket = mHostServer.accept();
// create streams in reverse oreder
mObjectOut = new ObjectOutputStream(mConnection.getOutputStream());
mObjectOut.flush();
mObjectIn = new ObjectInputStream(mConnection.getInputStream());
while (mIsSocketConnected)
{
StubConfig = (StubConfiguration)mObjectIn.readObject();
}
What I want to achieve is that as long at the socketconnection is alive, the server is listening for incoming config objects.
When I run my program however, I got an EOFException in the while loop at server side. I receive the first config object without any problems in the first iteration of the while loop but after that I get an EOFException every time readObject() is called.
I am looking for a way to solve this. Can anyone put me in the good direction?
EDIT: What I read about the EOFException is that it is thrown when you want to read from a stream when the end of it is reached. That means that for some reason the stream ended after the object has been send. Is there a way to reinitialize the streams or so??
EOFException is thrown by readObject() when the peer has closed the connection. There can never be more data afterwards. Ergo you can't have written multiple objects at all: you closed the connection instead.
try using this
Server side
1.Server running on a separate thread
public class ServeurPresence implements Runnable {
public final static int PORT = 20000 ;
public final static String HOSTNAME = "localhost" ;
public static enum Action {CONNEXION, MSG, DECONNEXION,USER, FINCLASSEMENT};
ServerSocket serveur ;
static List<String> names ;
*/
public ServeurPresence()
{
System.out.println("Start Server...");
try
{
serveur = new ServerSocket(PORT) ;
new Thread(this).start();
//javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI();} } );
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* #param args
*/
public static void main(String[] args)
{
new ServeurPresence();
}
#Override
public void run()
{
System.out.println("server runs");
while(true)
{
try {
Socket sock = serveur.accept();
ServiceClientsThread thread= new ServiceClientsThread(sock);
thread.start();
}
catch (IOException e)
{
System.out.println("Error with socket");
e.printStackTrace();
}
}
}
}
2. A Thread to handle each Client:ServiceClientThread
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ServiceClientsThread extends Thread{
private Socket sock ;
ServiceClientsThread(Socket sock)
{
//super();
this.sock=sock;
}
#Override
public void run()
{
DataInputStream is ;
DataOutputStream os ;
String name =null ;
try {
is = new DataInputStream(sock.getInputStream()) ;
os = new DataOutputStream(sock.getOutputStream()) ;
ServeurPresence.Action act ;
do {
// read Action
act = ServeurPresence.Action.valueOf(is.readUTF()) ; // read string -> enum
System.out.println("action :"+act);
switch (act) {
case CONNEXION :
name = is.readUTF(); //read client name
System.out.println("Name :"+name);
os.writeUTF("Hi");//send welcome msg
break ;
case MSG :
String msg = is.readUTF();
os.writeUTF("OK");//response
break ;
case DECONNEXION :
System.out.println(name+" is logged out");
break ;
}
} while (act!=ServeurPresence.Action.DECONNEXION) ;
// the end
is.close();
os.close();
sock.close();
} catch (IOException e)
{
System.out.println("Error with "+name+" socket");
e.printStackTrace();
}
}
}
3. Client side
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
/**
*
*/
Client(String name)
{
System.out.println("Start Client...");
try {
Socket sock = new Socket(ServeurPresence.HOSTNAME,ServeurPresence.PORT) ;
DataOutputStream os = new DataOutputStream(sock.getOutputStream()) ;
DataInputStream is = new DataInputStream(sock.getInputStream()) ;
System.out.println("Send "+name+" to server");
// CONNECTION : Action then value
os.writeUTF(ServeurPresence.Action.CONNEXION.name()) ; // send action : write enum -> String
os.writeUTF(name) ; // send the name
//read server welcome msg
String msg = is.readUTF();
System.out.println("Welcome msg: "+msg);
/* Your actions here : see example below */
try
{
Thread.currentThread().sleep(4000);
os.writeUTF(ServeurPresence.Action.MSG.name()) ; // send action : write enum -> String
os.writeUTF("My message here") ; // send msg
Thread.currentThread().sleep(4000);
msg = is.readUTF();//server response message
}
catch (InterruptedException e)
{
e.printStackTrace();
}
/************************************************/
//CLOSE
os.writeUTF(ServeurPresence.Action.DECONNEXION.name()) ; // send action
System.out.println("Log out");
os.close();
sock.close();
}
catch (UnknownHostException e)
{
System.out.println(ServeurPresence.HOSTNAME+ " unknown");
e.printStackTrace();
}
catch (IOException e)
{
System.out.println("Impossible to connect to "+ServeurPresence.HOSTNAME+ ":"+ServeurPresence.PORT);
e.printStackTrace();
}
}
}
4. In your case use readObject()/writeObject() instead of readUTF()/writeUTF() to write your config objects
Try this and let me know how it goes:
while (1==1)
{
StubConfig = (StubConfiguration)mObjectIn.readObject();
Thread.sleep(100); //Saves CPU usage
}
Very late answer, but just for future reference. I have been having problems sending Objects via sockets because the method flush() is not working properly.
I solved this problem just by switching flush() to reset().
I would really appreciate help with my program. It is some sort of chat server with multiple clients.
Here's the server code:
package com.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static int PORT;
private ServerSocket server;
private Socket socket;
public Server(int port) throws IOException {
PORT = port;
server = new ServerSocket(PORT);
System.out.println("server started");
try {
while (true) {
socket = server.accept();
try {
new ServeClient(socket);
} catch (IOException e) {
socket.close();
}
}
} finally {
server.close();
}
}
public static void main(String[] args) throws IOException {
int port = Integer.parseInt(args[0]);
Server server = new Server(port);
}
}
I start the server and then create a Client. The server receives connection socket from socket
and creates a ServeClient Thread.
Here's ServeClient code:
package com.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;
import com.gui.WindowManager;
public class ServeClient extends Thread {
private final Socket socket;
private BufferedReader in;
private PrintWriter out;
private String msg;
public static final String ENDSTRING = "END";
public static Vector clients = new Vector();
public ServeClient(final Socket socket) throws IOException {
this.socket = socket;
System.out.println("socket " + socket);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
start();
}
public void run() {
try {
clients.add(this);
while (true) {
msg = in.readLine();
if (msg == ENDSTRING)
break;
broadcast(msg);
}
System.out.println("closing...");
} catch (IOException e) {
System.err.println("IO EXCEPTION");
} finally {
try {
socket.close();
} catch (IOException e) {
System.err.println("SOCKET NOT CLOSED");
}
}
}
#SuppressWarnings("deprecation")
public void broadcast(String msg) {
synchronized (clients) {
Enumeration<ServeClient> e = clients.elements();
while (e.hasMoreElements()) {
ServeClient serveClient = e.nextElement();
try {
synchronized (serveClient.out) {
serveClient.out.println(msg);
}
} catch (Exception eee) {
serveClient.stop();
}
}
}
}
}
What i get is a NullPointerException when ServeClient invokes run() method
server started
socket Socket[addr=/127.0.0.1,port=51438,localport=8888]
Exception in thread "Thread-0" java.lang.NullPointerException
at com.server.ServeClient.run(ServeClient.java:33)
line 33 is the line with first "try" statement in ServeClient run() method
com.server.ServeClient.run(ServeClient.java:33)
I don't believe that it's happening at the try.
Open up an IDE, turn on debugging, and step through until you can see what's happening. That's the fastest way to figure out what you've missed.
There's an object that you're assuming is fine that is not. Find it.
Here's an example of how to do this properly:
http://www.kodejava.org/examples/216.html
Your problem is with the order in which static instance variables are initialised. Try doing something like:
...
private static Vector clients = null;
...
if (clients==null) {
clients = new Vector(); // consider putting this in a synchronized block
}
before you add the client to the vector.
Sorry for necroing such an old issue but it seemed like this problem wasn't resolved, so I'll give a bit of input from my end.
I've had a similar problem and the compiler also kept telling me that the problem was at the start() method. However, when I commented out the thread part and just ran the code on the same thread as the UI, the compiler directed me to the real source of the problem: the code inside the thread.
After making sure the code didn't give an error, I enclosed the code with the original thread code, and it stopped giving me the NullPointerException error.
Hope this helps someone along the way.
Remove the duplicate class declaration in JPanel.
I was trying to run a timer thread that updated a clock in the main application window.
I had created the JFrame with Eclipse/WindowBuilder and had followed a tutorial on how to make a timer. I had copied the declaration of the textfield into the class declaration to make it available for the entire class, but forgot to remove the Class Id in front of the widget definition. So it still initialized the local instance and not the global one. Thus when I accessed the global one it was still null.