Application is stopping because Memory usage is too high - java

Every 50 Miliseconds I am taking a Screenshot and sending it to another Computer which is showing the Screenshot. I am mirroring the Desktop. Now the problem is the Program is stopping because the Memory usage is getting too high. My Question is how can I "clear" the RAM - I already googled and found out that I should use the Garbage Collector but this isn't working. Here is my code:
CLIENT:
Client.java
import java.awt.AWTException;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ConnectException;
import java.net.Socket;
import java.net.SocketException;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
public class Client implements Runnable {
private Socket socket;
private ObjectInputStream din;
private static ObjectOutputStream dout;
public Client(String ip, int port) {
try {
socket = new Socket(ip, port);
din = new ObjectInputStream(socket.getInputStream());
dout = new ObjectOutputStream(socket.getOutputStream());
} catch (ConnectException e) {
JOptionPane.showMessageDialog(null, "Server is offline");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Thread.sleep(50);
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
ImageIO.write(screenFullImage, "jpeg", new File("C:\\Windows\\Temp\\screenshot.jpeg"));
} catch (IOException | AWTException | InterruptedException e) {
e.printStackTrace();
}
ImageIcon ii = new ImageIcon("C:\\Windows\\Temp\\screenshot.jpeg");
send(new Obj(ii));;
}
}
public static void send(Obj obj) {
try {
dout.writeObject(obj);
dout.flush();
} catch (SocketException e) {
JOptionPane.showMessageDialog(null, "Connection closed");
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() {
try {
dout.close();
din.close();
socket.close();
} catch (IOException e) {
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
// Connect to the Server
Client client = new Client("localhost", 9785);
// Runs a new Client
Thread clientThread = new Thread(client);
clientThread.start();
}
}
Obj.java
package ch.nyp.blj;
import java.io.Serializable;
import javax.swing.ImageIcon;
public class Obj implements Serializable {
private ImageIcon img;
public Obj(ImageIcon img) {
super();
this.img = img;
}
public ImageIcon getImg() {
return img;
}
public void setImg(ImageIcon img) {
this.img = img;
}
}
SERVER:
Main.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
GUI.open();
try {
ServerSocket s = new ServerSocket(9785);
System.out.println("Server Online");
while (true) {
Socket client = s.accept();
if (client != null) {
ClientThread ct = new ClientThread(client);
new Thread(ct).start();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Obj.java
import java.io.Serializable;
import javax.swing.ImageIcon;
public class Obj implements Serializable {
private ImageIcon img;
public Obj(ImageIcon img) {
super();
this.img = img;
}
public ImageIcon getImg() {
return img;
}
public void setImg(ImageIcon img) {
this.img = img;
}
}
GUI.java
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JLabel;
public class GUI {
public static JLabel img;
private JFrame frame;
public static Dimension d = new Dimension(400, 400);
/**
* Launch the application.
*/
public static void open() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GUI window = new GUI();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public GUI() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setSize(d.width, d.height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
img = new JLabel("");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(img, GroupLayout.DEFAULT_SIZE, 1924, Short.MAX_VALUE)
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(img, GroupLayout.DEFAULT_SIZE, 1181, Short.MAX_VALUE)
);
frame.getContentPane().setLayout(groupLayout);
}
}
ClientThread.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
public class ClientThread implements Runnable {
private Socket socket;
private ObjectOutputStream dout;
private ObjectInputStream din;
private static Obj input = null;
ClientThread(Socket socket) {
this.socket = socket;
try {
this.dout = new ObjectOutputStream(socket.getOutputStream());
this.din = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
#Override
public void run() {
try {
while (true) {
try {
input = (Obj) din.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
GUI.img.setIcon(input.getImg());
System.out.println(input.getImg());
}
} catch (SocketException e) {
Thread.currentThread().interrupt();
} catch (IOException e) {
}
}
}
Exception after some seconds:
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at java.base/java.lang.reflect.Array.newArray(Native Method)
at java.base/java.lang.reflect.Array.newInstance(Unknown Source)
at java.base/java.io.ObjectInputStream.readArray(Unknown Source)
at java.base/java.io.ObjectInputStream.readObject0(Unknown Source)
at java.base/java.io.ObjectInputStream.readObject(Unknown Source)
at java.desktop/javax.swing.ImageIcon.readObject(Unknown Source)
at java.base/jdk.internal.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at java.base/java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.base/java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.base/java.io.ObjectInputStream.readObject0(Unknown Source)
at java.base/java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.base/java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.base/java.io.ObjectInputStream.readObject0(Unknown Source)
at java.base/java.io.ObjectInputStream.readObject(Unknown Source)
at ch.nyp.blj.ClientThread.run(ClientThread.java:31)
at java.base/java.lang.Thread.run(Unknown Source)

Related

simple client server chat application not working

I am trying to a simple client server chat application using Stream sockets and Swing. But it is not working as it should. Apparently the server just waits for connection and does not proceed.
I have three java files, Server.java , Client.java and ChatApp.java
Server.java
package com.htpj.networkingChatApp;
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.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;
public class Server extends JFrame {
private static final long serialVersionUID = 1L;
private JTextArea displayArea;
private JTextField messageEnterField;
private ServerSocket server;
private Socket connectionSocket;
private ObjectInputStream input;
private ObjectOutputStream output;
private int counter = 1;
protected void serverGui() {
messageEnterField = new JTextField();
setMessageEnterFieldEditable(false);
messageEnterField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendDataToClient(e.getActionCommand());
}
});
add(messageEnterField, BorderLayout.SOUTH);
displayArea = new JTextArea();
add(new JScrollPane(displayArea), BorderLayout.CENTER);
displayArea.setEditable(false); // display area is never editable
setSize(500, 500);
setLocationRelativeTo(null);
setTitle("Chat Server");
setVisible(true);
}
protected void runServer() {
try {
server = new ServerSocket(2000, 100);
while (true) {
try {
waitForConnection(); // wait for a connection
getStreams(); // get input and output streams
processConnection(); // process connections
} catch (EOFException e) {
displayMessage("\n server terminated the connection");
} finally {
closeConnection();
++counter;
}
}
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF method runServer
private void waitForConnection() {
try {
displayMessage("Waiting for Connection\n");
connectionSocket = server.accept();
displayMessage("Connection" + counter + "received from: " + connectionSocket.getInetAddress() + "port: "
+ connectionSocket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF method waitForConnection
private void getStreams() throws IOException {
output = new ObjectOutputStream(connectionSocket.getOutputStream());
output.flush(); // flush output buffer to send header information
input = new ObjectInputStream(connectionSocket.getInputStream());
displayMessage("\n Got I/O Streams \n");
} // ENDOF getStreams method
private void processConnection() throws IOException {
String message = null;
sendDataToClient("Connection Successful \n");
setMessageEnterFieldEditable(true); // enable server to type message
do {
try {
message = (String) input.readObject();
displayMessage("\n" + message);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} while (!message.equals("CLIENT >> TERMINATE"));
} // ENDOF processConnection method
private void closeConnection() {
displayMessage("\n closing connection \n");
setMessageEnterFieldEditable(false);
try {
output.close();
input.close();
connectionSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF closeConnection method
private void sendDataToClient(String messageFromServer) {
try {
output.writeObject("SERVER>> " + messageFromServer);
output.flush(); // flush output to client
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF sendDataToClient method
private void displayMessage(String showMessage) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
displayArea.append(showMessage);
}
});
} // ENDOF method displayMessage
private void setMessageEnterFieldEditable(final boolean isEditable) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
messageEnterField.setEditable(isEditable);
}
});
}
} // ENDOF class server
Client.java
package com.htpj.networkingChatApp;
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.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Client extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField messageEnterField;
private JTextArea displayArea;
private String chatHost;
private Socket clientSocket;
private ObjectInputStream input;
private ObjectOutputStream output;
private String message = "";
public Client(String host) {
this.chatHost = host;
}
protected void clientGui() {
messageEnterField = new JTextField();
setMessageEnterFieldEditable(false);
messageEnterField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendDataToServer(e.getActionCommand());
}
});
add(messageEnterField, BorderLayout.SOUTH);
displayArea = new JTextArea();
add(new JScrollPane(displayArea), BorderLayout.CENTER);
displayArea.setEditable(false);
setTitle("Chat Client");
setSize(500, 500);
setLocationRelativeTo(null);
setVisible(true);
} // END OF clientGui method
// connect to the server and process message from server
protected void runClient() throws UnknownHostException, IOException, ClassNotFoundException {
// connect to server, get Streams, process connection
try {
connectToServer();
getStreams();
processConnection();
} catch (EOFException e) {
displayMessage("\n client closed the connection");
} finally {
closeConnection();
}
}
private void connectToServer() throws UnknownHostException, IOException {
displayMessage("Attempting Connection to Server: \n");
clientSocket = new Socket(InetAddress.getByName(chatHost), 2000);
displayMessage(
"Connected to: " + clientSocket.getInetAddress().getHostName() + "on Port : " + clientSocket.getPort());
} // END OF method connectToServer
private void getStreams() throws IOException {
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.flush();
input = new ObjectInputStream(clientSocket.getInputStream());
displayMessage("\n Got I/O stream \n ");
} // END OF getStreams method
private void processConnection() throws ClassNotFoundException, IOException {
displayMessage("\n connected to server\n");
setMessageEnterFieldEditable(true);
do {
message = (String) input.readObject();
displayMessage("\n" + message);
} while (!message.equals("SERVER>> TERMINATE"));
} // end of processConnection method
private void closeConnection() throws IOException {
displayMessage("\n closing connection ");
input.close();
output.close();
clientSocket.close();
setMessageEnterFieldEditable(false);
} // end of closeConnection method
private void displayMessage(final String messageToShow) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
displayArea.append(messageToShow);
}
});
} // end of displayMessage method
private void sendDataToServer(String messageToServer) {
try {
output.writeObject(messageToServer);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
} // end of sendDataToServer method
private void setMessageEnterFieldEditable(final boolean isEditable) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
messageEnterField.setEditable(isEditable);
}
});
}
}
ChatApp.java
package com.htpj.networkingChatApp;
import java.io.IOException;
public class ChatApp{
public static void main(String[] args) {
Server chatServer = new Server();
Client chatClient = new Client("127.0.0.1");
chatServer.serverGui();
chatClient.clientGui();
chatServer.runServer();
try {
chatClient.runClient();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
}

SocketChannel sockets not reading data

Here is my code. From the TestServer, I'm trying to send data through an outputstream and have it received from the test client. I'm using a SocketChannel because I need the client to listen on 3 ports at the same time. At the moment, i'm only trying to read from one socket. However it doesnt seem to be receiving any data from the server. For the run method of KBThread, if I uncomment the nodata println, that will execute over and over.
TestServer.java
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class TestServer extends JPanel implements KeyListener, MouseListener, MouseMotionListener {
private final int MAX_CLIENTS = 8;
JPanel listenerPanel = new JPanel();
JFrame listenerFrame = new JFrame();
static DataOutputStream kbOut;
static DataOutputStream mOut;
static Socket dataSocket;
public TestServer() {
this.setFocusable(true);
listenerPanel.addKeyListener(this);
listenerPanel.addMouseMotionListener(this);
listenerFrame.add(listenerPanel);
listenerFrame.setSize(1376,808); // 10 more x, 40 more y.
listenerFrame.setVisible(true);
listenerFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
listenerPanel.requestFocusInWindow();
}
public static void main(String[] args) {
new TestServer().startServer();
}
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(MAX_CLIENTS);
Runnable serverTask = () -> {
try {
ServerSocket serverSocket = new ServerSocket(1111);
System.out.println("Waiting for clients.");
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
}
} catch (IOException ex) {
System.err.println("Error with client socket.");
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private final Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
String clientIP = clientSocket.getInetAddress().getHostAddress();
System.out.println("Client connected from " + clientIP);
Socket kbSocket = new Socket(clientIP, 1112);
System.out.println("Keyboard socket connected to " + clientIP);
kbOut = new DataOutputStream(kbSocket.getOutputStream());
Socket mSocket = new Socket(clientIP, 1113);
System.out.println("Mouse socket connected to " + clientIP);
mOut = new DataOutputStream(mSocket.getOutputStream());
//new TestServer().startKBServer(clientIP);
//new TestServer().startMServer(clientIP);
try {
clientSocket.close();
} catch (IOException ex) {
}
} catch (IOException ex) {
Logger.getLogger(TestServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void startKBServer(String clientAddress) {
Runnable kbTask = () -> {
try {
Socket kbSocket = new Socket(clientAddress, 1112);
System.out.println("Keyboard socket connected to " + clientAddress);
new KBTask(kbSocket);
} catch (IOException ex) {
System.out.println("Error Calling Back " + clientAddress);
}
};
Thread kbThread = new Thread(kbTask);
kbThread.start();
}
private class KBTask implements Runnable {
private final Socket kbSocket;
private KBTask(Socket kbSocket) {
this.kbSocket = kbSocket;
}
#Override
public void run() {
try {
kbOut = new DataOutputStream(kbSocket.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(TestServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
#Override
public void keyPressed(KeyEvent ke) {
try {
int key = ke.getKeyCode();
System.out.println("Key Pressed: " + key);
kbOut.writeInt(key);
kbOut.flush();
} catch (IOException ex) {
System.out.println("Error writing key data to server");
}
}
#Override
public void keyReleased(KeyEvent ke) {
try {
int key = ke.getKeyCode();
System.out.println("Key Pressed: " + -key);
kbOut.writeInt(-key);
kbOut.flush();
} catch (IOException ex) {
System.out.println("Error writing -key data to server");
}
}
#Override
public void mouseMoved(MouseEvent me) {
try {
int mouseX = me.getX();
int mouseY = me.getY();
if (mOut != null) {
mOut.writeInt(mouseX);
mOut.writeInt(mouseY);
mOut.flush();
System.out.println("Mouse Moved To: " + mouseX + "," + mouseY);
}
} catch (IOException | NullPointerException ex) {
System.out.println("Error writing mouse data to server");
}
}
#Override
public void mouseClicked(MouseEvent me) {
}
#Override
public void mousePressed(MouseEvent me) {
}
#Override
public void mouseReleased(MouseEvent me) {
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
#Override
public void mouseDragged(MouseEvent me) {
}
#Override
public void keyTyped(KeyEvent ke) {
}
}
TestClient.java
import java.awt.AWTException;
import java.awt.Robot;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestClient {
private final static String SERVER_IP = "192.168.0.50";
JPanel clientPanel = new JPanel();
JFrame clientFrame = new JFrame();
public void setupGUI() {
clientFrame.add(clientPanel);
clientFrame.setSize(200,200);
clientFrame.setVisible(true);
clientFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
clientPanel.requestFocusInWindow();
}
public static void main(String[] args) {
try {
new TestClient().setupGUI();
Robot keyRobot = new Robot();
Socket firstSocket = new Socket(SERVER_IP, 1111);
System.out.println("Connected to Commander. Address sent. Waiting for callback.");
firstSocket.close();
Selector selector = Selector.open();
int ports[] = new int[] { 1112, 1113 };
for (int port : ports) {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress(port));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
while (true) {
// After the 2 accept methods fire, it stops here and program doesnt continue.
selector.select();
Set setKeys = selector.selectedKeys();
Iterator selectedKeys = setKeys.iterator();
while (selectedKeys.hasNext()) {
SelectionKey selectedKey = (SelectionKey) selectedKeys.next();
if (selectedKey.isAcceptable()) {
SocketChannel socketChannel = ((ServerSocketChannel) selectedKey.channel()).accept();
socketChannel.configureBlocking(false);
switch (socketChannel.socket().getLocalPort()) {
case 1112:
System.out.println("Keyboard socket open.");
Runnable kbr = new KBThread(socketChannel.socket());
new Thread(kbr).start();
break;
case 1113:
System.out.println("Mouse socket open.");
break;
}
}
selectedKeys.remove();
}
}
} catch (ConnectException ece) {
System.out.println("Failed to connect to server: " + SERVER_IP);
} catch (IOException | AWTException eio) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, eio);
}
}
private static class KBThread implements Runnable {
private final Socket kbSocket;
private int dataID = 0;
private KBThread(Socket kbSocket) {
this.kbSocket = kbSocket;
}
#Override
public void run() {
try {
DataInputStream kbDis = new DataInputStream(kbSocket.getInputStream());
while (true) {
try {
if (kbDis.available() > 0) {
dataID = kbDis.readInt();
System.out.println(dataID);
}
//else System.out.println("noData");
} catch (IOException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (IOException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
This is not how IO multiplexing is supposed to work.
First, don't remove from selectedKeys - after you accepted two connections there's nothing to select on, so the loop in the main thread blocks, and event if new connections are arriving you are not accepting them anymore. - this was wrong, I was confused about Java iterators, it's been a long time ...
Then, once a connection is accepted and marked non-blocking, add it to the same selector with OP_READ. Check for readable event in the loop, read from the socket. You don't need threads for this.
Alternatively, if you want to go with threads, don't set accepted client connection as non-blocking, just do regular reads from it in the dedicated thread.
Edit 0:
The best advise I can offer is to go over some good Java NIO tutorial. There many on the Intenet, but you can start here:
http://docs.oracle.com/javase/1.5.0/docs/guide/nio/example/index.html
http://tutorials.jenkov.com/java-nio/index.html
Don't have enough rep for comments so posting as answer. I am no expert but I believe you will have to use a PrintWriter on sockets output stream to pass the text back and forth. Here thisClient is a socket.
writer = new PrintWriter(thisClient.getOutputStream());
System.out.println("Transmitting");
writer.println(msg);
writer.flush();

Java socket: how the server can reads multiple lines from the client

I create chat app one to one by using Java programming language
I faced issue: client can't send a new message until he receives a message from the server.
You should have a multithreaded application.
The client will run 2 threads:
1) Sender thread which will run on send button. You can every time create a new instance of this thread on clicking send button.
2) The receiver thread will keep on running continuously and check the stream for any message. Once it gets a message on stream it will write the same on console.
Will update you shortly with the code.
Thanks
Written this code long back similarly you can write server using other port
package com.clients;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClientFullDuplex extends JFrame implements ActionListener {
private JFrame jframe;
private JPanel jp1, jp2;
private JScrollPane jsp;
private JTextArea jta;
private JTextField jtf;
private JButton send;
private Thread senderthread;
private Thread recieverthread;
private Socket ds;
private boolean sendflag;
public static void main(String[] args) {
try {
ClientFullDuplex sfd = new ClientFullDuplex();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ClientFullDuplex() throws UnknownHostException, IOException {
initGUI();
ds = new Socket("127.0.0.1", 1124);
initNetworking();
}
public void initGUI() {
jframe = new JFrame();
jframe.setTitle("Client");
jframe.setSize(400, 400);
jp1 = new JPanel();
jta = new JTextArea();
jsp = new JScrollPane(jta);
jtf = new JTextField();
send = new JButton("Send");
send.addActionListener(this);
jp1.setLayout(new GridLayout(1, 2, 10, 10));
jp1.add(jtf);
jp1.add(send);
jframe.add(jp1, BorderLayout.SOUTH);
jframe.add(jsp, BorderLayout.CENTER);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jta.append("hello client");
}
#Override
public synchronized void addWindowListener(WindowListener arg0) {
// TODO Auto-generated method stub
super.addWindowListener(arg0);
new WindowAdapter() {
#Override
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
if (ds != null)
try {
ds.close();
System.exit(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
public void initNetworking() {
try {
recieverthread = new Thread(r1);
recieverthread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Runnable r1 = new Runnable() {
#Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()
+ "Reciver Thread Started");
recieveMessage(ds);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Runnable r2 = new Runnable() {
#Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()
+ "Sender Thread Started");
sendMessage(ds);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public void recieveMessage(Socket rms) throws IOException {
while (true) {
System.out.println(Thread.currentThread().getName()
+ "Reciver Functionality");
BufferedReader br = new BufferedReader(new InputStreamReader(
rms.getInputStream()));
String line = br.readLine();
System.out.println(line);
jta.append("\nServer:"+line);
}
}
public void sendMessage(Socket sms) throws IOException {
System.out.println(Thread.currentThread().getName()
+ "Sender Functionality");
PrintWriter pw = new PrintWriter(sms.getOutputStream(), true);
String sline = jtf.getText();
System.out.println(sline);
pw.println(sline);
jtf.setText("");
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == send) {
senderthread = new Thread(r2);
senderthread.start();
}
}
}
This is the code I copied and edited from your earlier post.
The problem is that the input stream from socket is blocking. So my suggestion is to read up on async sockets in java and refactor the code below.
next to that it isn't that difficult to edit posts.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
public static void main(String[] args) {
Server chatServer = new Server(5555);
System.out.println("###Start listening...###");
chatServer.startListening();
chatServer.acceptClientRequest();
}
private ServerSocket listeningSocket;
private Socket serviceSocket;
private int TCPListeningPort;
private ArrayList<SocketHanding> connectedSocket;
public Server(int TCPListeningPort)
{
this.TCPListeningPort = TCPListeningPort;
connectedSocket = new ArrayList<SocketHanding>();
}
public void startListening()
{
try
{
listeningSocket = new ServerSocket(TCPListeningPort);
}
catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void acceptClientRequest()
{
try
{
while (true)
{
serviceSocket = listeningSocket.accept();
SocketHanding _socketHandling = new SocketHanding(serviceSocket);
connectedSocket.add(_socketHandling);
Thread t = new Thread(_socketHandling);
t.start();
System.out.println("###Client connected...### " + serviceSocket.getInetAddress().toString() );
}
}
catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
class SocketHanding implements Runnable
{
private Socket _connectedSocket;
private PrintWriter socketOut;
private InputStream socketIn;
private boolean threadRunning = true;
private String rmsg;
public SocketHanding(Socket connectedSocket) throws IOException
{
_connectedSocket = connectedSocket;
socketOut = new PrintWriter(_connectedSocket.getOutputStream(), true);
socketIn = _connectedSocket.getInputStream();
}
private void closeConnection() throws IOException
{
threadRunning = false;
socketIn.close();
socketOut.close();
_connectedSocket.close();
}
public void sendMessage(String message)
{
socketOut.println(message);
}
private String receiveMessage() throws IOException
{
String t = "";
if (_connectedSocket.getInputStream().available() > 0)
{
byte[] b = new byte[8192];
StringBuilder builder = new StringBuilder();
int bytesRead = 0;
if ( (bytesRead = _connectedSocket.getInputStream().read(b)) > -1 )
{
builder.append(new String(b, 0, b.length).trim());
}
t = builder.toString();
}
return t;
}
#Override
public void run()
{
while (threadRunning)
{
try
{
rmsg = receiveMessage();
System.out.println(rmsg);
if(rmsg.equalsIgnoreCase("bye"))
{
System.out.println("###...Done###");
closeConnection();
break;
}
else
{
String smsg = "";
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
smsg = keyboard.readLine();
keyboard.close();
sendMessage("Server: "+smsg);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}

Why doesn't this client/server program stop?

As I am learning java socket, I've made a functionnal but very simple chat in two frames : one client and one server. The app is only local and works. But it does not stop when I close windows (though I added WindowListener to both frame classes) : what's wrong ?
Don't forget to run the server first, and then the client : both frames will be visibles only after the client connection.
Here is SimpleSocketFrame.java (base class for both frames) :
package com.loloof64.java_se.simple_socket;
import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public abstract class SimpleSocketFrame extends JFrame {
public SimpleSocketFrame() {
setTitle(getFrameTitle());
setLayout(new GridLayout(0, 1));
messageToAddField = new JTextField(30);
messageToAddField.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER){
if ( ! messageToAddField.getText().isEmpty()) {
addMessage(messageToAddField.getText());
messageToAddField.setText("");
}
}
}
});
printedMessagesArea = new JTextArea(10,30);
printedMessagesArea.setEditable(false);
add(messageToAddField);
add(printedMessagesArea);
pack();
}
protected abstract void addMessage(String s);
protected abstract String getFrameTitle();
private static final long serialVersionUID = -5861605385948623162L;
protected JTextArea printedMessagesArea;
private JTextField messageToAddField;
}
Here is the server app class : SimpleSocketServer.java
package com.loloof64.java_se.simple_socket;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JOptionPane;
public class SimpleSocketServer extends SimpleSocketFrame {
public SimpleSocketServer(){
super();
setTitle("Simple Server");
try {
serverSocket = new ServerSocket(12345);
relatedSocket = serverSocket.accept();
outStream = new PrintStream(relatedSocket.getOutputStream());
isr = new InputStreamReader(relatedSocket.getInputStream());
inStream = new BufferedReader(isr);
final InStreamRunnable inStreamRunnable = new InStreamRunnable();
Thread inStreamReaderThread = new Thread(inStreamRunnable);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent evt) {
try {
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
outStream.close();
try {
relatedSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
inStreamRunnable.stop();
System.exit(0);
}
});
inStreamReaderThread.start();
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "Could not create the server !!!",
"Fatal error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
e.printStackTrace();
}
}
private class InStreamRunnable implements Runnable {
#Override
public void run() {
while (weMustGoOn){
String line;
try {
line = inStream.readLine();
printedMessagesArea.setText(printedMessagesArea.getText()+line+"\n");
} catch (IOException e) {
}
}
}
public void stop(){
weMustGoOn = false;
}
private boolean weMustGoOn = true;
}
#Override
protected void addMessage(String s) {
s = "Serveur> "+s;
outStream.println(s);
printedMessagesArea.setText(printedMessagesArea.getText()+"Client> "+s+"\n");
}
#Override
protected String getFrameTitle() {
return "Simple Server";
}
public static void main(String[] args) {
new SimpleSocketServer().setVisible(true);
}
private static final long serialVersionUID = 4288994465786972478L;
private Socket relatedSocket;
private ServerSocket serverSocket;
private PrintStream outStream;
private InputStreamReader isr;
private BufferedReader inStream;
}
Here is the client class : SimpleSocketClient.java
package com.loloof64.java_se.simple_socket;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JOptionPane;
public class SimpleSocketClient extends SimpleSocketFrame {
public SimpleSocketClient(){
try {
socket = new Socket(InetAddress.getLocalHost(), 12345);
outStream = new PrintStream(socket.getOutputStream());
isr = new InputStreamReader(socket.getInputStream());
inStream = new BufferedReader(isr);
final InStreamRunnable inStreamRunnable = new InStreamRunnable();
Thread inStreamReaderThread = new Thread(inStreamRunnable);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent evt) {
try {
inStream.close();
} catch (IOException e2) {
e2.printStackTrace();
}
try {
isr.close();
} catch (IOException e1) {
e1.printStackTrace();
}
outStream.close();
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
inStreamRunnable.stop();
System.exit(0);
}
});
inStreamReaderThread.start();
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "Could not create the client !!!",
"Fatal error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
e.printStackTrace();
}
}
public static void main(String[] args) {
new SimpleSocketClient().setVisible(true);
}
private class InStreamRunnable implements Runnable {
#Override
public void run() {
while (weMustGoOn){
String line;
try {
line = inStream.readLine();
printedMessagesArea.setText(printedMessagesArea.getText()+line+"\n");
} catch (IOException e) {
}
}
}
public void stop(){
weMustGoOn = false;
}
private boolean weMustGoOn = true;
}
#Override
protected void addMessage(String s) {
s = "Client> "+s;
outStream.println(s);
printedMessagesArea.setText(printedMessagesArea.getText()+s+"\n");
}
#Override
protected String getFrameTitle() {
return "Simple Client";
}
private static final long serialVersionUID = 5468568598525947366L;
private Socket socket;
private PrintStream outStream;
private InputStreamReader isr;
private BufferedReader inStream;
}
The program doesn't stop as you're attempting to close the network input Readers when closing a JFrame, which are blocking indefinitely. BufferedReader and InputStreamReader objects cannot close as the client thread is blocked in this readLine call which is waiting for a response from the server
line = inStream.readLine();
Comment out or remove:
inStream.close();
and
isr.close();
Just closing the Socket stream will suffice.
Aside: When interacting with Swing components for multi-threaded network applications, always use a SwingWorker. SwingWorkers are designed to interact correctly with Swing components.
You should add finally block after try and catch to close the socket and after that you can close your program by system exit method.

Images and Sound Won't Load at the Same Time (Java)

I'm making a game which is using sound and images. The weirdest thing is happening. When I load sound, my image won't appear. However, when I don't load my sound, my image does appear. Here is my code:
package com.gbp.chucknorris;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Title extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
public Thread thread;
private BufferedImage logo;
private Clip clip, titleClip;
public Title() {
super();
loadSound();
loadImages();
bind();
setBackground(Color.WHITE);
}
private void loadSound() {
File f = new File("res/sounds/title.wav");
AudioInputStream stream = null;
try {
stream = AudioSystem.getAudioInputStream(f);
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat());
try {
clip = (Clip) AudioSystem.getLine(info);
} catch (LineUnavailableException e) {
e.printStackTrace();
}
try {
clip.open(stream);
} catch (LineUnavailableException | IOException e) {
e.printStackTrace();
}
File title = new File("res/sounds/theme.wav");
AudioInputStream titleStream = null;
try {
titleStream = AudioSystem.getAudioInputStream(title);
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
DataLine.Info titleInfo = new DataLine.Info(Clip.class, titleStream.getFormat());
try {
titleClip = (Clip) AudioSystem.getLine(titleInfo);
titleClip.open(titleStream);
} catch (LineUnavailableException | IOException e) {
e.printStackTrace();
}
titleClip.loop(Clip.LOOP_CONTINUOUSLY);
}
private void bind() {
InputMap im = getInputMap();
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke("DOWN"), "down");
am.put("down", new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
}
});
}
private void loadImages() {
try {
logo = ImageIO.read(new File("res/pics/MenuPanel.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (true) {
repaint();
}
}
public void addNotify() {
super.addNotify();
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(logo, 0, 0, null);
}
}
Thanks in advance!
You need to learn to use background threading such as a SwingWorker so as not to tie up the event thread, the EDT, when loading and playing sounds. You can read up on how to use this here: Lesson: Concurrency in Swing.
Edit: I wouldn't recommend doing this:
#Override
public void run() {
while (true) {
repaint();
}
}

Categories