Buffer listener to server output ERROR - java

I have a problem with listening to my server output. I would like to be able to print something to the console as soon as one of the quoted command. The problem that I face is that it seems to be listening but then not go along with the rest of the program. So when I try to click on a button on my GUI, it get stuck.
public class MainFrame implements Runnable {
//declare Jpanel
private static JFrame frmHome;
// The client socket
private static Socket clientSocket = null;
// The output stream
static ObjectOutputStream os;
// The input stream
static ObjectInputStream is;
private static BufferedReader inputLine = null;
private static boolean closed = false;
public static void main(String[] args) throws IOException{
// The default port.
int portNumber = 3333;
// The default host.
String host = "localhost";
/*
* Open a socket on a given host and port. Open input and output streams.
*/
try {
clientSocket = new Socket(host, portNumber);
is = new ObjectInputStream(clientSocket.getInputStream());
os = new ObjectOutputStream(clientSocket.getOutputStream());
os.flush();
System.out
.println("CONNECTED TO SERVER\n"
+ "Now using host=" + host + ", portNumber=" + portNumber);
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + host);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to the host "
+ host);
}
/*
* If everything has been initialized then we want to write some data to the
* socket we have opened a connection to on the port portNumber.
*/
if (clientSocket != null && os != null && is != null) {
/* Create a thread to read from the server. */
new Thread(new MainFrame()).start();
os.writeObject("Home");
os.flush();
}
}
public void run() {
/*
* Keep on reading from the socket till we receive "Bye" from the
* server. Once we received that then we want to break.
*/
MainFrame window = new MainFrame();
MainFrame.frmHome.setVisible(true);
String responseLine;
try {
while (!closed) {
Here is where I try to create my buffer reader. The 2 commands "Modify,OK" and "AdStudent ok", are coming after other parts of the GUI have successfully performed a task.
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String line;
try {
while((line = br.readLine()) != null){
if (br.readLine().contains("Modify,OK")
|| br.readLine().contains("AddSudent ok")){
System.out.println("did it");
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} finally{
try {
is.close();
os.close();
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public MainFrame() {
initialize();
}
//function to make window visible
void setVisible() throws IOException {
main(null);
}
private void initialize() {
//Initialise Main window with 3 options.
frmHome = new JFrame();
frmHome.setTitle("Home");
frmHome.setBounds(100, 100, 300, 372);
frmHome.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmHome.getContentPane().setLayout(null);
frmHome.setResizable(false);
JLabel lblWelcomeToSrs = new JLabel("Welcome to SRS");
lblWelcomeToSrs.setFont(new Font("Tahoma", Font.PLAIN, 14));
lblWelcomeToSrs.setBounds(86, 183, 112, 14);
frmHome.getContentPane().add(lblWelcomeToSrs);
//initialise all buttons and labels of window.
JButton btnAdStu = new JButton("Add a student");
btnAdStu.setBounds(10, 207, 126, 23);
btnAdStu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
AddStudentFrame adus;
try {
try {
adus = new AddStudentFrame();
adus.setVisible();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frmHome.setVisible(false);
} catch (ParseException e) {
e.printStackTrace();
}
}
});
frmHome.getContentPane().add(btnAdStu);
JButton btnCheckStud = new JButton("Search / Modify");
btnCheckStud.setBounds(146, 207, 127, 23);
btnCheckStud.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
SearchFrame searchFrame;
searchFrame = new SearchFrame();
searchFrame.setVisible();
}
});
frmHome.getContentPane().add(btnCheckStud);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setBounds(0, 0, 0, 0);
frmHome.getContentPane().add(lblNewLabel);
JLabel lblCreatedByRmi = new JLabel("Created by R\u00E9mi Tuyaerts");
lblCreatedByRmi.setBounds(147, 318, 184, 14);
frmHome.getContentPane().add(lblCreatedByRmi);
JButton btnNewButton = new JButton("Complete List of Students");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
CompleteListFrame studentList = new CompleteListFrame();
studentList.setVisible();
}
});
btnNewButton.setBounds(52, 241, 184, 23);
frmHome.getContentPane().add(btnNewButton);
// wonderful pictures of his excellence design by Yasser
JLabel lblNewLabel_1 = new JLabel("");
Image img = new ImageIcon(frmHome.getClass().getResource("/michaelchung.jpg")).getImage();
lblNewLabel_1.setIcon(new ImageIcon(img));
lblNewLabel_1.setBounds(80, 11, 120, 148);
frmHome.getContentPane().add(lblNewLabel_1);
}
}

Related

Java Socket need to get name of sender

I'm starting with Socket Server in Java. I've written already simple app where I can send text between hosts. I'm sending with my message name of the host which is sending and here is my problem, how can I get host message?
Can someone just change my code to show host name instead of message?
Here is the code:
public class FMain extends JFrame {
private JPanel contentPane = null;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FMain frame = new FMain();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public FMain() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 508, 321);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
PReceiver receiver = new PReceiver();
receiver.setBorder(new LineBorder(new Color(0, 0, 0)));
receiver.setBounds(35, 13, 423, 106);
contentPane.add(receiver);
PSender sender = new PSender((String) null, 0);
sender.setBorder(new LineBorder(new Color(0, 0, 0)));
sender.setBounds(35, 132, 423, 129);
contentPane.add(sender);
}
}
And the class which is receiving:
interface MyListener {
void messageReceived(String theLine);
}
class Receiver {
private List < MyListener > ml = new ArrayList < MyListener > ();
private Thread t = null;
private int port = 0;
private ServerSocket s = null;
private boolean end = false;
public void stop() {
t.interrupt();
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
end = false;
t = new Thread(new Runnable() {
#Override
public void run() {
try {
s = new ServerSocket(port);
while (true) {
Socket sc = s.accept();
InputStream is = sc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String theLine = br.readLine();
ml.forEach((item) - > item.messageReceived(theLine));
sc.close();
}
} catch (SocketException e) {} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t.start();
}
public void addMyListener(MyListener m) {
ml.add(m);
}
public void removeMyListener(MyListener m) {
ml.remove(m);
}
Receiver(int port) {
this.port = port;
}
}
public class PReceiver extends JPanel implements MyListener {
private JTextField txtPort;
private Receiver r = null;
private JTextField txtMessage;
/**
* Create the panel.
*/
public PReceiver() {
setLayout(null);
txtPort = new JTextField();
txtPort.setBounds(282, 13, 62, 22);
add(txtPort);
// txtPort.setColumns(10);
JLabel lblPort = new JLabel("port:");
lblPort.setBounds(241, 16, 35, 16);
add(lblPort);
JToggleButton btnListen = new JToggleButton("Listen");
btnListen.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (btnListen.isSelected()) {
r = new Receiver(Integer.parseInt(txtPort.getText()));
r.addMyListener(PReceiver.this);
r.start();
} else {
r.stop();
}
}
});
btnListen.setBounds(265, 70, 79, 25);
add(btnListen);
JLabel lblMessage = new JLabel("message");
lblMessage.setBounds(12, 51, 56, 16);
add(lblMessage);
txtMessage = new JTextField();
txtMessage.setBounds(12, 71, 220, 22);
add(txtMessage);
//txtMessage.setColumns(10);
}
#Override
public void messageReceived(String theLine) {
txtMessage.setText(theLine);
}
}
And the sender class:
class Sender {
public void send(String message, String host, int port) {
Socket s;
try {
s = new Socket(host, port);
OutputStream out = s.getOutputStream();
PrintWriter pw = new PrintWriter(out, false);
pw.println(message);
pw.flush();
pw.close();
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class PSender extends JPanel {
private JTextField txtMessage;
private JTextField txtHost;
private JTextField txtPort;
private JLabel lblMessage;
/**
* Create the panel.
*/
public PSender(String host, int port) {
setLayout(null);
txtMessage = new JTextField();
txtMessage.setBounds(12, 77, 216, 22);
add(txtMessage);
//txtMessage.setColumns(10);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
new Sender().send(txtMessage.getText(), txtHost.getText(), Integer.parseInt(txtPort.getText()));
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
});
btnSend.setBounds(268, 76, 78, 25);
add(btnSend);
txtHost = new JTextField();
txtHost.setBounds(51, 13, 149, 22);
add(txtHost);
//txtHost.setColumns(10);
txtPort = new JTextField();
txtPort.setBounds(268, 13, 78, 22);
add(txtPort);
//txtPort.setColumns(10);
JLabel lblHost = new JLabel("host:");
lblHost.setBounds(12, 16, 35, 16);
add(lblHost);
JLabel lblPort = new JLabel("port:");
lblPort.setBounds(231, 16, 35, 16);
add(lblPort);
lblMessage = new JLabel("message");
lblMessage.setBounds(12, 58, 56, 16);
add(lblMessage);
}
}

method not working inside addactionlister

I am trying to build a LAN communication software where the process should be like this, when the user is logged in then networking between the client and server should start.
The problem that I am facing is that whenever I put my startRunning()(this is the method that starts the networking) method inside the addactionlistener of the button the whole software freezes but if I put the method outside of addactionlistener the networking starts fine. The problem is in the btnNewButton.addActionListener .If the count is 1 then it should call the startrunning() method which it doesn't and the whole software freezes.
Every method starting from the startRunning() method to down below is working perfectly.The database is also capable of checking whether the given username and password is correct or not. This software runs well when the startRunning method is in the constructor but not inside the btnNewButton.addActionListener.
public class Server extends JFrame {
private JTextField userText;
private JTextArea chatWindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
Connection dbconnection = null;
private JTextField textField_1;
private JPasswordField passwordField_1;
public Server() {
super("Communication system");
dbconnection = sqliteConnection.dbConnector();
setupFrame();
}
private void setupFrame() {
setBounds(100, 100, 450, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
JLabel lblNewLabel = new JLabel("UserName");
lblNewLabel.setBounds(10, 11, 81, 14);
getContentPane().add(lblNewLabel);
JLabel lblNewLabel_1 = new JLabel("Password");
lblNewLabel_1.setBounds(10, 36, 59, 14);
getContentPane().add(lblNewLabel_1);
JButton btnNewButton = new JButton("Login");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
String query = "SELECT * FROM EmplyeeInfo WHERE Username=? and password=?";
PreparedStatement pst = dbconnection
.prepareStatement(query);
pst.setString(1, textField_1.getText());
pst.setString(2, passwordField_1.getText());
ResultSet rs = pst.executeQuery();
int count = 0;
while (rs.next()) {
count++;
}
if (count == 1) {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null,
"Correct Username and Password");
startRunning();
} else {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null, "Wrong try again");
}
rs.close();
pst.close();
} catch (Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(null, e);
}
}
});
btnNewButton.setBounds(335, 7, 89, 23);
getContentPane().add(btnNewButton);
textField_1 = new JTextField();
textField_1.setBounds(101, 8, 224, 20);
getContentPane().add(textField_1);
passwordField_1 = new JPasswordField();
passwordField_1.setBounds(101, 33, 224, 20);
getContentPane().add(passwordField_1);
userText = new JTextField();
userText.setBounds(10, 230, 330, 20);
userText.setEditable(false);
userText.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
// TODO Auto-generated method stub
sendMessage(event.getActionCommand());
userText.setText("");
}
});
getContentPane().add(userText);
userText.setColumns(10);
chatWindow = new JTextArea();
chatWindow.setBounds(10, 75, 330, 144);
getContentPane().add(chatWindow);
setVisible(true);
}
// set up and run the server
public void startRunning() {
try {
server = new ServerSocket(6789, 100);
while (true) {
try {
waitForConnection();
setupStreams();
whileChatting();
} catch (EOFException eofException) {
// TODO: handle exception
showMessage("\nServer Ended the conection!");
} finally {
closeCrap();
}
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
// wait for the connection, then display connection
private void waitForConnection() throws IOException {
showMessage("Waiting for someone to connect... \n");
connection = server.accept();
showMessage(" Now connected to "
+ connection.getInetAddress().getHostName());
}
// get stream to send and receive data
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n Streams are now Setup \n");
}
// during the chat conversation
private void whileChatting() throws IOException {
String message = " You are now connected";
sendMessage(message);
ableToType(true);
do {
// have a conversation
try {
message = (String) input.readObject();
showMessage("\n" + message);
} catch (ClassNotFoundException classNotFoundException) {
showMessage("\n I don't know what the user send");
}
} while (!message.equals("CLIENT - END"));
}
// closing the streams and sockets after done chatting
private void closeCrap() {
showMessage("\n closing connections...\n");
ableToType(false);
try {
output.close();
input.close();
connection.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
// send message to a client
private void sendMessage(String message) {
try {
output.writeObject("SERVER - " + message);
output.flush();
showMessage("\nSERVER -" + message);
} catch (IOException ioException) {
chatWindow.append("\n Error : can't send the message");
}
}
// updates chat window
private void showMessage(final String text) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
chatWindow.append("" + text);
}
});
}
// allowing user to type stuff in the box
private void ableToType(final boolean tof) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
userText.setEditable(tof);
}
});
}
}
You may have to put it in a different thread - you can localize the thread to include only the startRunning method or what you want:
public void actionPerformed(ActionEvent arg0) {
Thread th=new Thread() {
public void run() {
try {
String query = "SELECT * FROM EmplyeeInfo WHERE Username=? and password=?";
PreparedStatement pst = dbconnection
.prepareStatement(query);
pst.setString(1, textField_1.getText());
pst.setString(2, passwordField_1.getText());
ResultSet rs = pst.executeQuery();
int count = 0;
while (rs.next()) {
count++;
}
if (count == 1) {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null,
"Correct Username and Password");
startRunning();
} else {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null, "Wrong try again");
}
rs.close();
pst.close();
} catch (Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(null, e);
}
}
};
th.start();
});

Adding java variable to batch file

Here's my updated code. This is the button being clicked in the class I made separate form the java class you provided. I know it says Ping (disregard that, I'm using the button for testing purposes) I don't see how they would reference each other with the Process P line of code you provided. What do you think?
JButton btnPingComputer = new JButton("PING");
btnPingComputer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String line;
BufferedWriter bw = null;
BufferedWriter writer =null;
try {
writer = new BufferedWriter(new FileWriter(tempFile));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String lineToRemove = "OU=Workstations";
String s = null;
Process p = null;
try {
p = Runtime.getRuntime().exec("cmd /c start c:\\computerQuery.bat computerName");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
p = Runtime.getRuntime().exec("c:\\computerQuery.bat");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
StringBuffer sbuffer = new StringBuffer(); // new trial
BufferedReader in = new BufferedReader(new InputStreamReader(p
.getInputStream()));
try {
while ((line = in.readLine()) != null) {
System.out.println(line);
textArea.append(line);
textArea.append(String.format(" %s%n", line));
String dn = "CN=FDCD111304,OU=Workstations,OU=SIM,OU=Accounts,DC=FL,DC=NET";
LdapName ldapName = new LdapName(dn);
String commonName = (String) ldapName.getRdn(ldapName.size() - 1).getValue();
System.out.println(commonName);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidNameException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
try {
fw.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Add the parameter to your java program like this :
Process p = Runtime.getRuntime().exec("cmd /c start c:\\batFile.bat computerName");
This will pass parameter_to_pass to the batch file.
For your situation this code should work well:
/*
This java program copies the value from a jTextField, adds it to a predifined value
and send it to command-line as a parameter. All these happens if you click the jButton
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class cmdJavaTest extends JFrame {
JTextField jTextField1 = new JTextField(20);
JButton jButton1 = new JButton("Click");
JLabel jLabel1 = new JLabel();
public cmdJavaTest() {
super("CmdJavaParameterPass");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jTextField1);
getContentPane().add(jButton1);
getContentPane().add(jLabel1);
jButton1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
sendParam();
}
});
setSize(300, 170);
setVisible(true);
}
public void sendParam(){
try{
String val = "Computer"+jTextField1.getText(); //Put whatever you want to pass as a prefix in place of "Computer"
jLabel1.setText(val);
Process p ;
p = Runtime.getRuntime().exec("cmd /c start c:\\batFile.bat "+val+"");
}
catch(Exception e){
e.printStackTrace();
}
}
public static void main(String argv[]) {
new cmdJavaTest();
}
}
Use this as you test batch file content
#dsquery computer -name %1
pause
But you must also see how to use a ProcessBuilder.
Thanks, hope it helps

using Button and Timer Simultaneously in java

I have two buttons and and Timer. When I run the code it gets connected to the Socket. For every 1000 milliseconds timer should send the command(message) to the Socket and simultaneously when I click a button it should send other message as in the code. But problem is that when I click a button either the messages which are sent are delayed or messages are not sent properly through dat is the receiving end is not receiving properly.
How to handle this issue?
Here is my code
public static void main(String[] args)
{
// TODO Auto-generated method stub
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
configure config=new configure();
config.run();
config.setVisible(true);
}
});
}
protected void run()
{
// TODO Auto-generated method stub
try {
connection.setText("Connected to < NONE >");
socket=new Socket("192.168.1.3",3000);
// System.out.println("Connection Established") ;
connection.setText("CONNECTION ESTABLISHED WITH : " + "< " +
socket.getInetAddress() + " >" + "\n");
} catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// System.out.println("connection failed");
connection.setText("CONNECTION FAILED");
}
}
public configure()
{
setResizable(false);
setBounds(300,80,800,600);
contentPane=new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5,5));
setContentPane(contentPane);
contentPane.setLayout(null);
configlabel=new JLabel("CONFIGURE YOUR MODEL");
configlabel.setBounds(210,20,500,40);
configlabel.setFont(new Font("arial",Font.BOLD,28));
contentPane.add(configlabel);
connection=new JLabel();
connection.setBounds(12,80,500,40);
connection.setFont(new Font("arial",Font.BOLD,16));
contentPane.add(connection);
channel1=new JLabel("Channel 1");
channel1.setBounds(80, 140, 80, 30);
channel1.setFont(new Font("arial",Font.BOLD,15));
contentPane.add(channel1);
channel1Field=new JTextField();
channel1Field.setBounds(55, 200, 120, 30);
channel1Field.setEnabled(true);
contentPane.add(channel1Field);
channel1send=new JButton("Send 1");
channel1send.setBounds(65, 270, 100, 30);
channel1send.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
if(!(channel1Field.getText().equals("")))
{
// TODO Auto-generated method stub
if(channel1send.isEnabled())
{
new Thread(new Channel1()).start();
}
}
else
{
JOptionPane optionPane = new JOptionPane("Field cannot be
empty", JOptionPane.ERROR_MESSAGE);
JDialog dialog = optionPane.createDialog("FAILURE");
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
}
}
});
contentPane.add(channel1send);
channel2=new JLabel("Channel 2");
channel2.setBounds(255, 140, 80, 30);
channel2.setFont(new Font("arial",Font.BOLD,15));
contentPane.add(channel2);
channel2Field=new JTextField();
channel2Field.setBounds(230, 200, 120, 30);
channel2Field.setEnabled(true);
contentPane.add(channel2Field);
channel2send=new JButton("Send 2");
channel2send.setBounds(250, 270, 80, 30);
channel2send.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(!(channel2Field.getText().equals("")))
{
if(channel2send.isEnabled())
{
new Thread(new Channel2()).start();
}
}
else
{
JOptionPane optionPane = new JOptionPane("Field cannot
be empty", JOptionPane.ERROR_MESSAGE);
JDialog dialog = optionPane.createDialog("FAILURE");
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
}
}
});
contentPane.add(channel2send);
Timer timer = new Timer();
timer.schedule(new SayHello(), 0, 1000);
}
class SayHello extends TimerTask {
public void run() {
try
{
byte[] com=new byte[]{0x01,(byte)0xFE};
socket=new Socket("192.168.1.3",3000);
DataOutputStream dw=new DataOutputStream(socket.getOutputStream());
dw.writeInt(com.length);
dw.write(com);
StringBuilder sb=new StringBuilder();
for(byte b:com)
{
sb.append(String.format("%02X ", b));
}
sentmessage.append("Timer Sent - " + sb.toString() + "\n");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
class Channel1 implements Runnable
{
#Override
public void run()
{
// TODO Auto-generated method stub
try {
String message1=channel1Field.getText();
int msg1=Integer.parseInt(message1);
command=new byte[]{(byte)0xFE,0x01,0x01,(byte)msg1,0x00,0x00,(byte)0xFD};
DataOutputStream dw=new DataOutputStream(socket.getOutputStream());
// dw.writeInt(command.length);
dw.write(command);
StringBuilder sb=new StringBuilder();
// System.out.println(Arrays.toString(command));
for(byte b:command)
{
sb.append(String.format("%02X ", b));
}
sentmessage.append("Client Sent to Channel 1 - " +
sb.toString() + "\n");
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
sentmessage.append("channel 1 failed to send");
}
finally
{
if(socket!=null)
{
try
{
socket.close();
socket=new Socket("192.168.1.3",3000);
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
}
class Channel2 implements Runnable
{
#Override
public void run()
{
// TODO Auto-generated method stub
try {
String message2=channel2Field.getText();
int msg2=Integer.parseInt(message2);
command=new byte[]{(byte)0xFE,0x01,0x02,(byte)msg2,0x00,0x00(byte)0xFD};
DataOutputStream dw=new DataOutputStream(socket.getOutputStream());
// dw.writeInt(command.length);
dw.write(command);
StringBuilder sb=new StringBuilder();
for(byte b:command)
{
sb.append(String.format("%02X ", b));
}
sentmessage.append("Client Sent to Channel 2 - " +
sb.toString() + "\n");
}
catch (IOException e1)
{
e1.printStackTrace();
sentmessage.append("channel 2 on failed");
}
finally
{
if(socket!=null)
{
try {
socket.close();
socket=new Socket("192.168.1.3",3000);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
}

Java - send a file over socket(chat client -> server -> another chat client)

So I'm working on a chat program and now I want to add a send file option.
I tried adding it and it worked but right after the file transfer finishes, both of the sockets close(the sockets of the two clients).
Here is an SSCCE for the Chat client:
public class SSCCEChatClient extends JFrame {
private JPanel contentPane;
private JTextField inputUsernameField;
private JTextArea textArea;
String serversock = "84.252.37.82";
String username;
Socket sock;
BufferedReader reader;
PrintWriter writer;
InputStreamReader streamreader;
public class IncomingReader implements Runnable{
public void run() {
String stream;
String[] data;
try {
while ((stream = reader.readLine()) != null) {
data = stream.split("`");
if(data[2].equals("receiveFile")&&(!data[3].equals(username))){
DataInputStream in = new DataInputStream(sock.getInputStream());
byte[] bytes = new byte[Integer.parseInt(data[1])];
in.read(bytes);
FileOutputStream fos = new FileOutputStream(System.getProperty("user.home") + "\\Desktop\\" + data[0]);
fos.write(bytes);
fos.close();
in.close();
textArea.append("Success!");
}else if(data[2].equals("server")){
textArea.append(data[0]);
}
}
}catch(Exception ex) {
}
}
}//Incoming Reader
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SSCCEChatClient frame = new SSCCEChatClient();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SSCCEChatClient() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
textArea = new JTextArea();
contentPane.add(textArea, BorderLayout.SOUTH);
JButton btnNewButton = new JButton("Send File");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
File transferFile = new File (System.getProperty("user.home") + "\\Desktop\\PNG\\Night.png");
byte [] bytearray = new byte [(int)transferFile.length()];
try {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(transferFile));
bin.read(bytearray,0,bytearray.length);
DataOutputStream os = new DataOutputStream(sock.getOutputStream());
writer.println(transferFile.getName() + "`" + transferFile.length() + "`receiveFile`" + username);
writer.flush();
os.write(bytearray,0,bytearray.length);
os.flush();
bin.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("File transfer complete");
}
});
contentPane.add(btnNewButton, BorderLayout.CENTER);
JButton btnNewButton_1 = new JButton("Connect");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
username = inputUsernameField.getText();
sock = new Socket(serversock, 5000);
streamreader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(streamreader);
writer = new PrintWriter(sock.getOutputStream());
Thread IncomingReader = new Thread(new IncomingReader());
IncomingReader.start();
writer.println(username + "``connect");
writer.flush();
} catch (Exception ex) {
textArea.append("\nCannot Connect!");
}
}
});
contentPane.add(btnNewButton_1, BorderLayout.WEST);
inputUsernameField = new JTextField();
contentPane.add(inputUsernameField, BorderLayout.NORTH);
inputUsernameField.setColumns(10);
}
}
and here is the Server side:
public class SSCCEServer {
static ArrayList<PrintWriter> clientOutputStreams;
static ArrayList<DataOutputStream> clientDataOutputStreams;
static ArrayList<String> onlineUsers = new ArrayList<>();
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
PrintWriter client;
public ClientHandler(Socket clientSocket, PrintWriter user) {
// new inputStreamReader and then add it to a BufferedReader
client = user;
try {
sock = clientSocket;
System.out.println(clientSocket.getRemoteSocketAddress().toString() + " - ");
InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(isReader);
}
catch (Exception ex) {
System.out.println("error beginning StreamReader");
}
}
public void run() {
String message;
String[] data;
try {
while ((message = reader.readLine()) != null) {
data = message.split("`");
if(data[2].equals("receiveFile")){
DataInputStream in = new DataInputStream(sock.getInputStream());
byte[] bytes = new byte[Integer.parseInt(data[1])];
in.read(bytes);
tellEveryone(data[0] + "`" + data[1] + "`" + data[2] + "`" + data[3]);
for(DataOutputStream dos:clientDataOutputStreams){
try {
dos.write(bytes);
dos.close();
}
catch (Exception ex) {
System.out.println("error telling everyone");
}
}
tellEveryone("File transfer complete``server");
}else if(data[2].equals("connect")){
System.out.println(data[0] + "has connected.");
}else {
System.out.println("No Conditions were met.");
}
}
}
catch (Exception ex) {
System.out.println("lost a connection");
System.out.println(ex.getMessage().toString());
clientOutputStreams.remove(client);
}
}
}
public void tellEveryone(String message) {
// sends message to everyone connected to server
for(PrintWriter writer:clientOutputStreams){
try {
writer.println(message);
//pop("Sending: " + message);
writer.flush();
}
catch (Exception ex) {
System.out.println("error telling everyone");
}
}
}
public static void main(String[] args) {
new SSCCEServer().go();
}
public void go(){
clientOutputStreams = new ArrayList<PrintWriter>();
clientDataOutputStreams = new ArrayList<>();
try {
#SuppressWarnings("resource")
ServerSocket serverSock = new ServerSocket(5000);
while(true){
Socket clientSock = serverSock.accept();
PrintWriter writer = new PrintWriter(clientSock.getOutputStream());
clientOutputStreams.add(writer);
clientDataOutputStreams.add(new DataOutputStream(clientSock.getOutputStream()));
Thread listener = new Thread(new ClientHandler(clientSock, writer));
listener.start();
}
}
catch (Exception ex)
{
System.out.println("error making a connection");
}
}
}
Sorry if it's really long but this is the minimal amount I could bring it to. Also it's not the whole thing because it misses the send text method but that doesn't affect the SSCCE. I've demonstrated the send method with the method 'tellEveryone' from the server side.
Also, the "\PNG\Night.png" is just an example, you can make your own folder and file in order to run the SSCCE.
What can I do to fix the closing of the socket after the file is send?
close all Objects in finally block (try - catch - finally)
you have got issue with Concurency in Swing, but there are three ways
a) proper ways
wrap code to the Runnable#Thread (easiest), have to wrap any changes to the Swing GUI into invokeLater()
use SwingWorker (implemented in standard ways), where methods publish, process and done quite guarante that all events are done on EDT
b) shortcuts, works but not proper of ways
wrap Swing GUI code into invokeLater() directly
The socket closes when you close the output stream. If you want to keep the socket open, do not close the stream. For reference have a look at SocketOutputStream.java

Categories