the following is giving me a "code unreachable" message on 'out.close();'
I can't find the issue as it is more or less identical to other code I have run which worked!
import java.io.*;
import java.net.*;
public class MyClient {
private static String SERVER = "127.0.0.1";
private static Integer PORT = 8765;
public static void main(String[] args) throws IOException {
// Connect to the server and create the writer and reader
Socket socket = new Socket(SERVER,PORT);
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Loop forever
while(true) {
out.println("Question:");
String sum = System.console().readLine();
out.println(sum);
String line = in.readLine().trim();
if(line==null || line.startsWith("Finished")) {
socket.close();
return;
}
else if (line.startsWith("My answer is: ")){
System.out.println(line);
String message = System.console().readLine();//correct or wrong!!
out.println(message);
}
}
// Close the in and out and socket
out.close();
in.close();
socket.close();
}
}
You are doing a return from within the while loop. You should do break instead.
Because the code never gets to :
// Close the in and out and socket
out.close();
in.close();
socket.close();
Change return to break:
if(line==null || line.startsWith("Finished")) {
socket.close();
break; //<------------------CHANGE
}
Here's the problem
// Loop forever
while(true) {
It'll loop forever, you never stop it so the next line after the loop will never be executed. That's it :P
Because you have an infinite loop (while(true)) with no break or other means of exit.
It is not a good style to do a return inside a loop, but if want to be sure to free resources you can wrap your loop with a try ... finally:
try {
while(true) {
// ...
if(condition) {
return;
}
// ...
}
} finally {
out.close(); // this is called just before leaving the surrounding function
// ...
}
This works even if there is an exception thrown inside the loop.
Related
I am attempting stream data over a socket with Java in an attempt to write a Kafka producer. I've written a class to pull the data in but I'm not getting the results I'd expect. I've got it set up so the data is being streamed from a Linux box. The source of the data is a csv file that I'm using the nc utility to stream. The class is running on a Windows 10 machine from Eclipse. When I run the class I see two weird things.
The column headers don't get transmitted.
I can only run the class once. If I want to run it again, I have to stop nc and restart it.
Below is my code. Am I missing anything? At this point I'm just trying to connect to the socket and pull the data over.
I run nc with the following command:
$ nc -kl 9999 < uber_data.csv
Below is my class
import java.net.*;
import java.io.*;
public class Client
{
static String userInput;
public static void main(String [] args)
{
try
{
InetAddress serverAddress = InetAddress.getByName("servername");
Socket socket = new Socket(serverAddress, 9999);
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((userInput = input.readLine()) != null) {
System.out.println(input.readLine());
}
input.close();
socket.close();
}
catch(UnknownHostException e1)
{
System.out.println("Unknown host exception " + e1.toString());
}
catch(IOException e2)
{
System.out.println("IOException " + e2.toString());
}
catch(IllegalArgumentException e3)
{
System.out.println("Illegal Argument Exception " + e3.toString());
}
catch(Exception e4)
{
System.out.println("Other exceptions " + e4.toString());
}
}
}
You're throwing away every odd-numbered line. It should be:
while ((userInput = input.readLine()) != null) {
System.out.println(userInput);
}
Secondly, you aren't closing the socket. Use a try-with-resources:
try
{
InetAddress serverAddress = InetAddress.getByName("servername");
try (
Socket socket = new Socket(serverAddress, 9999);
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
while ((userInput = input.readLine()) != null) {
System.out.println(input.readLine());
}
}
}
catch (...)
First, each call readLine() tries to read line from input stream.
In userInput = input.readLine() you read header, but println(input.readLine()) read body and print in console.
while ((userInput = input.readLine()) != null) {
System.out.println(userInput); //instead input.readLine()
}
Second, I didn't use nc, but I think problem will solve if you will close socket (and reader) in finally statement.
I hope it would be helpful.
For the first question: you were trying to print userInput string. But it's printing the result of another readline() call.
For the second: after the file has been transferred, you have to stop and restart nc; no matter what you do from your side. It's from nc side.
See the nc documentation.
I'm having a little trouble with a simple Java server, client application.
Basically the topics says it all: when I do a writeUTF on the server side it only sends every 2nd time it's being executed.
For an example:
Server:
public class Server {
/**
* #param args
*/
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(7777);
Socket client = server.accept();
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
DataInputStream in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
while(true) {
for(int i = 0; i < 100; i++) {
out.writeUTF("Test" + i);
out.flush();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And client:
public class Client {
/**
* #param args
*/
public static void main(String[] args) {
try {
Socket client = new Socket("localhost", 7777);
DataInputStream in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
while(in.readUTF() != null) {
System.out.println(in.readUTF());
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And the output in the console looks like this:
Test1
Test3
Test5
Test7
Test9
Test11
What is causing this behavior?
It's because you're discarding data on your client.
When you check while(in.readUTF() != null), you're reading an entry from the stream every time to see if it's non-null. Then you discard this value, and read a new one within the loop. (As well as losing values, this has the bug that with an odd number of total values, the while condition will evaluate to true but the next call to readUTF() would return null within the loop.)
To fix this, you should read the value to a variable, and test this before using it - something like the following:
String value;
while((value = in.readUTF()) != null) {
System.out.println(value);
}
If you don't like the assignment and nullity check as a single expression, you can instead assign value = in.readUTF() initially and at the end of every loop, but personally I find this more error-prone.
This loop
while(in.readUTF() != null) {
System.out.println(in.readUTF());
}
throws away every second string it reads. You read one string while testing for end of file, discard it, then read another one and print it.
You are consuming the data in the while loop evaluation here:
while(in.readUTF() != null) {
System.out.println(in.readUTF());
}
Try this instead:
String line;
while( ((line = in.readUTF()) != null) {
System.out.println(line);
}
If you want your socket in UTF-8
you only need to add "UTF-8" in BufferedWriter and BufferedReader's contstructor
here is the sample
this.basicReader = this.Client.getInputStream();
this.basicWriter = this.Client.getOutputStream();
this.Reader= new BufferedReader(new InputStreamReader(basicReader,"UTF-8"));
this.Writer= new BufferedWriter(new OutputStreamWriter(basicWriter,"UTF-8"));
how to send data
this.Writer.write("data"+"\r\n");
this.Writer.flush();
and your main problem is your client didnt respond a msg when your client receive a msg
server to client
client to server
server to client
like this, try it.
I have a function that reads from the console using readPassword(). This function is called several times in one program iteration. However, I keep getting a java io exception once it gets to the readPassword() line. I noticed when i removed the close() statement from the finally-clause this error disappears. Why does this happen and when should I properly close the reader?
public void Func()
{
Console console = System.console();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
if (console == null)
System.out.println("Error!");
try
{
char[] pwd = console.readPassword();
String password = new String(pwd);
System.out.println("PW: " + password);
String input = reader.readLine();
System.out.println("UserNm: " + input);
} catch (IOException e) {
System.out.println("IO EXCEPTION");
} finally {
if (reader != null)
{
try
{
reader.close();
}
catch (IOException e)
{
System.out.println("error");
}
}
}
return null;
}
Thanks in advance for the help!
There's only one console, and there's only one System.in. If you close it, then you can't read from it anymore! You don't need to close that BufferedReader, nor should you. That whole finally block can and should just go away.
On closer reading, I don't even see why you're creating the BufferedReader in the first place -- it seems to have no function. Just delete all the code that deals with it!
You don't need any reader here, just use the Console instance.
public String Func() {
Console console = System.console();
if (console == null)
throw new IllegalStateException("No console available");
try {
String username = console.readLine("Username: ");
String pwd = new String(console.readPassword("Password: "));
return pwd;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Edited with your question edit. Just use the Console class, it can read/write, you don't need any reader/writer.
Use something like java.util.Scanner instead and as other people say don't worry about ever trying to close system.in.
So much cleaner:
Scanner in = new Scanner(System.in);
String password = in.nextLine();
String username = in.nextLine();
No tidy up/exception handling required.
You should not close your Console. Keep it open until your program does no longer need to read from it.
I have 2 sockets and I am using BufferedReader around it's InputStreams. What I am trying to do is take all input from the first socket and send it to the other socket (and visa versa).
The problem is that if the first one does not send a message, it will still block on the first readLine() even though the 2nd socket has already sent some data and is ready. I would like to continue with this simple approach of using no additional threads.
Here's some code that I wrote up, as you can see I have 2 BufferedReaders (in0 and in1) , the program gets stuck at in0.readLine() (blocking).
private void network()
{
PrintWriter out0 = null, out1 = null;
BufferedReader in0 = null,in1 = null;
try{
//clients[] is an array of Socket[2]
in0 = new BufferedReader(new InputStreamReader(clients[0].getInputStream()));
out0 = new PrintWriter(clients[0].getOutputStream(), true);
in1 = new BufferedReader(new InputStreamReader(clients[1].getInputStream()));
out1 = new PrintWriter(clients[1].getOutputStream(), true);
} catch (IOException e) {
System.out.println("Accept failed: 4445");
System.exit(-1);
}
int count = 1;
while(true)
{
System.out.println("network check loop # " + count);
++count;
String nextMessage = null;
try {
if( (nextMessage = in0.readLine()) != null)
{
this.relayMessage(nextMessage,out1);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Middle of network check loop");
nextMessage = null;
try {
if((nextMessage = in1.readLine()) != null)
{
this.relayMessage(nextMessage,out0);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
How can I just skip that statement if in0 is not ready to give me some data? I have seen BufferedReader's ready() method and have attempted to use in0.ready() && readLine() but this causes an infinite loop as neither of the bufferedreaders appear to ever be 'ready'. As well, I am certain that the messages being sent over the socket end in newline characters so readLine() should process correctly!
Any ideas?
Try to use setSoTimeout to put a timeout on your read(), then you just need to catch the SocketTimeoutException if the timer has expired.
Here break and continue keywords are your friends.
The simplest approach is to use two threads. This way you don't have to write your own scheduling code to determine which thread should be running. BTW: The code to copy from one socket to another is the same in each thread, reducing duplication.
To manage your threads I would use an ExecutorService which will make shutting downt eh threads easier.
I got a socket listener which keep listening for data. The problem now is that the client which send data will finally close the connection by itself. Based on my codes below I am wondering do I still need to perform this part of the codes where it does writeBuffer.close();?
Should I remove the final part and just put the socket closing the catch?
public void run()
{
BufferedWriter writeBuffer = null;
BufferedReader readBuffer = null;
String message="";
try {
writeBuffer = new BufferedWriter(new OutputStreamWriter(receivedSocketConn1.getOutputStream()));
readBuffer = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream()));
int m = 0, count=0;
int nextChar=0;
while ((nextChar=readBuffer.read()) != -1)
{
message += (char) nextChar;
if (nextChar == '#')
{
System.out.println("\n\nSending PA : "+message);
writeBuffer.write("$PA\r\n");
writeBuffer.flush();
message="";
}
}
}
catch (Exception ex)
{
System.out.println("MyError:Exception has been caught in in the main first try");
ex.printStackTrace(System.out);
}
/*finally
{
try
{
if ( writeBuffer != null )
{
writeBuffer.close();
}
else
{
System.out.println("MyError:writeBuffer is null in finally close");
}
}
catch(IOException ex)
{
ex.printStackTrace(System.out);
}
}*/
}
It's always a good idea to explicitly close the connections you're using. Think about it, it might be possible that the client never closes the connection (of course, then you'd have to implement some kind of timeout mechanism that closes the connection on the server side after a certain amount of time, but that's a different matter).
My point is - it never hurts to be careful, and manage your resources in a conservative fashion.