I am trying to read a message from the server. following is the piece of code:
try{
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
stdIn = new BufferedReader(
new InputStreamReader(System.in));
J = new JChatComm(out , in,"client","server");
String userInput = "Free for a chat?";
JPacket p = new JPacket(userInput,"client");
out.writeObject(p);
p = (JPacket)in.readObject();
if (!p.message.equals("Sure. Let us begin.")){
System.out.println("Server seems to be unavailable.");
socket.close();
}
else{
System.out.println("Chat Initiated..");
}
}
catch(Exception e){
e.printStackTrace();
}
But it gives the following output:
java.io.EOFException
at
java.io.ObjectInp utStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2596)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1317)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at JClient.callServer(JClient.java:35)
at jtalkG24.main(jtalkG24.java:18)
Line 35 is the line which has the readObject() method.
I am unable to figure out where I am going wrong.
You aren't going wrong. You've reached the end of the stream. That's what the exception means. You have to catch it and react accordingly.
Related
This is the code I have
try
{
reader.read(msg1,0,6);
} catch (SocketTimeoutException e1){
loopcount = 1 ;
reader.close();
writer.close();
client.close();
reader = null;
writer = null;
client = null;
}
try
{
msg2 = new char[2000];
reader.read(msg2,0,intArrLen);
}catch (SocketTimeoutException e1){
loopcount = 1 ;
reader.close();
writer.close();
client.close();
reader = null;
writer = null;
client = null;
}
Inside the method, at this line reader. read (msg1,0,6) able to read the response correctly. After this when trying to read the response at the line reader. read (msg2,0,intArrLen).
It is giving stream is closed exception - Exception: java. I o. IO Exception: Stream closed. So need help in understanding why this exception is coming.
Firstly you are closing the connection of the reader and then without creating a new one calling the function using same reader which is close.
Instead, you can use reader.flush() method .
For more information please refer to the link.
I'm trying to develop client-server connection between phone and pc using sockets. During the developing i met a problem and cannnot fix it yet. The problem is with outputstream. I use an ObjectoutputStream to send a String array to client and it works when I use this code:
try
{
// отправка пакета с файлами
DataInputStream dir = new DataInputStream(conn.getInputStream());
OutputStream dos = conn.getOutputStream();
ObjectOutputStream objectOutput = new ObjectOutputStream(dos);
byte messageType = dir.readByte();
switch(messageType) {
case 1:
try {
textArea.append("\nClient sends a command: " + dir.readUTF());
objectOutput.writeObject(results);
objectOutput.close();
} catch(Exception e) {
e.printStackTrace();
}
}
dir.close();
} catch (IOException e) {
......
but when I move ObjectOutputStream to the switcher:
try
{
// отправка пакета с файлами
DataInputStream dir = new DataInputStream(conn.getInputStream());
OutputStream dos = conn.getOutputStream();
byte messageType = dir.readByte();
switch(messageType) {
case 1:
try {
ObjectOutputStream objectOutput = new ObjectOutputStream(dos);
textArea.append("\nClient sends a command: " + dir.readUTF());
objectOutput.writeObject(results);
objectOutput.close();
} catch(Exception e) {
e.printStackTrace();
}
}
dir.close();
} catch (IOException e) {
....
my program freezes. I need to do like this, because i also need to do another commands, like sending and receiving files. Any solutions for this problem?
I've solved a problem. I just use BufferedReader & Writer for it, because it will be also used for transferring files.
So now code works fine and looks like this:
// отправка пакета с файлами
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), ENCODING));
String messageType = br.readLine();
switch(messageType) {
case "connect": {
List<String> results = new ArrayList<String>();
File[] files = new File("C:/Tenzor_Denis/ServerFiles/").listFiles();
//If this pathname does not denote a directory, then listFiles() returns null.
for (File file : files) {
if (file.toString().endsWith(".txt")) {
results.add(file.getName());
}
}
try {
for(int i = 0; i < results.size(); i++) {
bw.write(results.get(i));
bw.newLine();
//textArea.append(" " + results.get(i));
}
textArea.append("\nClient sends a command: " + messageType);
} catch(Exception e) {
e.printStackTrace();
}
bw.close();
br.close();
}
break;
}
}
Thx to all for answers.
Which line does it freeze on? It seems like reading from the input stream causes the output stream to block until everything is consumed. Look at the documentation for your conn object. What class is this? Perhaps moving the dir.readUTF() call before creating the ObjectOutputStream might solve it.
You can't do it either way. Closing the ObjectOutputStream will close the socket. You need to keep it open for the life of the socket. So moving it inside the case is futile anyway.
But your code doesn't make sense. You're writing with ObjectOutputStream, yet all you're reading from the peer is a single byte. If you're writing objects, you need to read objects, with an ObjectInputStream, not a DataInputStream, and when using both object input and output streams you must always construct the ObjectOutputStream first, at both ends to be safe.
I am currently learning Java, and I tried to make a simple chat program, which communicates between a server and a client. My problem is that the two programs connect properly to each other, but send messages do not get print out. I do not know whether it is the sending or receiving part. Do not judge my class naming, it is just temporarily.
The client-side part of receiving:
InputStream is = chatterSock.getInputStream();
OutputStream os = chatterSock.getOutputStream();
Thread readThread = new Thread(() -> {
while (true) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
chatter.print("<p>" + out.toString() + "</p>");
} catch (IOException ex) {
chatter.printWarning("Connection lost");
}
}
The server-side part is pretty similar.
To send messages I just run
<Socket>.getOutputStream().write(<String>.getBytes());
I already tried some other posts from stackoverflow, but did not find a way that works. Thanks for your help!
Edit: here is the server side:
InputStream is = chatterSock.getInputStream();
OutputStream os = chatterSock.getOutputStream();
Thread readThread = new Thread(() -> {
while (true) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
overlord.print("<p>" + out.toString() + "</p>");
} catch (IOException ex) {
overlord.chatterSockList.remove(overlord.chatterSockList.indexOf(chatterSock));
overlord.printWarning("Connection to " + chatterSock.getInetAddress() + " lost");
overlord.sendToAll(("User " + username + " disconnected."));
}
}
});
Edit: The message gets send here:
sendButton.addActionListener(e -> {
try {
chatterSock.getOutputStream().write((messageArea.getText()+"\n").getBytes());
messageArea.setText("");
} catch (IOException ex) {
System.err.println(ex);
printWarning("Connection lost"); //TODO heartbeat
}
});
As #Russell Uhl mentions in his comment, a read loop whose termination condition is reader.readLine()) != null is only going to terminate when the output stream is closed.
If the output stream is not closed, that call simply waits for new information, and shall continue to do so indefinitely.
It is also going to wait indefinitely if you don't send over a newline, which is why you were told to add it to your write command.
It would be best to process each line you read separately, rather than trying to append them to a buffer and output them all together. Do the processing inside the loop.
And probably it's also a good idea to add some button to your GUI to terminate the chat. It will disable the rest of the GUI and close the output stream, which in turn will cause the readLine() to return null, and the loop to terminate properly.
I'm creating server and client java applications. I would like to create an array to store my sockets in. I'm using eclipse, and when I type in this line:
Socket[] sockets = new Socket[3];
Eclipse gives me an error saying "The resource type Socket[] does not implement java.lang.AutoCloseable".
How can I fix this?
Thank you
Try/Catch Statement:
try (
Socket[] sockets = new Socket[3]; //Line giving me error
ServerSocket serverSocket =
new ServerSocket(Integer.parseInt(ip));
Socket clientSocket = serverSocket.accept();
ServerClient client = new ServerClient(clientSocket);
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
//User input
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in))
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
out.println(inputLine);
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ port + " or listening for a connection");
System.out.println(e.getMessage());
continue;
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
While Socket class itself implements AutoCloseable interface, array of Sockets - does not.
To put it in simple terms: you cannot open or close an array.
The resources defined in a try-with-resources block must all be auto-closeable. That's what it's for. Socket[] is not AutoCloseable, so it cannot be defined there. Move the declaration before the try. Ditto for any other resources you get the error on. Don't treat it as a general declaration block. It isn't.
When I run your code I recevie this error message
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - incompatible types: try-with-resources not applicable to variable type
(java.net.Socket[] cannot be converted to java.lang.AutoCloseable)
I advice you not to use try catch block with resources when you want to define your socket array.
try (
your rest of code
) {
define your array here ---> Socket[] sockets = new Socket[3];
String inputLine;
while ((inputLine = in.readLine()) != null) {
out.println(inputLine);
}
} catch (IOException e) {
your rest of code
Note: Socket class implements Closeable and AutoCloseable , yet array cannot be defined in try block like you tried to do
You can outsmart this problem easily, just create a class containing a socket connection, then build an array of this class object.
Build the class:
Class example
{
Socket con;
The constructor and extra code here
...
}
Then just build the array:
example[] arr=new example[3];
I've connected to an already existent server that contains lines of strings I need to read in. Given that I only need to read in a String type, which input reader would work here so I could read line by line in my While loop? Here's my simple Client:
public class Client
{
public static final int PORT_NUMBER = 8888;
public static void main(String[] args)
{
int port = PORT_NUMBER;
String content;
OutputStream output;
InputStream input;
Socket s = null;
try
{
s = new Socket("server.example.exp", port);
output = s.getOutputStream();
input = s.getInputStream();
System.out.println("Connected to " + s.getInetAddress() + " on port " + s.getPort());
}
catch (IOException e) {System.err.println(e);}
while (true)
{
try
{
//read next line from server
}
catch (EOFException eof){
System.out.println("eof encountered" + eof.getMessage());
break;
}
catch (OptionalDataException ode){System.out.println("OptionalDataException" + ode.getMessage());}
catch (IOException ioe){System.out.println("IOException on read object");}
catch (ClassNotFoundException cnf){System.out.println("ClassNotFoundException");}
}
}
}
I know it's a very basic question, I'm just having trouble getting started, is all. I appreciate any clarification. Thanks.
To read from an InputStream, you can wrap it in a InputStreamReader, and then a BufferedReader, from which you can readLine:
BufferedReader input;
input = new BufferedReader(new InputStreamReader(s.getInputStream()));
Then:
while(true){
try{
input.readLine();//Read from server
}
Add the folloWing line before your while
BufferedReader inp2 = new BufferedReader(new InputStreamReader(inp));
while (true) {
try {
inp2.readLine();
}
}