I'm having this problem where the thread that is used to get information from the client will not shutdown when that user has disconnected. The cpu usage goes up go to 100% and the program gets stuck in an infinite loop.
The problem is on the server side but I have searched and searched and I have found no way to solve this issue. I will post the whole server and client class but i think the issue is centered around the Transfer thread and the SendToAll method.
SERVER:
package serverSide;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server implements Runnable{
public final static int Port = 3000;
public static ServerSocket ss;
public static ArrayList<ClientInfo> Client;
public static String Message = "";
public static void main(String[] args) throws IOException {
#SuppressWarnings("unused")
Server server = new Server();
}
public Server() throws IOException{
ss = new ServerSocket(Port);
Client = new ArrayList<ClientInfo>();
new Thread(this).start();
}
public void run(){
try {
while (true){
//Accept new client
Socket s = ss.accept();
//Get client info
DataInputStream dis = new DataInputStream(s.getInputStream());
String Name = dis.readUTF();
//Give client storage
int Result = CheckClients();
if (Result == -1){
Result = Client.size();
Client.add(new ClientInfo(Name,Result,s));
} else {
Client.set(Result, new ClientInfo(Name,Result,s));
}
//Run get input
Transfer transfer = new Transfer(Client.get(Result).ClientID);
transfer.start();
}
} catch (IOException e) {
System.out.println("Connection Error");
}
}
public static void SendToAll() throws IOException{
for (int i=0;i<Client.size();i++){
DataOutputStream dos = new DataOutputStream(Client.get(i).ClientSocket.getOutputStream());
dos.writeUTF(Message);
}
Message = "";
}
public int CheckClients(){
int Result = -1;
for(int i = 0;i < Client.size() + 1;i++){
try{
if (Client.get(i) == null){
Result = i;
break;
}
} catch (IndexOutOfBoundsException e){
break;
}
}
return Result;
}
}
class Transfer extends Thread{
int ClientNumber;
public Transfer(int ClientNumber){
this.ClientNumber = ClientNumber;
}
public void run(){
while(true){
DataInputStream dis;
try {
dis = new DataInputStream(Server.Client.get(ClientNumber).ClientSocket.getInputStream());
String FromClient = dis.readUTF();
Server.Message = FromClient;
System.out.println(Server.Message);
Server.SendToAll();
} catch (IOException e) {
try {
this.join();
} catch (InterruptedException e1) {
}
break;
}
}
}
}
class ClientInfo {
public ClientInfo(String Name,int ClientID,Socket ClientSocket){
this.Name = Name;
this.ClientID = ClientID;
this.ClientSocket = ClientSocket;
}
public String Name;
public int ClientID;
public Socket ClientSocket;
}
CLIENT:
package clientSide;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.Window.Type;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import java.awt.Font;
import javax.swing.SwingConstants;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientWindow {
private JFrame frmClient;
private JTextArea txtLog;
private JTextField txtMessage;
public String ServerAddress;
public String Name;
public String Password;
public Socket s;
public final int Port = 3000;
public static void main(String[] args,String sa,String n,String p) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ClientWindow window = new ClientWindow(sa,n,p);
window.frmClient.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void ConnectToServer(JTextArea txtLog){
try {
s = new Socket(ServerAddress,Port);
System.out.println("Connected");
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(Name);
GetResponse gr = new GetResponse(txtLog,s);
gr.start();
} catch (UnknownHostException e) {
JOptionPane.showMessageDialog(this.frmClient,"Unable to open connection to " + ServerAddress + ". Unknown host.","Error" ,JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
} catch (IOException e) {
JOptionPane.showMessageDialog(this.frmClient,"Unable to open connection to " + ServerAddress + ". Unknown host.","Error" ,JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
}
public ClientWindow(String sa,String n,String p) throws InterruptedException {
ServerAddress = sa;
Name = n;
Password = p;
initialize();
}
private void initialize() {
frmClient = new JFrame();
frmClient.setResizable(false);
frmClient.setIconImage(Toolkit.getDefaultToolkit().getImage("C:\\Users\\joshu.DESKTOP-ECFG8JL\\workspace\\ChatSocket\\res\\icons\\Custom-Icon-Design-Flatastic-11-Connection.ico"));
frmClient.setType(Type.POPUP);
frmClient.setTitle("Connect");
frmClient.getContentPane().setBackground(new Color(15, 80, 120));
frmClient.setBounds(100, 100, 870, 650);
frmClient.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmClient.getContentPane().setLayout(null);
txtLog = new JTextArea();
txtLog.setEditable(false);
txtLog.setForeground(Color.WHITE);
txtLog.setFont(new Font("Calibri Light", Font.PLAIN, 24));
txtLog.setColumns(1);
txtLog.setBorder(new LineBorder(new Color(0, 153, 255)));
txtLog.setBackground(new Color(15, 80, 120));
txtLog.setBounds(7, 87, 845, 450);
frmClient.getContentPane().add(txtLog);
txtMessage = new JTextField();
txtMessage.setHorizontalAlignment(SwingConstants.LEFT);
txtMessage.setForeground(Color.WHITE);
txtMessage.setFont(new Font("Calibri Light", Font.PLAIN, 24));
txtMessage.setColumns(1);
txtMessage.setBorder(new LineBorder(new Color(0, 153, 255)));
txtMessage.setBackground(new Color(15, 80, 120));
txtMessage.setBounds(7, 559, 659, 40);
frmClient.getContentPane().add(txtMessage);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DataOutputStream dos;
try {
dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(Name + ": " + txtMessage.getText());
txtMessage.setText("");
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
btnSend.setForeground(Color.WHITE);
btnSend.setFont(new Font("Calibri Light", Font.BOLD, 25));
btnSend.setBackground(new Color(51, 153, 204));
btnSend.setBounds(676, 559, 176, 40);
Border emptyBorder = BorderFactory.createEmptyBorder();
btnSend.setBorder(emptyBorder);
frmClient.getContentPane().add(btnSend);
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setBackground(new Color(51, 153, 204));
panel.setBounds(0, 0, 864, 75);
frmClient.getContentPane().add(panel);
JLabel lblIP = new JLabel("Connected to: " + ServerAddress);
lblIP.setVerticalAlignment(SwingConstants.TOP);
lblIP.setHorizontalAlignment(SwingConstants.LEFT);
lblIP.setForeground(new Color(15, 80, 120));
lblIP.setFont(new Font("Calibri Light", Font.BOLD, 40));
lblIP.setBounds(12, 12, 853, 50);
panel.add(lblIP);
ConnectToServer(txtLog);
}
}
class GetResponse extends Thread{
JTextArea txtLog;
Socket s;
public GetResponse(JTextArea txtLog,Socket s){
this.txtLog = txtLog;
this.s = s;
}
public void run(){
while(true){
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
String Input = dis.readUTF();
txtLog.setText(txtLog.getText() + "\n" + Input);
} catch (IOException e) {
}
}
}
}
Related
I am creating a multiclient chat server program. Messages are sent as Message objects. The ServerClient class is not recieving the messages, though, and I don't know why.
Client:
package client;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.*;
import constraints.Constraints;
import message.Message;
import tools.Tools;
import window.ApplicationWindow;
#SuppressWarnings("serial")
public class Client extends ApplicationWindow {
private static final int portNumber = 4444;
private boolean send = false;
private String userName;
private String serverHost;
private int serverPort;
private GridBagLayout layout;
private JTextArea textArea;
private Constraints c_textArea;
private JTextField textField;
private Constraints c_textField;
public static void main(String[] args){
String readName = System.getProperty("user.name");
Client client = new Client(readName, portNumber);
client.startClient();
}
private Client(String userName, int portNumber){
super("ChatApp");
Tools.setLookAndFeel();
this.userName = userName;
this.serverPort = portNumber;
try {
this.serverHost = InetAddress.getLocalHost().getHostAddress();
}catch(Exception e) {
}
layout = new GridBagLayout();
setLayout(layout);
textArea = new JTextArea();
textArea.setColumns(75);
textArea.setRows(20);
c_textArea = new Constraints(0,1);
textArea.setLineWrap(true);
textArea.setEditable(false);
textArea.setVisible(true);
JScrollPane scroll = new JScrollPane (textArea);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scroll, c_textArea);
textField = new JTextField();
textField.setColumns(50);
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
send = true;
}
});
c_textField = new Constraints(0,2);
add(textField, c_textField);
pack();
setVisible(true);
setResizable(false);
}
public void output(String message) {
this.textArea.setText(this.textArea.getText() + "\n" + message);
}
private void startClient() {
try{
Socket socket = new Socket(serverHost, serverPort);
Thread.sleep(1000);
ServerThread serverThread = new ServerThread(socket, userName, this);
Thread serverAccessThread = new Thread(serverThread);
serverAccessThread.start();
while(serverAccessThread.isAlive() && this.isRunning()) {
if (send) {
Message message = new Message(textField.getText(), "[" + "]", this.userName);
serverThread.addNextMessage(message);
send = false;
textField.setText("");
}
Thread.sleep(200);
}
}catch(IOException ex){
output("Could not connect to server!");
}catch(InterruptedException ex){
output("Connection interrupted!");
}
}
public void setHost(String serverHost) {
this.serverHost = serverHost;
}
}
ServerClient:
package server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
import message.Message;
public class ServerClient implements Runnable {
private Socket socket;
private PrintWriter clientOut;
private ChatServer server;
private boolean running;
public ServerClient(ChatServer server, Socket socket) {
this.server = server;
this.socket = socket;
this.running = true;
}
private PrintWriter getWriter(){
return clientOut;
}
public boolean isRunning() {
return this.running;
}
public void stop() {
this.running = false;
}
#Override
public void run() {
try{
this.clientOut = new PrintWriter(socket.getOutputStream(), false);
clientOut.flush();
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
while(!socket.isClosed()){
try {
if (in.available() > 0) {
Object i = in.readObject();
if (!i.equals(null)) {
Message input = (Message) i;
String message = input.getText();
String time = input.getTimestamp();
String user = input.getUser();
for(ServerClient thatClient : server.getClients()){
PrintWriter thatClientOut = thatClient.getWriter();
if(thatClientOut != null){
thatClientOut.write(time + " " + user + ": " + message + "\r\n");
thatClientOut.flush();
}
}
}
}
} catch (ClassNotFoundException e) {
System.out.println(e);
} catch (SocketException ex) {
System.out.println(ex);
break;
}
}
in.close();
this.stop();
} catch (IOException e) {
e.printStackTrace();
}
}
//public void fileWrite()
}
ChatServer:
package server;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
//import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import constraints.Constraints;
import tools.Tools;
import window.ApplicationWindow;
import message.Message;
#SuppressWarnings("serial")
public class ChatServer extends ApplicationWindow {
private static final int portNumber = 4444;
private ArrayList<Command> commands;
private int serverPort;
private String serverHost;
private List<ServerClient> clients;
ServerSocket serverSocket;
private GridBagLayout layout;
private JTextArea textArea;
private Constraints c_textArea;
private JTextField textField;
private Constraints c_textField;
public static void main(String[] args){
ChatServer server = new ChatServer(portNumber);
server.startServer();
}
public ChatServer(int portNumber){
super("Server " + portNumber);
this.serverPort = portNumber;
try {
this.serverHost = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
this.serverHost = "";
}
Tools.setLookAndFeel();
initActions();
layout = new GridBagLayout();
setLayout(layout);
textArea = new JTextArea();
textArea.setColumns(75);
textArea.setRows(20);
c_textArea = new Constraints(0,1);
textArea.setLineWrap(true);
textArea.setEditable(false);
textArea.setVisible(true);
JScrollPane scroll = new JScrollPane (textArea);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scroll, c_textArea);
textField = new JTextField();
textField.setColumns(50);
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
process(textField.getText());
}
});
c_textField = new Constraints(0,2);
add(textField, c_textField);
pack();
setVisible(true);
setResizable(false);
}
public List<ServerClient> getClients(){
return clients;
}
private void startServer(){
clients = new ArrayList<ServerClient>();
serverSocket = null;
try {
InetAddress addr = InetAddress.getByName(this.serverHost);
serverSocket = new ServerSocket(serverPort, 50, addr);
acceptClients(serverSocket);
} catch (IOException e){
output("[ERROR] COULD NOT LISTEN ON PORT: " + serverPort);
this.stop();
}
}
private void acceptClients(ServerSocket serverSocket){
output("[BEGIN] SERVER STARTING ON PORT: " + serverSocket.getLocalSocketAddress());
while (this.isRunning()) {
try{
Socket socket = serverSocket.accept();
output("[ACCEPT] ACCEPTED CLIENT AT: " + socket.getRemoteSocketAddress());
ServerClient client = new ServerClient(this, socket);
Thread thread = new Thread(client);
thread.start();
clients.add(client);
} catch (IOException ex) {
output("[ERROR] ACCEPT FAILED ON: " + serverPort);
}
}
}
private void initActions() {
this.commands = new ArrayList<Command>();
this.commands.add(new Command() {
public void run() {
output("[COMMAND] IP: " + serverSocket.getInetAddress().toString());
}
public String getTrigger() {
return "-ip";
}
});
this.commands.add(new Command() {
public void run() {
for (ServerClient client : clients) {
if (!client.isRunning()) {
clients.remove(client);
}
}
output("[COMMAND] CLIENTS: " + clients.size());
}
public String getTrigger() {
return "-clients";
}
});
}
public boolean process(String command) {
for (Command c : this.commands) {
if (c.getTrigger().equals(command)) {
c.run();
textField.setText("");
return true;
}
}
return false;
}
public void output(String message) {
this.textArea.setText(this.textArea.getText() + "\n" + message);
}
}
ServerThread:
package client;
import java.io.*;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Scanner;
import message.Message;
#SuppressWarnings("unused")
public class ServerThread implements Runnable {
private Socket socket;
private String userName;
private boolean isAlived;
private final LinkedList<Message> messagesToSend;
private boolean hasMessages = false;
private Client client;
public ServerThread(Socket socket, String userName, Client client){
this.socket = socket;
this.userName = userName;
this.client = client;
messagesToSend = new LinkedList<Message>();
}
public void addNextMessage(Message message) {
synchronized (messagesToSend) {
hasMessages = true;
messagesToSend.push(message);
}
}
#Override
public void run(){
print("Welcome :" + userName);
print("Local Port :" + socket.getLocalPort());
print("Server = " + socket.getRemoteSocketAddress() + ":" + socket.getPort());
try {
ObjectOutputStream serverOut = new ObjectOutputStream(socket.getOutputStream());
serverOut.flush();
ObjectInputStream serverIn = new ObjectInputStream(socket.getInputStream());
while(!socket.isClosed()){
if (serverIn.available() > 0) {
try {
if (serverIn.readObject() != null) {
Message input = (Message) serverIn.readObject();
}
} catch (ClassNotFoundException e) {
System.out.println(e);
}
}
if(hasMessages){
Message nextSend;
synchronized(messagesToSend){
nextSend = messagesToSend.pop();
hasMessages = !messagesToSend.isEmpty();
}
serverOut.writeObject(nextSend);
serverOut.flush();
}
}
serverOut.close();
serverIn.close();
} catch(Exception ex){
ex.printStackTrace();
}
}
public void print(String message) {
this.client.output(message);
}
}
I know that the client is able to connect to the server, and both can get messages and successfully call the writeObject() method. However, the message never gets recieved. Can someone help me?
while(!socket.isClosed()){
if (serverIn.available() > 0) {
try {
if (serverIn.readObject() != null) {
Message input = (Message) serverIn.readObject();
}
} catch (ClassNotFoundException e) {
System.out.println(e);
}
}
if(hasMessages){
Message nextSend;
synchronized(messagesToSend){
nextSend = messagesToSend.pop();
hasMessages = !messagesToSend.isEmpty();
}
serverOut.writeObject(nextSend);
serverOut.flush();
}
}
This is all nonsense.
isClosed() returns true when you have closed the socket. Not when the peer disconnects.
Calling available() here and merely spin-looping while it is false is just literally a waste of time.
ObjectInputStream.readObect() only returns null if you send a null.
You are calling it twice, throwing the first object read away, and then trying to read the next object. So you are throwing away every odd-numbered object.
It should be more like this:
for (;;) {
try {
Message input = (Message) serverIn.readObject();
// process input here
} catch (EOFException e) {
break;
} catch (ClassNotFoundException e) {
System.out.println(e);
}
}
if(hasMessages){
Message nextSend;
synchronized(messagesToSend){
nextSend = messagesToSend.pop();
hasMessages = !messagesToSend.isEmpty();
}
serverOut.writeObject(nextSend);
serverOut.flush();
}
}
You should probably split this into a reading thread and a writing thread, as writeObject() and flush() can also block. Same remarks apply to the other place where you are using isClosed(), available(), testing for null, etc.
The hasMessages flag is also not going to work. It will remain false even though a message got added subsequently. It would be better to delete it and just rely on messagesToSend.isEmpty(), inside a synchronized block:
synchronized(messagesToSend){
while (!messagesToSend.isEmpty()){
Message nextSend = messagesToSend.pop();
serverOut.writeObject(nextSend);
}
}
serverOut.flush();
I'm trying to make a MultiClient Chat Application in which the chat is implemented in the client window. I've tried server and client code for the same.one clint to server is running good but teo client to server is not running properly one clint communication good but second one client not giving response.
Client Code
package server1;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Clientchatform extends JFrame implements ActionListener {
static Socket conn;
JPanel panel;
JTextField NewMsg;
JTextArea ChatHistory;
JButton Send;
String line;
BufferedReader br;
String response;
BufferedReader is ;
PrintWriter os;
public Clientchatform() throws UnknownHostException, IOException {
panel = new JPanel();
NewMsg = new JTextField();
ChatHistory = new JTextArea();
Send = new JButton("Send");
this.setSize(500, 500);
this.setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel.setLayout(null);
this.add(panel);
ChatHistory.setBounds(20, 20, 450, 360);
panel.add(ChatHistory);
NewMsg.setBounds(20, 400, 340, 30);
panel.add(NewMsg);
Send.setBounds(375, 400, 95, 30);
panel.add(Send);
Send.addActionListener(this);
conn = new Socket(InetAddress.getLocalHost(), 2000);
ChatHistory.setText("Connected to Server");
this.setTitle("Client");
while (true) {
try {
BufferedReader is = new BufferedReader(new InputStreamReader(conn.getInputStream()));
br= new BufferedReader(new InputStreamReader(System.in));
String line = is.readLine();
ChatHistory.setText(ChatHistory.getText() + 'n' + "Server:"
+ line);
} catch (Exception e1) {
ChatHistory.setText(ChatHistory.getText() + 'n'
+ "Message sending fail:Network Error");
try {
Thread.sleep(3000);
System.exit(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if ((e.getSource() == Send) && (NewMsg.getText() != "")) {
ChatHistory.setText(ChatHistory.getText() + 'n' + "Me:"
+ NewMsg.getText());
try {
br= new BufferedReader(new InputStreamReader(System.in));
PrintWriter os=new PrintWriter(conn.getOutputStream());
os.println(NewMsg.getText());
os.flush();
} catch (Exception e1) {
ChatHistory.append(ChatHistory.getText() + 'n'
+ "Message sending fail:Network Error");
}
NewMsg.setText("");
}
}
public static void main(String[] args) throws UnknownHostException,
IOException {
Clientchatform chatForm = new Clientchatform();
}
}
Server Code
package server1;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class serverChatform extends JFrame implements ActionListener {
static ServerSocket server;
static Socket conn;
JPanel panel;
JTextField NewMsg;
JTextArea ChatHistory;
JButton Send;
//DataInputStream dis;
//DataOutputStream dos;
String line;
BufferedReader is ;
public serverChatform() throws UnknownHostException, IOException {
panel = new JPanel();
NewMsg = new JTextField();
ChatHistory = new JTextArea();
Send = new JButton("Send");
this.setSize(500, 500);
this.setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel.setLayout(null);
this.add(panel);
ChatHistory.setBounds(20, 20, 450, 360);
panel.add(ChatHistory);
NewMsg.setBounds(20, 400, 340, 30);
panel.add(NewMsg);
Send.setBounds(375, 400, 95, 30);
panel.add(Send);
this.setTitle("Server");
Send.addActionListener(this);
server = new ServerSocket(2000, 1, InetAddress.getLocalHost());
ChatHistory.setText("Waiting for Client");
conn = server.accept();
// ServerThread st=new ServerThread(conn);
// st.start();
ChatHistory.setText(ChatHistory.getText() + 'n' + "Client Found");
while (true) {
try {
BufferedReader is = new BufferedReader(new InputStreamReader(conn.getInputStream()));
PrintWriter os=new PrintWriter(conn.getOutputStream());
line=is.readLine();
ChatHistory.append(ChatHistory.getText() + 'n' + "Client:"
+ line);
} catch (Exception e1)
{
ChatHistory.setText(ChatHistory.getText() + 'n'
+ "Message sending fail:Network Error");
try {
Thread.sleep(3000);
System.exit(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if ((e.getSource() == Send) && (NewMsg.getText() != "")) {
ChatHistory.setText(ChatHistory.getText() + 'n' + "ME:"
+ NewMsg.getText());
try {
PrintWriter os =new PrintWriter(conn.getOutputStream());
os.println(NewMsg.getText());
os.flush();
} catch (Exception e1) {
try {
Thread.sleep(3000);
System.exit(0);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
}
NewMsg.setText("");
}
}
public static void main(String[] args) throws UnknownHostException,
IOException {
new serverChatform();
}
}
You're definitely on the right track, but I've got a question for you to ask yourself.
conn = server.accept();
// ServerThread st=new ServerThread(conn);
// st.start();
ChatHistory.setText(ChatHistory.getText() + 'n' + "Client Found");
How often is this code executed? Consider that of course the main(),
public static void main(String[] args) throws UnknownHostException,
IOException {
new serverChatform();
}
is only called once, and therefore only one serverChatform will ever be created.
As you seem to have written quite a bit of code yourself, and it therefore seems like you're ready to learn more, I'm not going to give a full solution, but merely a direction.
Once you accept a client, with conn = server.accept();, you will have to create another new serverChatform();. This has to happen in a different Thread though. How to do this, I leave as an exercise for you.
Each connected client has to be served in its own thread. Additionally you need a Thread that continiously listens for new clients to connect. That would look like this.
List<Socket> clients; // Save the socket for each client
[...]
new Thread(new Runnable(){
#Override
public void run() {
// Thread that runs forever listening for new clients
while(true){
Socket conn = server.accept();
// new client has connected, store its socket
clients.add(conn);
// and start new thread that interacts with this new client
new Thread(new Runnable(){
#Override
public void run() {
// SERVE CLIENT HERE!
}
}).start();
}
}
}).start();
I am converting a video into frames using a simple Frame splitter code and these are getting stored in a separate folder.
I want to pass these snapshots sequentially to another module (class) for processing. How Can i do this?
this is the code of the Frame Splitter:
package FrameSplitter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global;
public class FrameSplitter {
public static final double SECONDS_BETWEEN_FRAMES = 2;
private static final String inputFilename = "C://Sample.mp4";
private static final String outputFilePrefix = "C://snapshots//mysnapshot";
private static int mVideoStreamIndex = -1;
// Time of last frame write
private static long mLastPtsWrite = Global.NO_PTS;
public static final long MICRO_SECONDS_BETWEEN_FRAMES =
(long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);
public static void main(String[] args) {
IMediaReader mediaReader = ToolFactory.makeReader(inputFilename);
// stipulate that we want BufferedImages created in BGR 24bit color space
mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
mediaReader.addListener(new ImageSnapListener());
while (mediaReader.readPacket() == null) ;
}
private static class ImageSnapListener extends MediaListenerAdapter {
public void onVideoPicture(IVideoPictureEvent event) {
if (event.getStreamIndex() != mVideoStreamIndex) {
if (mVideoStreamIndex == -1)
mVideoStreamIndex = event.getStreamIndex();
else
return;
}
if (mLastPtsWrite == Global.NO_PTS)
mLastPtsWrite = event.getTimeStamp() - MICRO_SECONDS_BETWEEN_FRAMES;
if (event.getTimeStamp() - mLastPtsWrite >=
MICRO_SECONDS_BETWEEN_FRAMES) {
String outputFilename = dumpImageToFile(event.getImage());
double seconds = ((double) event.getTimeStamp()) /
Global.DEFAULT_PTS_PER_SECOND;
System.out.printf(
"at elapsed time of %6.3f seconds wrote: %s\n",
seconds, outputFilename);
// update last write time
mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;
}
}
private String dumpImageToFile(BufferedImage image) {
try{
String outputFilename = outputFilePrefix +
System.currentTimeMillis() + ".png";
ImageIO.write(image, "png", new File(outputFilename));
return outputFilename;
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
`
this is the code of the module which performs text extraction from images.. i need to pass the snapshots to this module
package tessgui;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Window;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.PropertyResourceBundle;
import javax.swing.UIManager;
public class Main
{
private static Hashtable preferences = new Hashtable();
public static final String TESS_PATH = "TesseractPath";
public static void main(String[] args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception ex)
{
ex.printStackTrace();
}
String tesseractPath = "";
readPreferences();
// tesseractPath = (String)preferences.get("TesseractPath");
tesseractPath = "C:/Tesseract-OCR/";
File tessLog = new File(tesseractPath + "\\tesseract.exe");
if (tessLog.canWrite())
{
System.out.println("Path valid : " + tesseractPath);
TessFrame tf = new TessFrame(tesseractPath);
tf.setTitle("Tesseract 1.00 GUI");
centerOnParent(tf);
tf.setVisible(true);
}
else
{
System.out.println("Path valid: " + tesseractPath);
TessFrame tf = new TessFrame("Enter Valid Tesseract Path");
centerOnParent(tf);
tf.setVisible(true);
}
}
public static void readPreferences()
{
Properties properties = System.getProperties();
Enumeration myEnum = properties.propertyNames();
while (myEnum.hasMoreElements())
{
String key = myEnum.nextElement().toString();
if (key.startsWith("Pianificatore")) {
preferences.put(key, properties.getProperty(key));
}
}
try
{
PropertyResourceBundle rb = new PropertyResourceBundle(new FileInputStream("tessgui.properties"));
myEnum = rb.getKeys();
while (myEnum.hasMoreElements())
{
String key = myEnum.nextElement().toString();
String value = (String)preferences.get(key);
if (value == null) {
preferences.put(key, rb.getString(key));
}
}
}
catch (FileNotFoundException ex)
{
System.out.println("File not found");
}
catch (IOException ex1) {}
}
public static void centerOnParent(Window window)
{
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle r = ge.getMaximumWindowBounds();
Dimension dim = new Dimension(r.width, r.height);
Rectangle abounds = window.getBounds();
window.setLocation((dim.width - abounds.width) / 2, (dim.height - abounds.height) / 2);
}
}
front end of it
package tessgui;
import java.awt.Color;
import java.awt.Container;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.accessibility.AccessibleContext;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.LayoutStyle.ComponentPlacement;
public class TessFrame
extends JFrame
{
String tesseractPath = "";
java.util.List<File> selectedFiles;
private JButton aboutButton;
private JButton addFileButton;
private JPanel buttonPanel;
private JPanel cfgPanel;
private JButton changePathButton;
private java.awt.List fileList;
private JPanel fileListPanel;
private JLabel jLabel1;
private JLabel jLabel2;
private JScrollPane jScrollPane1;
private JPanel logPanel;
private JTextArea logTextArea;
private JLabel outputFileNameLabel;
private JTextField outputFileNameTextField;
private JButton quitButton4;
private JButton removeAllButton;
private JButton runButton;
private JTextField tessPathTextField;
public TessFrame(String tessPath)
{
this.selectedFiles = new ArrayList();
this.tesseractPath = tessPath;
initComponents();
this.tessPathTextField.setText(this.tesseractPath);
}
private void initComponents()
{
this.cfgPanel = new JPanel();
this.tessPathTextField = new JTextField();
this.jLabel1 = new JLabel();
this.changePathButton = new JButton();
this.outputFileNameLabel = new JLabel();
this.outputFileNameTextField = new JTextField();
this.fileListPanel = new JPanel();
this.fileList = new java.awt.List();
this.buttonPanel = new JPanel();
this.runButton = new JButton();
this.addFileButton = new JButton();
this.removeAllButton = new JButton();
this.quitButton4 = new JButton();
this.aboutButton = new JButton();
this.jLabel2 = new JLabel();
this.logPanel = new JPanel();
this.jScrollPane1 = new JScrollPane();
this.logTextArea = new JTextArea();
setDefaultCloseOperation(3);
this.jLabel1.setText("Tesseract Installation Path");
this.changePathButton.setText("...");
this.changePathButton.setToolTipText("Change Tesseract Installation Path");
this.changePathButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
TessFrame.this.changePathButtonActionPerformed(evt);
}
});
this.outputFileNameLabel.setText("Output File Name");
this.outputFileNameTextField.setText("= FileName.txt");
this.outputFileNameTextField.setEnabled(false);
GroupLayout cfgPanelLayout = new GroupLayout(this.cfgPanel);
this.cfgPanel.setLayout(cfgPanelLayout);
cfgPanelLayout.setHorizontalGroup(cfgPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(cfgPanelLayout.createSequentialGroup().addContainerGap().addGroup(cfgPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(this.jLabel1).addComponent(this.outputFileNameLabel)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(cfgPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false).addComponent(this.outputFileNameTextField).addComponent(this.tessPathTextField, -1, 329, 32767)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.changePathButton).addContainerGap(34, 32767)));
cfgPanelLayout.setVerticalGroup(cfgPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(cfgPanelLayout.createSequentialGroup().addContainerGap().addGroup(cfgPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(this.jLabel1).addComponent(this.changePathButton).addComponent(this.tessPathTextField, -2, -1, -2)).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addGroup(cfgPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(this.outputFileNameLabel).addComponent(this.outputFileNameTextField, -2, -1, -2)).addContainerGap(20, 32767)));
this.jLabel1.getAccessibleContext().setAccessibleName("tessPathLabel");
this.changePathButton.getAccessibleContext().setAccessibleName("changePathButton");
GroupLayout fileListPanelLayout = new GroupLayout(this.fileListPanel);
this.fileListPanel.setLayout(fileListPanelLayout);
fileListPanelLayout.setHorizontalGroup(fileListPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(this.fileList, -1, 556, 32767));
fileListPanelLayout.setVerticalGroup(fileListPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(this.fileList, -1, 285, 32767));
this.buttonPanel.setBackground(new Color(204, 204, 255));
this.runButton.setText("RUN");
this.runButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
TessFrame.this.runButtonActionPerformed(evt);
}
});
this.addFileButton.setText("ADD FILE");
this.addFileButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
TessFrame.this.addFileButtonActionPerformed(evt);
}
});
this.removeAllButton.setText("REMOVE ALL");
this.removeAllButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
TessFrame.this.removeAllButtonActionPerformed(evt);
}
});
this.quitButton4.setText("QUIT");
this.quitButton4.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
TessFrame.this.quitButton4ActionPerformed(evt);
}
});
this.aboutButton.setText("About");
this.aboutButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
TessFrame.this.aboutButtonActionPerformed(evt);
}
});
this.jLabel2.setForeground(new Color(102, 102, 255));
this.jLabel2.setText("TessGUI-v0-20");
GroupLayout buttonPanelLayout = new GroupLayout(this.buttonPanel);
this.buttonPanel.setLayout(buttonPanelLayout);
buttonPanelLayout.setHorizontalGroup(buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(buttonPanelLayout.createSequentialGroup().addContainerGap().addComponent(this.jLabel2).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 63, 32767).addComponent(this.runButton).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.addFileButton).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.removeAllButton).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.quitButton4).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.aboutButton).addGap(46, 46, 46)));
buttonPanelLayout.setVerticalGroup(buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(buttonPanelLayout.createSequentialGroup().addContainerGap().addGroup(buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(this.runButton).addComponent(this.addFileButton).addComponent(this.removeAllButton).addComponent(this.quitButton4).addComponent(this.aboutButton)).addComponent(this.jLabel2)).addContainerGap(-1, 32767)));
this.logTextArea.setColumns(20);
this.logTextArea.setForeground(SystemColor.textInactiveText);
this.logTextArea.setRows(5);
this.jScrollPane1.setViewportView(this.logTextArea);
GroupLayout logPanelLayout = new GroupLayout(this.logPanel);
this.logPanel.setLayout(logPanelLayout);
logPanelLayout.setHorizontalGroup(logPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 556, 32767).addGroup(logPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(this.jScrollPane1, -1, 556, 32767)));
logPanelLayout.setVerticalGroup(logPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 160, 32767).addGroup(logPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(this.jScrollPane1, -1, 160, 32767)));
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(this.logPanel, -1, -1, 32767).addComponent(this.buttonPanel, -1, -1, 32767).addComponent(this.cfgPanel, -1, -1, 32767).addComponent(this.fileListPanel, -1, -1, 32767));
layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addComponent(this.cfgPanel, -2, -1, -2).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.fileListPanel, -1, -1, 32767).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.buttonPanel, -2, -1, -2).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(this.logPanel, -2, -1, -2)));
pack();
}
private void quitButton4ActionPerformed(ActionEvent evt)
{
System.exit(0);
}
private void addFileButtonActionPerformed(ActionEvent evt)
{
JFileChooser chooser = new JFileChooser();
int x = 0;
chooser.setCurrentDirectory(new File(this.tesseractPath));
int returnVal = chooser.showOpenDialog(this);
if (returnVal == 0)
{
File f = chooser.getSelectedFile();
this.selectedFiles.add(f);
updateShowedList();
}
}
private void removeAllButtonActionPerformed(ActionEvent evt)
{
this.selectedFiles.clear();
updateShowedList();
}
private void runButtonActionPerformed(ActionEvent evt)
{
for (File fs : this.selectedFiles)
{
String executeCom = this.tesseractPath + "\\tesseract.exe " + fs.getAbsolutePath() + " " + this.tesseractPath + "\\" + fs.getName().subSequence(0, fs.getName().length() - 4) + "";
System.out.println(" --- " + executeCom);
try
{
this.logTextArea.append("Starting tesseract for: \n" + fs.getName() + "\n");
Process p = Runtime.getRuntime().exec(executeCom);
p.waitFor();
if (p.exitValue() == 0) {
this.logTextArea.append("Done: \n" + fs.getName().subSequence(0, fs.getName().length() - 4) + ".txt \n");
} else {
this.logTextArea.append("Errors for: \n" + fs.getName().subSequence(0, fs.getName().length() - 4) + ".txt \n");
}
}
catch (InterruptedException ex)
{
Logger.getLogger(TessFrame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex)
{
Logger.getLogger(TessFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void aboutButtonActionPerformed(ActionEvent evt)
{
AboutDlg adlg = new AboutDlg(this, true);
adlg.setVisible(true);
}
private void changePathButtonActionPerformed(ActionEvent evt)
{
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Select Tesseract Path");
chooser.setFileSelectionMode(1);
chooser.setCurrentDirectory(new File(this.tesseractPath));
int returnVal = chooser.showOpenDialog(this);
if (returnVal == 0)
{
this.tesseractPath = chooser.getSelectedFile().getAbsolutePath();
this.tessPathTextField.setText(this.tesseractPath);
}
}
private void updateShowedList()
{
this.fileList.removeAll();
for (File fs : this.selectedFiles) {
this.fileList.add(fs + "");
}
}
private void updateLog()
{
String fileLogName = this.tesseractPath + "\\tesseract.log";
File tessLog = new File(fileLogName);
String s = "";
if (tessLog.canRead()) {
try
{
FileReader fRed = new FileReader(fileLogName);
BufferedReader in = new BufferedReader(fRed);
while ((s = in.readLine()) != null) {
this.logTextArea.append(s + "\n");
}
}
catch (IOException e)
{
System.err.println("Unable to read from file");
System.exit(-1);
}
}
}
}
`
I am making a simple 1v1 "private chat" using TCP in java. Currently, i have a problem whenever i am using JButtons. This is my first attempt at using JButtons and ActionListeners so i'm not 100% sure whats going on here.
I have two separate projects for the Server and the Client.
To compile these, it would have to be two separate projects.
The problem occurs when i try to hit the button to either
A: Start the server
B: Connect to the server.
The button freezes as if it is in the pushed state. While running the server and hitting the button, to "unpress" the button, a client has to try and connect. The server sends out a MOTD to the client and the client should print that out onto the text window. It prints out the MOTD only once the server is closed. Again, not sure why
The server code:
package net.valid4life.chat;
import java.awt.Component;
public class Chat implements ActionListener {
private static final long serialVersionUID = 1L;
private static JFrame mainFrame;
private static JPanel contentPane;
private static JTextArea chatWindow;
private static JTextArea serverWindow;
private static JTextField chatBox;
private static JTextField portBox;
private static JLabel currentStatusL;
private static JLabel portl;
private static JLabel status;
private static JButton startServerButton;
private static int port = 1234;
public static final int NOT_STARTED = 0;
public static final int WAITING_FOR_CLIENT = 1;
public static final int CONNECTED = 2;
private static int currentStatus = NOT_STARTED;
public static String newLine = "\n";
public static boolean started = false;
static ServerSocket listener = null;
public static void initGUI() {
mainFrame = new JFrame("Chat Server");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
mainFrame.setContentPane(contentPane);
contentPane.setLayout(null);
chatWindow = new JTextArea();
chatWindow.setLineWrap(true);
chatWindow.setEditable(false);
chatWindow.setBounds(220, 15, 200, 215);
chatWindow.setAlignmentY(Component.BOTTOM_ALIGNMENT);
contentPane.add(chatWindow);
serverWindow = new JTextArea();
serverWindow.setLineWrap(true);
serverWindow.setEditable(false);
serverWindow.setBounds(10, 150, 201, 80);
contentPane.add(serverWindow);
chatBox = new JTextField();
chatBox.setBounds(221, 236, 199, 20);
contentPane.add(chatBox);
chatBox.setColumns(10);
portBox = new JTextField("1234");
portBox.setBounds(68, 37, 86, 25);
portBox.setActionCommand("portEnter");
portBox.setColumns(10);
contentPane.add(portBox);
portl = new JLabel("Port:");
portl.setFont(new Font("Times New Roman", Font.PLAIN, 16));
portl.setBounds(95, 20, 64, 14);
contentPane.add(portl);
status = new JLabel("Status:");
status.setFont(new Font("Times New Roman", Font.PLAIN, 16));
status.setBounds(15, 239, 46, 14);
contentPane.add(status);
currentStatusL = new JLabel(changeStatus(NOT_STARTED));
currentStatusL.setFont(new Font("Times New Roman", Font.PLAIN, 16));
currentStatusL.setBounds(60, 239, 151, 14);
contentPane.add(currentStatusL);
startServerButton = new JButton("Start Server");
startServerButton.setFont(new Font("Times New Roman", Font.PLAIN, 13));
startServerButton.setBounds(60, 96, 100, 40);
startServerButton.setActionCommand("start");
startServerButton.addActionListener(new Chat());
contentPane.add(startServerButton);
mainFrame.setVisible(true);
}
public static void main(String[] args) throws IOException {
initGUI();
}
public void actionPerformed(ActionEvent e) {
if ("start".equals(e.getActionCommand())) {
try {
port = Integer.parseInt(portBox.getText());
startServerButton.setEnabled(false);
listener = new ServerSocket(port);
changeStatus(WAITING_FOR_CLIENT);
serverWindow.append("The server has started on "
+ listener.getLocalPort());
} catch (IOException e1) {
e1.printStackTrace();
} finally {
try {
startServer();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}else
System.out.println("YOU BROKE IT");
}
public static void startServer() throws IOException {
try {
System.out.println("Looking for client");
new ServerThread(listener.accept()).start();
System.out.println("Found client");
} catch (Exception e) {
e.printStackTrace();
} finally {
listener.close();
}
}
public static String changeStatus(int newStatus) {
String newStatusText;
switch (newStatus) {
case 0:
newStatusText = "Server not started.";
break;
case 1:
newStatusText = "Waiting for client.";
break;
case 2:
newStatusText = "Connected to client.";
break;
default:
newStatusText = "Broken";
}
currentStatus = newStatus;
return newStatusText;
}
public static class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
Chat.serverWindow.append("New Connection from:"
+ socket.getInetAddress() + Chat.newLine);
Chat.changeStatus(CONNECTED);
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(),
true);
out.println("MOTD:Welcome to the testing phase of this chat!");
out.println("To view commands simply type /help");
while (true) {
String input = in.readLine();
if (input == null || input.equals(".")) {
break;
}
out.println(input);
}
} catch (IOException e) {
Chat.serverWindow.append("Error handling client");
} finally {
try {
socket.close();
} catch (IOException e) {
Chat.serverWindow
.append("Couldn't close a socket, what's going on?");
}
Chat.serverWindow.append("Connection with client closed");
}
}
}
}
The client code:
package net.valid4life.chat;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Chat implements ActionListener {
private static JFrame mainFrame;
private static JPanel contentPane;
private static JTextArea chatWindow;
private static JTextField chatBox;
private static JTextField portBox;
private static JLabel currentStatusL;
private static JLabel portl;
private static JLabel status;
private static JButton connectButton;
private static int port = 1234;
private static String hostIP = "127.0.0.1";
public static final int NOT_STARTED = 0;
public static final int WAITING_FOR_SERVER = 1;
public static final int CONNECTED = 2;
private static int currentStatus = NOT_STARTED;
public static boolean serverStarted = false;
private static JTextField IPField;
private static JLabel IPL;
private static BufferedReader in;
private static PrintWriter out;
public static void initGUI() {
public static void connectToServer() throws Exception {
port = Integer.parseInt(portBox.getText());
hostIP = IPField.getText();
Socket socket = new Socket("127.0.0.1", 1234);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
for (int i = 0; i < 3; i++) {
chatWindow.append(in.readLine() + "\n");
}
// connectButton.setEnabled(false);
}
public static void main(String[] args) throws Exception {
initGUI();
connectToServer();
}
public void actionPerformed(ActionEvent e) {
if ("start".equals(e.getActionCommand())) {
try {
connectToServer();
} catch (Exception e1) {
e1.printStackTrace();
}
} else {System.out.println("ASDASD");}
}
public static String changeStatus(int newStatus) {
String newStatusText;
switch (newStatus) {
case 0:
newStatusText = "Server not started.";
break;
case 1:
newStatusText = "Waiting for client.";
break;
case 2:
newStatusText = "Connected to client.";
break;
default:
newStatusText = "Broken";
}
currentStatus = newStatus;
return newStatusText;
}
}
Thanks in advance for the help!
Your server code runs well, but your client is blocking the Event Dispatching Thread when you call connectToServer.
The Event Dispatching Thread is responsible for, amongst other things, processing repaint requests and new input events. If you block this thread for any reasons, then there is no way that the Event Dispatching Thread can process any new events...
All blocking or long running tasks should be executed out side of the context of the Event Dispatching Thread.
Take a look at Concurrency in Swing for more details
I'm writing a simply chat client and am moving it over to a nice GUI. The constructor for the server side (client side is android) contains a list that's in the JFrame, and the first part of the server runs, but then the entire frame locks up. Does anyone see the issue? Sorry for the relatively disorganized, not cleanly commented code...
Server:
import java.awt.List;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class ChatServer {
private final int CHAT_PORT = 4453;
ServerSocket sSocket;
Socket cSocket;
PrintWriter pWriter;
BufferedReader bReader;
InetAddress localAddr;
List messageList;
public ChatServer(List entList)
{
messageList = entList;
}
public synchronized void run()
{
messageList.add("Chat Server Starting...");
try {
localAddr = InetAddress.getLocalHost();
} catch (UnknownHostException e1) {
messageList.add("InnetAddress error");
}
while(true)
{
try {
sSocket = new ServerSocket(CHAT_PORT);
sSocket.setReuseAddress(true);
messageList.add("Server has IP:" + localAddr.getHostAddress());
messageList.add("Server has hostname:" + localAddr.getHostName());
messageList.add("Server has port:" + CHAT_PORT);
} catch (IOException e) {
//ERRORS
if(cSocket.isConnected())
{
messageList.add("User disconnected\n");
try {
cSocket.close();
} catch (IOException e1) {
messageList.add("Error closing client socket");
}
}
else
{
messageList.add("ERROR CREATING SOCKET\n");
}
}
try {
cSocket = sSocket.accept();
cSocket.setReuseAddress(true);
messageList.add("INFO: socket connected");
} catch (IOException e) {
messageList.add("Client Socket Error");
System.exit(-1);
}
try {
pWriter = new PrintWriter(cSocket.getOutputStream(), true);
messageList.add("INFO: Print writer opened");
} catch (IOException e) {
messageList.add("PrintWriter error");
}
try {
bReader = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
messageList.add("INFO: buffered reader opened");
} catch (IOException e) {
messageList.add("BufferedReader error");
}
String inputLine;
try {
while((inputLine = bReader.readLine()) != null)
{
messageList.add(inputLine);
if(inputLine.equals("close"))
{
close();
}
}
} catch (IOException e) {
messageList.add("Buffered Reader error");
}
}
}
public synchronized void close()
{
messageList.add("****Server closing****");
try {
sSocket.close();
} catch (IOException e) {
messageList.add("Error closing server socket");
}
try {
cSocket.close();
} catch (IOException e) {
messageList.add("Error closing client socket");
}
pWriter.close();
try {
bReader.close();
} catch (IOException e) {
messageList.add("Error closing buffered reader");
}
messageList.add("****It's been fun, but I've got to go.****\n****Server has shut down.****");
System.exit(0);
}
}
GUI:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.List;
import java.awt.Toolkit;
#SuppressWarnings("serial")
public class ClientGUI extends JFrame {
private JPanel contentPane;
private JTextField txtEnterTextHere;
private JMenuBar menuBar;
private List messageList;
private JMenu mnOptions;
private JMenu mnHelp;
private JMenuItem mntmStartServer;
private JMenuItem mntmStopServer;
private JMenuItem mntmConnectionInfo;
private JMenuItem mntmEmailDeveloper;
private static String userName;
private ChatServer cServer;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ClientGUI frame = new ClientGUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ClientGUI() {
setTitle("Ben's Chat Client");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mnFile = new JMenu("File");
menuBar.add(mnFile);
JMenuItem mntmExit = new JMenuItem("Exit");
mntmExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showConfirmDialog(null, "Are you sure you want to exit?");
}
});
mnFile.add(mntmExit);
mnOptions = new JMenu("Options");
menuBar.add(mnOptions);
mntmStartServer = new JMenuItem("Start Server");
mntmStartServer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ChatServer cServer = new ChatServer(messageList);
cServer.run();
}
});
mnOptions.add(mntmStartServer);
mntmStopServer = new JMenuItem("Stop Server");
mnOptions.add(mntmStopServer);
mntmConnectionInfo = new JMenuItem("Connection Info");
mnOptions.add(mntmConnectionInfo);
mnHelp = new JMenu("Help");
menuBar.add(mnHelp);
mntmEmailDeveloper = new JMenuItem("Email Developer");
mnHelp.add(mntmEmailDeveloper);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
txtEnterTextHere = new JTextField();
txtEnterTextHere.setBounds(10, 220, 334, 20);
txtEnterTextHere.setText("Enter text here...");
contentPane.add(txtEnterTextHere);
txtEnterTextHere.setColumns(10);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
messageList.add(userName + ": " + txtEnterTextHere.getText().toString());
}
});
messageList = new List();
btnSend.setBounds(349, 219, 85, 23);
contentPane.add(btnSend);
messageList.setBounds(10, 10, 424, 204);
contentPane.add(messageList);
}
public static String getUsername()
{
return userName;
}
public static void setUsername(String entName)
{
userName = entName;
}
}
Thanks!
It looks like you're starting the server on the Swing thread (see: The Event Dispatch Thread). As soon as you call cServer.run(); in the ActionListener, you are blocking the EDT from doing anything else (such as updating your JFrame and responding to events). Start your server in a background thread instead:
new Thread(new Runnable()
{
#Override
public void run()
{
// start your server
}
}).start();