I am trying to create a server and client(s) app, where the server can send messages to the client(s), and the client(s) can only accept the messages from the server.
I have succeed this goal. The problem is, that the client.jar won't receive any messages from the server. But everything work just fine in netbean.
Any idea why this happen ?
Here's my complete server code :
public sServerUI() {
super("Server : "+System.getenv("COMPUTERNAME")); // mendapatkan nama komputer
initComponents();
}
public void startListener(){
Random randomGen = new Random();
try{
myPort = randomGen.nextInt(9999);
server = new ServerSocket(myPort);//Bebas portnya, tp nggk boleh sudah terpakai atau pakai random jg bisa
btnListen.setEnabled(false);
while(key == null) {
key = JOptionPane.showInputDialog(this, "Input your Key : ", "Insert Key", JOptionPane.PLAIN_MESSAGE);
}
if(key.equals("")) {
key = "Random";
txtMessage.setText(txtMessage.getText()+"Invalid key inputted, key automatically set to '"+key+"'\n");
} else txtMessage.setText(txtMessage.getText()+"Key set to '"+key+"'\n");
} catch (IOException e) {//Kalau sudah terpakai muncul error
JOptionPane.showMessageDialog(this, "Could not listen at " + myPort);
//Gagal, keluarin info
} finally{
myPort = server.getLocalPort();
lblPort.setText("Port: "+myPort);
System.out.println("Port: "+myPort);
}
acceptClient.start();
}
public void windowClosing(WindowEvent e){
try {
server.close();
for (int i=0;i<numberOfClient;i++){
socketIn[i].close();
socketOut[i].close();
}
} catch (IOException ex) {
System.out.println("Error "+ex.getMessage());
}
}
class Accepter extends Thread{
#Override
public void run(){
while (true){
try{
client[numberOfClient] = server.accept();
numberOfClient++;
lblStatus.setText("Status: "+numberOfClient+" client(s) connected");
Handler handleClient = new Handler(numberOfClient-1);
handleClient.start();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Accept failed: " + myPort);
}
}
}
}
class Handler extends Thread{
private int arr;
Handler(int ar){
arr = ar;
try{
socketIn[arr] = new BufferedReader(new InputStreamReader(client[arr].getInputStream()));
socketOut[arr] = new PrintWriter(client[arr].getOutputStream(), true);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Read failed");
}
}
#Override
public void run(){
while (true){
try{
if (socketIn[arr].ready()){
System.out.println("Reading...");
line = socketIn[arr].readLine();
if (!txtMessage.getText().equals("")){
txtMessage.setText(txtMessage.getText()+"\n");
//broadcast message ke client2 lain
}
txtMessage.setText(txtMessage.getText()+"Client "+(arr+1)+": "+line);
for (int i=0;i<numberOfClient;i++){
if (i!=arr){//jgn kembaliin ke client yg kirim
socketOut[i].println("Client "+(arr+1)+": "+line);
}
}
}
} catch (IOException e) {
System.out.println("Read failed");
}
}
}
}
private void btnListenActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
startListener();
}
private void sendData(String data) {
for (int j=0;j<numberOfClient;j++){
socketOut[j].println(data);
}
}
private void btnSendActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if(numberOfClient > 0) {
int packetIndex = 1;
String ext = getExt(filePath, '.');
String sData = "start"+pemisahString+fByte.length+pemisahString+ext+pemisahString; //menaruh kata kunci 'start' dan ukuran file di awal message, serta extensionnya
sendData(sData);
sData = "";
int k = 0;
for(int i = 0; i < fByte.length; i++) {
if(k >= Math.ceil((double)fByte.length/10.0)) {
k = 0;
sData = rc4(key, sData);
sendData(Integer.toString(packetIndex)+pemisahString+sData);
txtMessage.setText(txtMessage.getText()+"packet-"+packetIndex+" sent ! isi : "+revertToString(rc4(key,revertToString(sData)))+"\n");
packetIndex++;
sData = "";
}
sData += fByte[i];
sData += pemisahString;
k++;
if(i == fByte.length-1) {
sData = rc4(key, sData);
sendData(Integer.toString(packetIndex)+pemisahString+sData);
txtMessage.setText(txtMessage.getText()+"packet-"+packetIndex+" sent ! isi : "+revertToString(rc4(key,revertToString(sData)))+"\n");
packetIndex++;
sData = "";
}
}
sData = "end"+pemisahString;
sendData(sData);
txtMessage.setText(txtMessage.getText() + "Done ! divided into "+k+" piece(s) per packet\n");
} else JOptionPane.showMessageDialog(this, "No Client Connected !", "Error", JOptionPane.ERROR_MESSAGE);
}
private void fileBtnActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("d:/Kul/Smstr 6/Kripto n Steno/Stream Cipher/"));
int returnVal = chooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
filePath = chooser.getSelectedFile().getPath();
try {
inputFile = new File(filePath);
fIn = new FileInputStream(inputFile);
fByte = new byte[(int)inputFile.length()];
System.out.println("file size : "+(int)inputFile.length()+" byte(s)");
System.out.print("Isi file : ");
fIn.read(fByte);
fIn.close();
for(int i = 0; i < fByte.length; i ++) {
System.out.print(fByte[i]+" ");
}
System.out.print("end of file\n");
String stringBuatDitampilin = getExt(filePath, (char)92);
txtMessage.setText(txtMessage.getText() + "'" + stringBuatDitampilin + "' Loaded !\n");
btnSend.setEnabled(true);
//fIn.close();
//JOptionPane.showMessageDialog(this, "File Loaded !", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch(java.io.IOException e) {
JOptionPane.showMessageDialog(this, e.toString(), "IO Error", JOptionPane.ERROR_MESSAGE);
}
}
}
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(sServerUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new sServerUI().setVisible(true);
}
});
}
and here's my complete client code :
public sClientUI() {
super("Client");
initComponents();
}
public void listenSocket(){
//Create socket connection
try{
socket = new Socket(txtHost.getText(), Integer.parseInt(txtPort.getText()));
socketOut = new PrintWriter(socket.getOutputStream(), true);
socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
txtMessage.setText(txtMessage.getText()+"Succesfully connected to "+txtHost.getText()+" !\n");
while(key == null) {
key = JOptionPane.showInputDialog(this, "Input your Key : ", "Insert Key", JOptionPane.PLAIN_MESSAGE);
}
if(key.equals("")) {
key = "Random";
txtMessage.setText(txtMessage.getText()+"Invalid key inputted, key automatically set to '"+key+"'\n");
} else txtMessage.setText(txtMessage.getText()+"Key set to '"+key+"'\n");
txtHost.setEditable(false);
txtPort.setEditable(false);
btnConnect.setEnabled(false);
myListener = new Timer(250, readLine);
myListener.start();
} catch (UnknownHostException e) {
JOptionPane.showMessageDialog(this, "Unknown host: "+e.getMessage(), "Unknown Hostname", JOptionPane.ERROR_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "Either your hostname is wrong, or you entered wrong port number\n"+e.getMessage(),"Input Error", JOptionPane.ERROR_MESSAGE);
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(this, e.getMessage(),"Invalid Port Number", JOptionPane.ERROR_MESSAGE);
}
}
public void windowClosing(WindowEvent e){
try {
socket.close();
socketIn.close();
socketOut.close();
} catch (IOException ex) {
System.out.println("Error "+ex.getMessage());
}
}
ActionListener readLine = new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
try{
if (socketIn.ready()){
String tempReceiver;
if((tempReceiver = socketIn.readLine()) != null) {
exStr(tempReceiver); //untuk memotong-motong string dan meng-create file baru
}
}
} catch (IOException e) {
System.out.println("Read failed");
}
}
};
private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
listenSocket();
}
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(sClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new sClientUI().setVisible(true);
}
});
}
the .jar client and server has been connected to each other, they just can't send or receive any messages
Your code is missing some important peaces. For example the imports. They show us what libraries you used and give us chances to do some reserches.
1) For example the line:
myListener = new Timer(250, readLine);
It can't be java.util.Timer because this class doesn't have an constructor (long/int, ActionListener). Possibly this call only runs once instead of multiple times, but I'm unable to know and tell you that.
2) Another example: You have the line
acceptClient.start();
I can only assume that there is an instance variable
Accepter acceptClient = new Accepter();
but it can also refer to a completely different class which works differently.
3) Back to my first example:
You are doing some kind of polling. This is not good style in java because Java Thready are by design optimized for blocking threads. Use a code block like this instead (untested; inspired by your server code)
class ClientThread extends Thread{
#Override
public void run(){
try{
String tempReceiver;
while ((tempReceiver = socketIn.readLine()) != null) {
exStr(tempReceiver);
}
} catch (IOException e) {
System.out.println("Read failed");
}
}
}
In this case you don't need polling and you have immediate response. This consumes less CPU.
A completely different option would be to use Java NIO, which is more optimized for single-thread applications (or let's call it few-thread).
Some off-topic remarks:
OT 1)
Calling Swing-functions like JOptionPane.showMessageDialog() and setText() is dangerous from threads. Swing itself is not Thread-safe. You should use a EventQueue.invokeLater() wrapper around it. my favourite: SwingUtils.invokeLater()
OT 2)
Having the variable tempReceiver class-global (I assume this because I can't see any declaration) is also dangerous because you likely use it somewhere else and possibly exactly overwrite it during the readLine() and exStr() calls in the other thread (if Timer is the Swing-implementation, it runs an extra thread).
OT 3)
You are saying "the .jar client and server has been connected to each other". Does this mean you have two open console windows with a java -jar command running in each window? If not, you might miss some important console output (possibly exceptions).
The windows distribution of java has 2 java runners: javaw.exe which is called when double-clicking a .jar file in the Explorer. And java.exe which also runs your program but also opens a console window which shows the output of System.out.println etc. This console is very important for debugging. It shows the same output as the Debug window in NetBeans or Eclipse.
Solved
it was because i encrypt the message using some cipher algorithm
and i send the bytes as string
some ciphered character are unreadable by the console, and so the program can't do certain key operations to process the message
thanks all anyway :)
Related
We wanted to execute some commands on Windows Server 2008/Windows 7 using telnet. As everytime logining in and running commands on around 50 of the same is tedious so I searched in google and zeored to apache commons and I found an example.
It works but it is printing some junk characters (I'm thinking it is some issue with character encoding of Windows, I'm new to this).
package com.kiran.telnet;
import org.apache.commons.net.telnet.TelnetClient;
import java.io.InputStream;
import java.io.PrintStream;
public class AutomatedTelnetClient {
private TelnetClient telnet = new TelnetClient();
private InputStream in;
private PrintStream out;
private String prompt = ">";
public AutomatedTelnetClient(String server, String user, String password) {
try {
// Connect to the specified server
telnet.connect(server, 23);
// Get input and output stream references
in = telnet.getInputStream();
out = new PrintStream(telnet.getOutputStream(), true);
// Log the user on
readUntil("login: ");
write(user);
readUntil("password: ");
write(password);
// Advance to a prompt
readUntil(prompt + " ");
} catch (Exception e) {
e.printStackTrace();
}
}
public void su(String password) {
try {
write("su");
readUntil("Password: ");
write(password);
prompt = ">";
readUntil(prompt + " ");
} catch (Exception e) {
e.printStackTrace();
}
}
public String readUntil(String pattern) {
try {
char lastChar = pattern.charAt(pattern.length() - 1);
StringBuffer sb = new StringBuffer();
boolean found = false;
char ch = (char) in.read();
while (true) {
System.out.print(ch);
sb.append(ch);
if (ch == lastChar) {
if (sb.toString().endsWith(pattern)) {
return sb.toString();
}
}
ch = (char) in.read();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void write(String value) {
try {
out.println(value);
out.flush();
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
}
}
public String sendCommand(String command) {
try {
write(command);
return readUntil(prompt);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void disconnect() {
try {
telnet.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
AutomatedTelnetClient telnet = new AutomatedTelnetClient(
"127.0.0.1", "Kiran", "artha");
System.out.println("Got Connection...");
telnet.sendCommand("hostname");
//telnet.sendCommand("ipconfig");
//telnet.sendCommand("ps -ef ");
//System.out.println("run command");
//telnet.sendCommand("ls ");
//System.out.println("run command 2");
telnet.disconnect();
System.out.println("DONE");
} catch (Exception e) {
e.printStackTrace();
}
}
}
The Output while I run this is:
Welcome to Microsoft Telnet Service
login: Kiran
Kiran
password: artha
[1;1H*=============================================================== [2;1HMicrosoft Telnet Server. [3;1H*=============================================================== [4;1HC:\Users\Kiran> Got Connection...
hostname
[5;1H[K[6;1H[K[7;1H[K[8;1H[K[9;1H[K[10;1H[K[11;1H[K[12;1H[K[13;1H[K[14;1H[K[15;1H[K[16;1H[K[17;1H[K[18;1H[K[19;1H[K[20;1H[K[21;1H[K[22;1H[K[23;1H[K[24;1H[K[25;1H[K[4;16Hhostname[5;1HKiran-PC[7;1HC:\Users\Kiran>DONE
And some ESC char before "["
Any help regarding this one.
Thank You.
Take a look at this wiki article. This symbols are just control characters, used to format the output in your terminal.
You can try to configure your terminal type like:
TelnetClient telnet = new TelnetClient("dumb");
Or you can try to configure it with TerminalTypeOptionHandler.
By default your telnet client is created with terminal type vt100' which supports control sequences. The dumb one does not support them. But you have to understand, that it is not guaranteed, that remote server support this terminal type.
I've searched quite a bit for answers, but haven't found anything that really helps, and the threads I found were zombies.
My problem: I'm creating a UI for Bukkit servers, but for end-users to execute commands in the server, I have to write to the process using an OutputStreamWriter.
I have all the code, but the command isn't getting sent to the process.
So far, this is the code I'm using to execute the server and get all the streams:
#SuppressWarnings("null")
private void startServer() throws InterruptedException, IOException {
setTitleText("BukkitUI by Beatsleigher [Starting...]");
setStatusImg(ServerState.BOOTING);
Thread.sleep(1000);
setTitleText("BukkitUI by Beatsleigher [Loading components...]");
runServer = true;
process = new ProcessBuilder();
// Set attibutes
process.redirectErrorStream(true);
java.util.List<String> jvmArgs = new ArrayList<>(4);
jvmArgs.add(JVMManager.getJava().toString()); // If you don't know what this does, you should not consider yourself a programmer.
jvmArgs.add("-jar");
jvmArgs.add(JVMManager.getProcessedInitHeapSize()); // Add Java VM arg[0]
//jvmArgs.add(JVMManager.getProcessedMaxHeapSize()); // Add Java VM arg[1]
jvmArgs.add(PreferenceManager.getBukkitLocation().getAbsolutePath()); // Add Java VM arg[2]
jvmArgs.add("-o"); // Add CraftBukkit arg[0]
jvmArgs.add("true"); // Add CraftBukkit arg[1]
process.command(jvmArgs);
// Start process
pr = process.start();
setTitleText("BukkitUI by Beatsleigher [Running]");
consoleWriter = new BufferedWriter(new OutputStreamWriter(pr.getOutputStream()));
processServer();
}
private void processServer() throws IOException {
new Thread() {
#Override
public void run() {
try {
setStatusImg(ServerState.ONLINE);
jTextPane1.setText("");
consoleReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while ((consoleOutput = consoleReader.readLine()) != null && (runServer)) {
jTextPane1.setText(jTextPane1.getText() + "\n" + consoleOutput);
highlight();
}
jTextPane1.setText(jTextPane1.getText() + "\n[INFO] [BukkitUI] Server has Stopped!");
highlight();
stopServer();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
pr.destroy();
try {
consoleReader.close();
} catch (IOException ex1) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex1);
}
setStatusImg(ServerState.OFFLINE);
setTitleText("BukkitUI by Beatsleigher [ERROR! Server has stopped!]");
}
}
}.start();
}
The server starts and runs fine, I get all the process output I need, but, as mentioned before, any commands I send to the console using following code won't work.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String inputCmd = jTextField1.getText();
try {
if (inputCmd != null | !inputCmd.equals("")) {
if (inputCmd.startsWith("/")) {
String[] cmd = inputCmd.split("/");
consoleWriter.write(cmd[1]);
clearCmd();
return;
} else if (inputCmd.startsWith("cmd;")) {
String[] cmd = inputCmd.split("cmd;");
consoleWriter.write(cmd[1]);
clearCmd();
return;
}
if (inputCmd.startsWith("bcast;")) {
String[] msg = inputCmd.split("bcast;");
consoleWriter.write("broadcast " + msg[1]);
clearCmd();
return;
}
if (inputCmd.startsWith("appnd;")) {
String[] msg = inputCmd.split("appnd;");
jTextPane1.setText(jTextPane1.getText() + "\n[BUKKITUI] " + msg[1]);
clearCmd();
return;
}
if (inputCmd.equals("--h")) { showHelp(); clearCmd(); return; }
consoleWriter.write("say " + inputCmd);
clearCmd();
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
Any help with this matter is greatly appreciated.
I'm really confused by this: some of my code is not working when i run my program normally in eclipse, but it does wok when i run through each step separately using the debug mode.
Code:
public void showConnectDialog() {
ConnectDialog connectDialog = new ConnectDialog();
connectDialog.setVisible(true);
//Until here, code runs
while(! connectDialog.getConnected()) {};
//The next line does only run in debug
JOptionPane.showMessageDialog(connectDialog, "Connected", "Connected", JOptionPane.INFORMATION_MESSAGE);
}
The connector (is started (as a thread) as soon as the user hits 'connect' in the dialog):
private class ServerConnector implements ActionListener, Runnable {
#Override
public void actionPerformed(ActionEvent e) {
if (! IP_field.getText().equals("")) {
if (! isConnecting) {
new Thread(new ServerConnector(), "ServerConnector").start();
}
}
else {
JOptionPane.showMessageDialog(dialog,
"Enter an IP address",
"Enter IP",
JOptionPane.WARNING_MESSAGE);
}
}
#Override
public void run() {
try {
setConnecting(true);
Socket socket = connect();
if (socket != null) {
ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream oIn = new ObjectInputStream(socket.getInputStream());
if (login(oOut, oIn)) {
isConnected = true;
setConnecting(false);
}
else {
socket.close();
}
setConnecting(false);
}
}
catch (RSPException e) {
e.printStackTrace();
System.exit(1);
}
catch (Exception e) {
//If an exception occurs, setConnecting() will be true. This
//not good, so it has to be set to false
e.printStackTrace();
setConnecting(false);
}
}
private boolean login(ObjectOutputStream oOut, ObjectInputStream oIn)
throws ClassNotFoundException, IOException, RSPException {
//Send login request action:
oOut.writeObject(new LoginAction(ActionSender.CLIENT, getID(),
getPassword()));
Object obj = oIn.readObject();
if (obj instanceof LoginActionResult) {
LoginActionResult result = (LoginActionResult) obj;
if (result.getResult() == LoginResults.SUCCES) {
return true;
}
else if (result.getResult() == LoginResults.FAIL_ON_ID) {
JOptionPane.showMessageDialog(dialog,
"Invalid password or ID",
"Can't login",
JOptionPane.ERROR_MESSAGE);
return false;
}
else if (result.getResult() == LoginResults.FAIL_ON_PASSWORD) {
JOptionPane.showMessageDialog(dialog,
"Invalid password or ID",
"Can't login",
JOptionPane.ERROR_MESSAGE);
return false;
}
else if (result.getResult() == LoginResults.SERVER_FULL) {
JOptionPane.showMessageDialog(dialog,
"Couldn't connect: \n" +
"Server is full",
"Failed to connect",
JOptionPane.WARNING_MESSAGE);
return false;
}
else {
return false;
}
}
else {
System.out.println(obj);
throw new RSPException("Server is not following the protocol.");
}
}
private void setConnecting(boolean connecting) {
if (connecting) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
connectButton.setEnabled(false);
}
});
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
connectButton.setText("Connecting...");
}
});
}
else {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
connectButton.setText("Connect");
}
});
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
connectButton.setEnabled(true);
}
});
}
isConnecting = connecting;
}
private String getAddressFromTextField() {
return IP_field.getText();
}
private InetAddress getInetAddress(String fullAddress) {
try {
if (fullAddress.contains(":")) {
String[] splitAddress = fullAddress.split(":");
return InetAddress.getByName(splitAddress[0]);
}
else {
return InetAddress.getByName(fullAddress);
}
}
catch (UnknownHostException e) {
return null;
}
}
private int getPort(String fullAddress) {
try {
String[] splittedAddress = fullAddress.split(":");
return Integer.valueOf(splittedAddress[1]);
}
catch (NumberFormatException ex) {
return -1;
}
catch (NullPointerException
| ArrayIndexOutOfBoundsException
| PatternSyntaxException ex) {
//Returning default port value: 25566, because no port was given
return 25566;
}
}
#SuppressWarnings("resource")
private Socket connect() {
Socket socket = null;
InetAddress address = null;
if ((address = getInetAddress(getAddressFromTextField())) == null) {
return null;
}
int port = getPort(getAddressFromTextField());
try {
socket = new Socket(address, port);
}
catch (ConnectException e ) {
Socket retrySocket = null;
if ((retrySocket = retryConnect(address, port)) == null) {
JOptionPane.showMessageDialog(dialog,
"Connection timed out",
"Failed to connect",
JOptionPane.ERROR_MESSAGE);
setConnecting(false);
}
else {
socket = retrySocket;
}
}
catch(IOException e) {
e.printStackTrace();
}
return socket;
}
private Socket retryConnect(InetAddress address, int port) {
Thread waitThread = new Thread(new Runnable() {
#Override
public void run() {
try {
//Will wait 15(000) (milli)seconds before stopping with
//trying to connect.
//One second (1000 millis) is for debugging and testing
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
waitThread.start();
while (waitThread.isAlive()) {
try {
return new Socket(address, port);
}
catch (ConnectException e) {
//Do nothing, will re-attempt to connect.
}
catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private String getID() {
return ID_field.getText();
}
private String getPassword() {
if (getID().equals("master")) {
return "masterPassword";
}
else {
return new String(passwordField.getPassword());
}
}
}
getConnected() returns true as soon as it's connected to the server. The connector is running on a separate thread.
EDIT: I tried to put code in the getConnected() while block, and then it works. Why does it works then and not else?
I had the same Problem, but with some more specification. The code was working fine in 32bit but I had this issue in 64bit (I am using native library so I need to maintain both).
The solution I found is to add Thread.sleep() in the while loop. I don't know why it works, so your guess is as good as mine.
A better solution would probably to implement an Observer Pattern instead of having an infinite loop. But that would require some re-factoring.
Using Thread.sleep(), as the other answers have suggested, should solve the problem but it is not a very good approach. Instead, we should be using Thread.yield().
Why yield and not sleep?
Refer:
Difference between Thread.Sleep(0) and Thread.Yield() and Are Thread.sleep(0) and Thread.yield() statements equivalent?
Why this works?
When we just run the threads, the OS puts them to "idle" state and when it is expected to "wake-up", it does not. On the other hand, in debug mode, we have a controlled environment. The OS has little control over it as everything goes on step-by-step, slowly. If we run the debug a few times without any break-points, after a few successful runs, we should see the same effect.
I had a very similar problem with a "while" loop that wouldn't run and that loop was my main routine. How I got the loop to run was that the very first thing that was done in the loop was a sleep:
try
{Thread.sleep(0);}
catch (Exception e)
{e.printStackTrace();}
This was enough to get everything going.
I had same problem in UIAutomator with UiObject2 wait(Until.findObject(),20) .
Thread.yield() - works for me
I'm trying to enter some value in external application using Java.
Java application looks like this:
Runtime runtime = Runtime.getRuntime();
// ... str build ...
proc = runtime.exec(str);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
bw.write(value);
bw.flush();
bw.close();
if (proc.waitFor() != 0)
// error msg
// the end
Application hangs at waitFor method.
External application looks like this:
welcome banner
please enter 8 character input:
Welcome banner is printed using printf and input is taken with SetConsoleMode/ReadConsoleInput. ReadConsoleInput reads one char and they are masked with * character.
Help
you can use:
proc.getOutputStream().write("some date".getBytes())
keep in mind that you HAVE to read everything the app send to stdout and stderr, else it might get stuck writing there.
I use a generic class to read it in a different thread.
usage is like:
InputStreamSucker inSucker = new InputStreamSucker(proc.getInputStream());
InputStreamSucker errSucker = new InputStreamSucker(proc.getErrorStream());
proc.waitFor();
int exit = process.exitValue();
inSucker.join();
errSucker.join();
InputStreamSucker code is here:
public class InputStreamSucker extends Thread
{
static Logger logger = Logger.getLogger(InputStreamSucker.class);
private final BufferedInputStream m_in;
private final ByteArrayOutputStream m_out;
private final File m_outFile;
public InputStreamSucker(InputStream in) throws FileNotFoundException
{
this(in, null);
}
public InputStreamSucker(InputStream in, File outFile) throws FileNotFoundException
{
m_in = new BufferedInputStream(in, 4096);
m_outFile = outFile;
m_out = new ByteArrayOutputStream();
start();
}
#Override
public void run()
{
try
{
int c;
while ((c = m_in.read()) != -1)
{
m_out.write(c);
}
}
catch (IOException e)
{
logger.error("Error pumping stream", e);
}
finally
{
if (m_in != null)
{
try
{
m_in.close();
}
catch (IOException e)
{
}
}
try
{
m_out.close();
}
catch (IOException e)
{
logger.error("Error closing out stream", e);
}
if (m_outFile != null)
{
byte data[] = m_out.toByteArray();
if (data.length > 0)
{
FileOutputStream fo = null;
try
{
fo = new FileOutputStream(m_outFile);
fo.write(data);
}
catch (IOException e)
{
logger.error("Error writing " + m_outFile);
}
finally
{
try
{
if (fo != null) fo.close();
}
catch (IOException e)
{
logger.error("Error closing " + m_outFile);
}
}
}
}
}
}
public String getOutput()
{
return new String(m_out.toByteArray());
}
}
Got the answer! The trick is to use WriteConsoleInput() API because program expects keyboard event, not text ... That's why the waitFor() waited forever! :)
I have two applications, one is a server and the other is a client. At first, I run my server application. Then I will run the client application. When running the client application, a window will be shown to prompt for a username and password and if they were correct, another window will be shown. When I click on the “Sign In” button, nothing happens. What's wrong?
Main class in Server application:
public static void main(String[] args) {
System.out.println("Server is starting...");
ServerSocket server = null;
try {
server = new ServerSocket(5000);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Server is listening...");
while (true) {
try {
Socket socket = server.accept();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Client Connected...");
}
}
Client class which has a socket in it:
private static InformationClass info = new InformationClass();
private static Socket c;
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
/**
* #param args the command line arguments
*/
public static void runAClient() {
try {
c = new Socket("localhost", 5000);
} catch (UnknownHostException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void clienT(){
try {
BufferedReader read = new BufferedReader(new InputStreamReader(c.getInputStream()));
BufferedWriter write = new BufferedWriter(new OutputStreamWriter(c.getOutputStream()));
while (true) {
String string = reader.readLine();
write.write(string, 0, string.length());
write.newLine();
write.flush();
System.out.println(read.readLine());
}
} catch (Exception e) {
System.err.println(e);
}
}
public static boolean connected() {
boolean bool = false;
if (c.isConnected()) {
info.setSituation("Connected");
bool = true;
} else {
info.setSituation("disconnected");
bool = false;
}
return bool;
}
The main window in the client application, which I start after when I run the server application. A part of that is for the “Sign In” button.
private void submit() {
String id = idField.getText();
char[] pass1 = passField.getPassword();
String pass = new String(pass1);
if (id.equals("") || pass.equals("")) {
ErrorFrame frame = new ErrorFrame();
frame.setVisible(true);
} else {
boolean b = Manager.Test(id, pass);
if (b == true) {
Main.runAClient();
boolean boOl = Main.connected();
if(boOl==true){
this.setVisible(false);
ListFrame fRAme = new ListFrame(client);
fRAme.setVisible(true);
}
else{
JOptionPane.showConfirmDialog(this, "You couldn't connect successfully,please try again!","sign_In Problem",JOptionPane.ERROR_MESSAGE);
return;
}
} else {
JOptionPane.showConfirmDialog(this, "You have entered wrong datas,try it again");
return;
}
}
}
Have you tried stepping through your code using a debugger to work out precisely which line of code is not working correctly? Simply stating that "nothing happens" when you click on the sign-in button doesn't give us much to go on.
Are you sure your submit() method is called when you click 'Sign In' button?
Another thing, Main.RunAClient() never returns constantly asking user to enter a line in system console.