I'm trying to send a string to the servlet from java program and retrieve the same string with some padding.
Here's the code i'm working on and the problem is java.io.EOFException is being thrown at the establishment of inputstream in java program.
why does the end of stream is occuring when i'm setting it up. please clarify my doubt.
Servlet program is
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ProgServlet implements Servlet {
public void init(ServletConfig sc){
}
public void service (ServletRequest req,ServletResponse res)
throws ServletException, java.io.IOException
{
}
public void destroy(){
}
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost");
//Setting up streams
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(response.getOutputStream());
String p = "Server String";
//Receiving data from client and resends by padding
try {
p = (String) ois.readObject();
p = p.concat(" -sever padding");
oos.writeObject(p);
oos.flush();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
}
}
}
java program on client is
public static void main(String arg[]) throws IOException{
System.out.println("Enter a string :");
Scanner s = new Scanner(System.in);
String data = s.next();
s.close();
URL serv = null;
try {
serv = new URL("http://10.0.0.9:8080/project/projectservlet");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpURLConnection servletConnection = null;
System.out.println("establishing communication with server....");
try {
servletConnection = (HttpURLConnection) serv.openConnection();
System.out.println("connection with the server established"+servletConnection.getRequestMethod());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
servletConnection.setRequestMethod("POST");
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(""+servletConnection.getRequestMethod());
servletConnection.setDoOutput(true);
servletConnection.setRequestProperty("Content-Type", "application/octet-stream");
System.out.println("setting up streams to communicate...");
ObjectOutputStream dos = null;
ObjectInputStream dis = null;
try {
dos = new ObjectOutputStream(servletConnection.getOutputStream());
System.out.println("Streams are up and ready to go");
System.out.println("Sending data to the server...");
dos.flush();
dos.writeObject(data);
dos.flush();
System.out.println("Data sent successfullyy \n Retrieving data from server");
dis = new ObjectInputStream(servletConnection.getInputStream());
data = (String) dis.readObject();
System.out.println("Data retrieved from the server is "+data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
dos.close();
dis.close();
servletConnection.disconnect();
}
}
the output and stack trace is
Enter a string :
jaggu
establishing communication with server....
connection with the server established
GET
POST
setting up streams to communicate...
Streams are up and ready to go
Sending data to the server...
Data sent successfully
Retrieving data from server
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at ServletInvokation.main(ServletInvokation.java:57)
Exception in thread "main" java.lang.NullPointerException
at ServletInvokation.main(ServletInvokation.java:69)
In the java client, the output stream represents the request sent to the server, and the input stream represents the response retrieved from the server. When you call servletConnection.getInputStream(), you are requesting the response from the server, so it immediately sends the HTTP request to the server. But if you look at your code, at that point you have not yet written anything to the output stream, so you are actually trying to send an empty request, and that's why you are getting an EOFException.
Try doing it in two steps instead. First, get the output stream, write to it and close it. Then get the input stream and read from it.
See also this answer.
Close OutPutStream in servlet after servlet work is completed.
Related
Imagine the next case:
Client - server connection
Client sends a request to the server
Server answers the Client
Client reads the answer
Class Client:
public class Client extends Service{
private String IP_ADDRESS;
private int PORT;
public void start(){
l.info("Starting client for server at: "+IP_ADDRESS+":"+PORT);
//Initialization of the client
try {
cs=new Socket(IP_ADDRESS,PORT);
} catch (UnknownHostException e) {
l.error("Unkown host at the specified address");
e.printStackTrace();
} catch (IOException e) {
l.error("I/O error starting the client socket");
e.printStackTrace();
}
}
//Sends the specified text by param
public void sendText(String text){
//Initializa the output client with the client socket data
try {
//DataOutputStream to send data to the server
toServer=new DataOutputStream(cs.getOutputStream());
l.info("Sending message to the server");
PrintWriter writer= new PrintWriter(toServer);
writer.println(text);
writer.flush();
} catch (IOException e) {
l.error("Bat initialization of the output client stream");
e.printStackTrace();
}
//Should show the answers from the server, i run this as a thread
public void showServerOutput(){
String message;
while(true){
//If there are new messages
try {
BufferedReader br= new BufferedReader(new InputStreamReader((cs.getInputStream())));
if((message=br.readLine())!=null){
//Show them
System.out.println(message);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
showServerOutput() is the method that returns any answer sent by the server
Then my server class have the following code
public class Server extends Service{
public void startListenner(){
l.info("Listening at port "+PORT);
while(true){
// Waits for a client connection
try {
cs=ss.accept();
l.info("Connection received: "+cs.getInetAddress()+":"+cs.getPort());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
toClient= new DataOutputStream(cs.getOutputStream());
PrintWriter cWriter= new PrintWriter(toClient);
//Send a confirmation message
cWriter.println("Message received");
//Catch the information sent by the client
csInput=new BufferedReader(new InputStreamReader(cs.getInputStream()));
printData();
toClient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
As you can see im sending a message to the client with the words: "Message received" but its never shown in the client console. Whats wrong?
EDIT
The printData() method prints the message received from the client in console
public void printData(){
l.info("Printing message received");
try {
System.out.println(csInput.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Not sure what your printData() method is doing, but aren't you missing a cWriter.flush() on the server side, once you printed "Message received" ?
As I understand it, you write your message but never send it to your client.
I try to send a message from server to a client, after client receives the message, it sends back a message to the server and so on. The problem is with receiving the message in python. The loop it's stuck there.
import socket
HOST = "localhost"
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
try:
s.bind((HOST, PORT))
except socket.error as err:
print('Bind failed. Error Code : ' .format(err))
s.listen(10)
print("Socket Listening")
conn, addr = s.accept()
while(True):
conn.send(bytes("Message"+"\r\n",'UTF-8'))
print("Message sent")
data = conn.recv(1024)
print(data.decode(encoding='UTF-8'))
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Main {
static Thread sent;
static Thread receive;
static Socket socket;
public static void main(String args[]){
try {
socket = new Socket("localhost",9999);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
sent = new Thread(new Runnable() {
#Override
public void run() {
try {
BufferedReader stdIn =new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while(true){
System.out.println("Trying to read...");
String in = stdIn.readLine();
System.out.println(in);
out.print("Try"+"\r\n");
System.out.println("Message sent");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
sent.start();
try {
sent.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The Python code is fine. The problem is that calling out.print in the Java code does not necessarily cause your message to be sent through the socket immediately. Add
out.flush();
immediately after
out.print("Try"+"\r\n");
to force the message to be sent through the socket. (flush "flushes" through the stream any data that has not yet been sent.) The Python should then be able to receive it correctly.
I'm making a Java program to make my computer a server to communicate with my smartphone over WiFi. Therefore I use the Socket class, as can be seen in the code below (based on Android-er):
package main;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerCommunication {
#SuppressWarnings("resource")
public static void main(String[] args){
ServerSocket serverSocket = null;
Socket clientSocket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
String message = null;
try {
int portNumber = 8888;
serverSocket = new ServerSocket(portNumber);
System.out.println("Listening :" + Integer.toString(portNumber));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true){
try {
clientSocket = serverSocket.accept();
dataInputStream = new DataInputStream(clientSocket.getInputStream());
dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("ip: " + clientSocket.getInetAddress());
System.out.println("message: " + dataInputStream.readUTF());
dataOutputStream.writeUTF("test");
message = dataInputStream.readUTF(); // <--- PROBLEM LINE
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if( clientSocket!= null){
try {
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if( dataInputStream!= null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if( dataOutputStream!= null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
Everything works perfectly when the problem line (indicated with <---) is not present in the file. The message I receive is properly printed in the console. But form the moment I want to store this message in a String, I get a java.io.EOFException...
Can anyone tell me why I can print a message, but not store it as a string?
Thanks in advance!
The exception java.io.EOFException says that all the data in the stream is read, looks like you are trying to consume the data twice, one in the following statement,
System.out.println("message: " + dataInputStream.readUTF());
and the next one in,
dataInputStream.readUTF()
Either write more data from the writing side (client side) or consume once. Hope it helps.
Once you call
dataInputStream.readUTF();
it pops the string and you print that one. Then in the second call since there are no more data in outputstream the End Of File exception occurs.
You may try storing the popped string to a variable and then printing it:
String message = dataInputStream.readUTF();
System.out.println("message: " + message);
Remove your problem line
message = dataInputStream.readUTF(); // <--- PROBLEM LINE
like the headline says I´m getting an EOFException on the serverside after i called shutdownOutput() at the clientside
this is at the serverside:
public void getRestaurant() {
String tempRestaurant=null;
try { BufferedReader fr =
new BufferedReader( new FileReader( "Restaurant.txt" ));
tempRestaurant = fr.readLine();
System.out.println( tempRestaurant );
System.out.println("writing tempRestaurant is the next Step");
oos.writeObject(tempRestaurant);
System.out.println("tempRestaurant has been written");
oos.close();
fr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
and this is the code at the clientside:
protected String doInBackground(Void... params) {
connecttoServer();
System.out.println("connecting to server...");
try {
oos.writeInt(1);
System.out.println("next step is closing");
serverside.shutdownOutput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
System.out.println("connected to server");
Restaurant=(String) ois.readObject();
System.out.println("doInBackground(): "+Restaurant);
and this is the error code:
java.io.EOFException
at java.io.DataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream.readInt(Unknown Source)
at prealphaserverpackage.clientsidethreads.handlerequest(Serverpart.java:355)
at prealphaserverpackage.clientsidethreads.run(Serverpart.java:156)
pls comment if you need any further informations i will put them online as soon as possible :)
I forgot to call oos.flush(); While the server was still waiting for the data, I closed the stream. That was the reason for the EOFException.
Im developing a client-server app. The client side is Java based, the server side is C++ in Windows.
Im trying to communicate them with Sockets, but im having some trouble.
I have succesfully communicated the client with a Java Server, to test if it was my client that was wrong, but its not, it seems like im not doing it right in the C++ version.
The java server goes like this:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args){
boolean again = true;
String mens;
ServerSocket serverSocket = null;
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
serverSocket = new ServerSocket(12321);
System.out.println("Listening :12321");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(again){
try {
System.out.println("Waiting connection...");
socket = serverSocket.accept();
System.out.println("Connected");
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
while (again){
mens = dataInputStream.readUTF();
System.out.println("MSG: " + mens);
if (mens.compareTo("Finish")==0){
again = false;
}
}
} catch (IOException e) {
System.out.println("End of connection");
//e.printStackTrace();
}
finally{
if( socket!= null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
if( dataInputStream!= null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if( dataOutputStream!= null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
System.out.println("End of program");
}
}
The client just makes a connection and sends some messages introduced by the user.
Could you please give me a similar working server but in C++ (in Windows)?
I can't make it work by myself.
Thanx.
Your problem is that you are sending a java string which could take 1 or 2 bytes per character (see bytes of a string in java?)
You will need to send and receive in ascii bytes to make things easier, imagine data is your data string on the client side:
byte[] dataBytes = data.getBytes(Charset.forName("ASCII"));
for (int lc=0;lc < dataBytes.length ; lc++)
{
os.writeByte(dataBytes[lc]);
}
byte responseByte = 0;
char response = 0;
responseByte = is.readByte();
response = (char)responseByte;
where is and os are the client side DataInputStream and DataOutputStream respectively.
You can also sniff your tcp traffic to see what's going on :)