Java Socket PrintWriter Works Once Only? - java

Hello i am trying to make a chat that use sockets and when i am trying to send data to the client it sends it once but then its not receiving anything then i noticed that its printwriter messed up i tried other ways but it does the same it only works once even i tried to copy everything from a tutorial online it does the SAME! does not work like it should soo whats the problem here? the printwriter should be able to send data more than once. I am developing this in JavaFX.
This is the printwriter function code that execute on button press:
public void testfunction(ActionEvent event){
//new Thread(new ListenerThread()).start();
//play();
//ObservableList<String> list = FXCollections.observableArrayList("Hello, hello?");
//TabPaneTabSlavesSlavesList.setItems(list);
/*System.out.println("Pc index: " + connectedClients.get(0).getLocalAddress().getLocalHost().getHostAddress());
System.out.println("Pc index: " + connectedClients.get(0).getLocalAddress().getLocalHost().getCanonicalHostName());
System.out.println("Pc index: " + connectedClients.get(0).getLocalAddress().getLocalHost().getAddress());
System.out.println("Pc index: " + connectedClients.get(0).getLocalAddress().getLocalHost().getHostName());*/
// Neina gauti ip ar kanors tokio su sitom funkcijomis FIX: Paimti informatcija ir persiusti su stream.
try {
Random rand = new Random();
int myrand = rand.nextInt(50) +1;
PrintWriter pw = new PrintWriter(connectedClients.get(0).getOutputStream());
pw.println("PINGiamconnected: " + Integer.toString(myrand));
pw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
This is the listener code that is working on a thread:
#Override
public void run() {
// TODO Auto-generated method stub
try {
Socket clientSocket = MainController.serverSocket.accept();
MainController.connectedClients.add(clientSocket);
MainController.NewClientConnected = true;
} catch (Exception e) {
e.printStackTrace();
}
}
And here is the reader on the client that is also working on a thread:
#Override
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(MainController.socket.getInputStream()));
//DataInputStream in = new DataInputStream(MainController.socket.getInputStream());
String line = in.readLine();
System.out.println(line);
} catch (Exception e) {
e.printStackTrace();
}
}
I think thats all you guys need i think if you need something more tell me. Thanks.

I fixed it the problem was that the thread executed only 1 time and then stopped it did work all that time – GrimReaper

Related

Running python script from java and sending input/output

I am writing a java program that will need to run a python script.
The script will print output which will java need to read to know the progress of the script.
To be able to pause the script while running I want it to ask for input once in a while, only when java give it input the script will keep going.
Here is my Java method:
private static void sevenTry(String[] strCommands) throws IOException {
Object oLock1 = new Object();
Object oLock2 = new Object();
ProcessBuilder pBuilder = new ProcessBuilder(strCommands);
pBuilder.redirectErrorStream(true);
Process proc = pBuilder.start();
Thread tReader = new Thread() {
#Override
public void run() {
System.out.println("~~tReader starting~~");
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
synchronized (oLock1) {
try {
String line = reader.readLine();
while (line != null && !line.trim().equals("--EOF--")) {
System.out.println("Stdout: " + line);
if (line.trim().equals("--INPUT--")) {
synchronized (oLock2) {
oLock2.notify();
}
oLock1.wait();
}
line = reader.readLine();
}
} catch (IOException e) {
System.out.println("tReader: " + e.getMessage());
} catch (InterruptedException e) {
System.out.println("tReader: " + e.getMessage());
} catch (Exception e) {
System.out.println("tReader: " + e.getMessage());
}
}
System.out.println("~~tReader end~~");
synchronized (oLock2) {
oLock2.notify();
}
}
};
Thread tWriter = new Thread() {
#Override
public void run() {
System.out.println("~~tWriter starting~~");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
String line, input;
Scanner scan = new Scanner(System.in);
synchronized (oLock2) {
try {
oLock2.wait();
} catch (InterruptedException e1) {
System.out.println("tWriter: " + e1.getMessage());
}
}
while (tReader.isAlive()) {
synchronized (oLock1) {
System.out.println("Java: insert input");
scan.hasNext();
input = scan.nextLine();
try {
writer.write(input + "\n");
writer.flush();
} catch (IOException e) {
System.out.println("tWriter: " + e.getMessage());
}
oLock1.notify();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
System.out.println("tWriter: " + e1.getMessage());
}
}
System.out.println("~~tWriter end~~");
}
};
tReader.start();
tWriter.start();
System.out.println("~~everything submitted~~");
try {
tReader.join();
tWriter.join();
System.out.println("~~finish~~");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This is my python script:
# coding=utf-8
import sys
print '1'
print '--INPUT--'
inum = sys.stdin.readline()
print '2'
print '--EOF--'
I tried running my code
sevenTry("python", "C:\\Testing.py");
but on java side it get stuck inside tReader at line:
String line = reader.readLine();
The program does work if i take out the input line from the python file
inum = sys.stdin.readline()
Using
inum = raw_input()
still bring up the same problem (im using python 2.7)
The most confusing part here that i even tried to test this with a java file (instead of python)
sevenTry("java", "-classpath", "C:\\class", "CheckCMD");
and it worked even with the input lines
import java.util.Scanner;
public class CheckCMD {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String line;
System.out.println("1");
System.out.println("--INPUT--");
in.hasNext();
line = in.nextLine();
System.out.println("2");
System.out.println("--EOF--");
}
}
As you may have noticed, this is a problem related to Python.
As described in https://unix.stackexchange.com/questions/182537/write-python-stdout-to-file-immediately,
" when process STDOUT is redirected to something other than a terminal, then the output is buffered into some OS-specific-sized buffer (perhaps 4k or 8k in many cases)."
So, you need to call sys.stdout.flush() after each invoke to print.
Or, as a better option, you can change the default behaviour for the process, using the -u param, to get unbuffered output.

Multithreaded Client/Server application java issue

This is my first post, so correct me if I am doing something wrong.
I am trying to make a multithreaded client/server application. I have no problem making a basic 1 to 1 client/server application without threading, but I want every client to talk individually to the server and each client only to recieve the messages that belongs to the particular client in the console. This is where I can't make it work.
I have looked at some tutorials online and I tried to debug in Eclipse without any luck.
What I want the application to do:
If I run the server and 2 clients I want to be able to write a message on a client and make the server return the message and the message number without skipping a number.
Client 1 :
Message no: 0. You said: Hello!
Message no: 1. You said: Whats up!
Client 2 :
Message no: 0. You said: Hey Server!
Message no: 1. You said: What are you doing now?
It works with the first Client that I run and perfectly increment the messagenumber, but when I create the second one it freezes, so I guess my problem is either with the socket declaration or with the way I am threading. (Maybe a socket.close() is missing somewhere?)
I know there is some other flaws with the application, but keep in mind that it is just a school assignment for working with threads.
Thanks in advance if someone is willing to help. :)
Server Code:
public class Server extends Thread
{
DataInputStream in;
DataOutputStream out;
ServerSocket listener;
public Server() throws IOException
{
try
{
while (true)
{
listener = new ServerSocket(9090);
Socket socket = listener.accept();
System.out.println("Test");
ThreadServer ts = new ThreadServer(socket);
Thread t1 = new Thread(ts);
t1.start();
}
}
finally
{
listener.close();
}
}
public static void main(String[] args) throws IOException
{
new Server();
}
}
Client code:
public class Client extends JFrame
{
DataOutputStream dos;
BufferedReader input;
String answer = null;
String textString;
Socket s = new Socket("localhost", 9090);
public Client() throws IOException
{
JButton btn = new JButton("run");
final JTextField txf = new JTextField(10);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try
{
dos = new DataOutputStream(s.getOutputStream());
textString = txf.getText();
dos.writeUTF(textString);
dos.flush();
input = new BufferedReader(new InputStreamReader(s.getInputStream()));
answer = input.readLine();
}
catch (Exception e1)
{
e1.printStackTrace();
}
System.out.println(answer);
}
});
setLayout(new GridLayout(2,2));
add(btn);
add(txf);
setVisible(true);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) throws IOException
{
new Client();
}
}
ThreadServer code:
public class ThreadServer implements Runnable
{
DataInputStream in;
DataOutputStream out;
public ThreadServer (Socket socket) throws IOException
{
int i = 0;
try
{
while (true)
{
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
try
{
String message = in.readUTF();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Message no: " + i + ". You said: " + message);
out.println("Message no: " + i);
}
catch(Exception e)
{
e.printStackTrace();
}
i++;
}
}
finally
{
socket.close();
}
}
#Override
public void run() {
// TODO Auto-generated method stub
}
}
Let me try to solve it.
Create only one ServerSocket. Move below line from while loop. Put it before while loop.
listener = new ServerSocket(9090);
Move the code of ThreadServer's constructor to run() method because it implements Runnable but doesn't behave like a Runnable class.
public ThreadServer(Socket socket) throws IOException {
this.socket=socket;
}
#Override
public void run() {
...
//code from constructor
}
In Server class you are writing two lines to Client but client is reading just one. Remove extra line as shown below
out.println("Message no: " + i + ". You said: " + message);
//out.println("Message no: " + i);
One last suggestion:
Always check for inputs before calling readUTF() as shown below:
if (in.available() > 0) {
try {
String message = in.readUTF();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Message no: " + i + ". You said: " + message);
//out.println("Message no: " + i);
} catch (Exception e) {
e.printStackTrace();
}
i++;
}
Your ThreadServer is looping infinitely in the constructor, instead of the run method.
This is very bad. The run method is where you should put that code.
You should also follow the advice in the comment and move the socket creation.
-edit-
same is true for your ThreadServer, don't do the socket init in the loop. just the reading.
You might also discover later that you need an extra thread for the client. As it is now
it seems each client can only receive messages when the action performed button is clicked,
and that is probably not what you want. This will expose some synchronization problems
that you will have to deal with, but most you gui library might actually help you there.
It was a long time since I dealt with swing.
-edit again-
In addition, read up on exception handling. You should decide where you want
to catch the IO exceptions, rather than randomly nesting try/catch and declaring methods
as throwing them.

Interfacing Python and Java - Multithreaded Input and Output Streams

I have a Python app and a Java app running simultaneously.
I want Java to start the Python process and then communicate using the normal STDIN/STDOUT streams with Python.
I have started the process correctly and have two threads to handle the two I/O streams.
OUTPUT THREAD:
class output2 extends Thread {
Process process;
OutputStream stdin;
BufferedWriter writer;
Scanner in = new Scanner(System.in);
output2(Process p) {
try {
process = p;
stdin = process.getOutputStream();
writer = new BufferedWriter(new OutputStreamWriter(stdin));
} catch (Exception e) {
System.out.println("ERROR output2(): " + e);
}
}
#Override
public void run() {
System.out.println("Starting OUTPUT THREAD");
try {
while (true) {
String input = in.nextLine();
writer.write(input);
writer.flush();
}
} catch (Exception e) {
System.out.println("ERROR output2_run(): " + e);
}
System.out.println("Ending OUTPUT THREAD");
}
}
INPUT THREAD :
class input2 extends Thread {
Process process;
InputStream stdout;
BufferedReader reader;
input2(Process p) {
try {
process = p;
stdout = process.getInputStream();
reader = new BufferedReader(new InputStreamReader(stdout));
} catch (Exception e) {
System.out.println("ERROR input2(): " + e);
}
}
#Override
public void run() {
System.out.println("Started INPUT THREAD");
try {
while (true) {
System.out.println(Thread.currentThread().getName() + " is executing");
if (reader.readLine() != null) {
System.out.println("Stdout: " + reader.readLine());
}
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " stopped executing");
}
} catch (Exception e) {
System.out.println("ERROR input2_run(): " + e);
}
System.out.println("Ending INPUT THREAD");
}
}
MAIN :
public class My_Java {
public static void main(String args[]) {
File file = new File("C:\\Location\\");
try {
Process process = Runtime.getRuntime().exec("C:\\Python27\\python.exe chat_from_file.py", null, file);
input2 input = new input2(process);
output2 output = new output2(process);
input.setName("INPUT THREAD");
output.setName("OUTPUT THREAD");
input.start();
output.start();
} catch (Exception e) {
System.out.println("ERROR main(): " + e);
}
}
}
This doesn't seem to give any response at all.
It starts both threads, says INPUT THREAD is executing but nothing after that.
Where am I going wrong?
First of all, after calling if (reader.readLine() != null) { in your input class, you effectively have read the line and the next call will return null.
Use ready to check for non-blocking read possibility. Don't read upfront.
However, I'm pretty sure that you process exists abnormally, with something like python: can't open file 'chat_from_file.py': [Errno 2] No such file or directory or, throws a stacktrace and exits.
Use getErrorStream to check what the process is outputting if an error exists. This will put you on the correct path to solve your issue.
Also, just in case, make sure there's actually something to be read. Make sure your Python application is outputting enough data for buffers to be flushed (or flushing its writes).
And don't forget to join and exit cleanly and correctly. Good luck.

Java server program maxing out heap, burning CPU

I've got a little network game I'm making to learn networking in Java, and I'm in need of a little insight into what my program is having issues with. My server program maxes out the heap and burns 100% of the CPU. I'm sure I've got major newbie gotchas in the code, and I'm wondering if anyone would be so kind as to point them out to me, and perhaps detail why it is such a horrible practice.
Basically, the Server class's job is to wait in socket.accept() to deal with new clients. Each client from there gets its own ConnectionThread (which deals with input) and an attached OutputStream (which handles output). I know this may be wasteful for large applications, but with the server running along with just three clients (which are set to skip rendering and only send data through the socket every ~20ms for both input and output) it cooks the CPU and the server overflows the stack.
I've got a Packet class which converts the data into a string for sending, and the receiver decodes it back into a Packet. I suspect I have some Packets laying around too long, but I don't see where. If it isn't the packets, I'm fairly certain I have SOME sort of uncontrolled exponential object growth.
Here are some snippets of relevant code. I'm happy to provide more if the problem is elsewhere.
Just for reference, here is the full code: https://github.com/taylorrobert/ProjectM2O
Server:
public Server() {
network = new NetworkManager(this);
network.setConnectionCounter(0);
entityManager = new EntityManager(this);
setListenState(true);
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
System.out.println("Error in server constructor.");
System.exit(1);
}
}
public void listen() {
System.out.println("Current connectionCounter: " + network.getConnectionCounter());
while (shouldListen) {
ConnectionThread conn = null;
try {
conn = new ConnectionThread(serverSocket, this);
}
catch (Exception e) {
System.out.println("____Error constructing ConnectionThread. Could there be another instance of the server running?");
e.printStackTrace();
System.exit(1);
}
(new Thread(conn)).start();
System.out.println("Connection count: " + network.getConnectionCounter());
}
}
ConnectionThread:
public ConnectionThread(ServerSocket s, Server ser) {
resetTimer();
setActiveState(false);
server = ser;
//This UUID becomes the client's controllable player ID
//and the ID of this ConnectionThread.
connectionID = String.valueOf(UUID.randomUUID());
try {
socket = s.accept();
System.out.println("Socket ID " + connectionID + " established on: " + socket);
} catch (IOException e) {
System.out.println("Error in ConnectionThread. Is there a server already running on this port?");
}
init();
}
public void init() {
try {
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (IOException e) {
System.out.println("Error in intializing I/O streams.");
System.exit(1);
}
//Create the output thread
OutputStream outputHandler = new OutputStream(this);
new Thread(outputHandler).start();
//Get the client up to date on all relevant data
server.getEntityManager().addPlayerEntity(getConnectionID());
server.getNetwork().pushClientInitState(getConnectionID(), this);
server.getNetwork().addConnection(this);
server.getNetwork().notifyClientsAboutNewPlayer(getConnectionID());
int s = server.getNetwork().getConnections().size();
server.getNetwork().sendConsoleMessage("Players online: " + s, this);
}
public void run() {
setActiveState(true);
System.out.println("Running ConnectionThread...");
while (isActive()) {
//System.out.println("Entity size: " + server.getEntityManager().getEntities().size());
String op = readInputStream();
if (op.equals("")) continue;
Packet packet = Packet.populateNewPacketFromString(op);
try {
incomingOpQueue.put(packet);
} catch (InterruptedException e) {
System.out.println("Server failed to add packet to outgoing queue!");
}
//Take all packets off the incoming queue and execute them in order
while (incomingOpQueue.size() > 0) {
Packet p = incomingOpQueue.poll();
PacketExecutor.executePacket(server, p, this);
}
}
}
public String readInputStream() {
String msg = "";
try {
msg = in.readLine();
msg = msg.replace("\n", "");
msg = msg.trim();
} catch (IOException e) {
return "";
}
return msg;
}
OutputStream:
public void output() {
while (parentCT.isActive()) {
UnitTester.updateAllEntityLocationsToAllClients(parentCT, parentCT.server.getEntityManager().getEntities());
while (parentCT.getOutgoingOpQueue().size() > 0) {
String packet = (parentCT.getOutgoingOpQueue().poll().getString());
if (packet.equals("")) continue;
//System.out.println("Sending " + packet + " to " + parentCT.getConnectionID());
parentCT.getOutput().println(packet);
}
}
}
You probably need to make shouldListen volatile. Otherwise, there's every chance that its value will be cached, and setting it to false in some other thread will make no difference. You are setting it to false right, so that the main loop just doesn't make lots and lots of threads until it maxes out the heap and burns up the CPU?

how to read each string from the inputStream in java

I am trying to send accelerator values over bluetooth from an Android App to the PC. I am working on the BluetoothChat demo application. In the Android App I have a method called onSensorChanged that will be called every time when the accelerations changes. the method looks like below:
#Override
public void onSensorChanged(SensorEvent e) {
// the work done when the accelerometer data changes
try {
Thread.sleep(25);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
sensorX = e.values[0];
sensorY = e.values[1];
Toast.makeText(BluetoothChat.this, "x coordinate = " + sensorX + "y coordinate = " + sensorY Toast.LENGTH_SHORT).show();
BigDecimal sensorXDec = new BigDecimal(e.values[0]).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal sensorYDec = new BigDecimal(e.values[1]).setScale(2,BigDecimal.ROUND_HALF_UP);
String vals = String.valueOf(sensorXDec.toPlainString() + "," + sensorYDec.toPlainString());
mChatService.writeFromString(vals);
}
The method writeFromString
public void writeFromString(String temp){
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.writeString(temp);
}
and the writeString method is the following:
public void writeString(String out) {
try {
if(D) Log.d(TAG, "Sending File....AS STRING");
mmOutStream.write(out.getBytes(), 0, out.getBytes().length);
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
in the following method I process the inputStream on the PC side
#Override
public void run() {
try {
// prepare to receive data
InputStream inputStream = mConnection.openInputStream();
System.out.println("waiting for input");
while (true) {
int command = inputStream.read();
if (command == EXIT_CMD)
{
System.out.println("finish process");
break;
}
processCommand(command);
}
} catch (Exception e) {
e.printStackTrace();
}
}
The question again is: How can I retrieve each set of Strings I am sending from the Android App?
Try this
String msg = null;
BufferedReader br = new BufferedReader(
new InputStreamReader(inputStream)
);
msg = br.readLine();
This will solve problem
Scanner scanner = new Scanner (inputStream);
while(true){
if(!scanner.hasNextInt()){
continue;
}
// at this point we've got an int, so get it and use it
try{
int commmand = scanner.nextInt();
if (command == EXIT_CMD){
System.out.println("finish process");
break;
}
processCommand(command);
} catch (Exception catchThem){
// Deal with the caught exceptions
}
}
I didn't test this, hope it works for you.

Categories

Resources