java [deprecation] readLine() in DataInputStream has been deprecated? - java

I wrote a java sever socket,it could connect postgresql and return values,but when I compile javac -deprecation SQLServer.java
And why warning cannot work?
It didn't have any error.How can I fix it?
SQLServer.java:66: warning: [deprecation] readLine() in DataInputStream has been deprecated
query = in.readLine();
^
1 warning
code:
import java.io.*;
import java.net.*;
import java.util.*;
import java.sql.*;
public class SQLServer extends Thread{
public static final int MYPORT = 6700;
ServerSocket listen_socket;
public SQLServer(){
try{
listen_socket = new ServerSocket (MYPORT);
}
catch(IOException e) {System.err.println(e);}
this.start();
}
public void run(){
try{
while(true)
{
Socket client_socket = listen_socket.accept();
SQLConnection c = new SQLConnection (client_socket);
}
}
catch(IOException e) {System.err.println(e);}
}
public static void main(String[] argv){
new SQLServer();
}
}
class SQLConnection extends Thread{
protected Socket client;
protected DataInputStream in;
protected PrintStream out;
protected String query;
public SQLConnection (Socket client_socket){
client = client_socket;
try{
in = new DataInputStream(client.getInputStream());
out = new PrintStream (client.getOutputStream());
}
catch(IOException e) {
System.err.println(e);
try {client.close();}
catch (IOException e2) {};
return;
}
this.start();
}
public void run(){
try{
query = in.readLine();
System.out.println("read query string <" + query + ">");
do_sql();
//out.println(d.toString());
}
catch (IOException e) {}
finally{
try {client.close();}
catch (IOException e) {};
}
}
public void do_sql(){
Connection con; // database connection object
Statement stmt; // SQL statement object
ResultSet rs; // SQL query results
ResultSetMetaData rsmd;
boolean more; // "more rows found" switch
String dsn = "jdbc:postgresql://localhost/postgres";
String user = "postgres";
String password = "123456";
String record;
int colcount, i;
try{
Class.forName ("org.postgresql.Driver");
con = DriverManager.getConnection(dsn, user, password);
stmt = con.createStatement();
rs = stmt.executeQuery(query);
more = rs.next();
if (!more) {
out.println("No rows found.");
return;
}
rsmd = rs.getMetaData();
colcount = rsmd.getColumnCount();
System.out.println(colcount + " columns in result set");
while (more) {
//build result string
record = "";
for (i=1; i <= colcount; i++){
record = record.concat(rs.getString(i) + " ");
}
out.println(record);
System.out.println(record);
more = rs.next();
}
rs.close();
stmt.close();
con.commit();
con.close();
}
catch (Exception e)
{
System.out.println("Exception occurred" + e.toString());
}
}
}

From DataInputStream#readLine javadoc:
Deprecated. This method does not properly convert bytes to characters. As of JDK 1.1, the preferred way to read lines of text is via the BufferedReader.readLine() method. Programs that use the DataInputStream class to read lines can be converted to use the BufferedReader class by replacing code of the form:
DataInputStream d = new DataInputStream(in);
with:
BufferedReader d = new BufferedReader(new InputStreamReader(in));

The method was deprecated because Streams are meant to be treating bytes, to treat text we have since a long time Readers & Writers as they offer the functionality to use encodings.
if you want text to be read try wrapping your stream into a reader
BufferedReader r = new BufferedReader(new InputStreamreader(your data stream, optional encoding parameter like "UTF-8"))
r.readLine();

This is what the Java API says:
Deprecated.
This method does not properly convert bytes to characters. As of JDK 1.1, the preferred way to read lines of text is via the BufferedReader.readLine() method. Programs that use the DataInputStream class to read lines can be converted to use the BufferedReader class by replacing code of the form:
DataInputStream d = new DataInputStream(in);
with:
BufferedReader d
= new BufferedReader(new InputStreamReader(in));

Related

Java Socket Read Input Twice

I have a situation with a Java Socket Input reader.
I am trying to develop an URCAP for Universal Robots and for this I need to use JAVA.
The situation is as follow:
I connect to the Dashboard server through a socket on IP 127.0.0.1, and port 29999.
After that the server send me a message "Connected: Universal Robots Dashboard Server".
The next step I send the command "play".
Here starts the problem. If I leave it like this everything works.
If I want to read the reply from the server which is "Starting program" then everything is blocked.
I have tried the following:
-read straight from the input stream-no solution
-read from an buffered reader- no solution
-read into an byte array with an while loop-no solution
I have tried all of the solution presented here and again no solution for my case.
I have tried even copying some code from the Socket Test application and again no solution.
This is strange because as mentioned the Socket Test app is working with no issues.
Below is the link from the URCAP documentation:
https://www.universal-robots.com/articles/ur/dashboard-server-cb-series-port-29999/
I do not see any reason to post all the trials code because I have tried everything.
Below is the last variant of code maybe someone has an idea where I try to read from 2 different buffered readers. The numbers 1,2,3 are there just so I can see in the terminal where the code blocks.
In conclusion the question is: How I can read from a JAVA socket 2 times?
Thank you in advance!
public void sendPlay() {
try {
// Create a new Socket Client
Socket sc = new Socket("127.0.0.1", 29999);
if (sc.isConnected()) {
InputStream is = sc.getInputStream();
BufferedInputStream in = new BufferedInputStream(is);
String data = "";
int s = in.read();
data += ""+(char)s;
int len = in.available();
System.out.println("Len got : "+len);
if(len > 0) {
byte[] byteData = new byte[len];
in.read(byteData);
data += new String(byteData);
}
System.out.println(data);
System.out.println("1");
// Create stream for data
DataOutputStream out;
out = new DataOutputStream(sc.getOutputStream());
String command = new String();
command = "play"+"\n";
// Send command
out.write(command.getBytes("US-ASCII"));
out.flush();
System.out.println("2");
InputStream is1 = sc.getInputStream();
BufferedInputStream in1 = new BufferedInputStream(is1);
String data1 = "";
int s1 = in1.read();
data1 += ""+(char)s1;
int len1 = in1.available();
System.out.println("Len got : "+len1);
if(len1 > 0) {
byte[] byteData1 = new byte[len1];
in.read(byteData1);
data1 += new String(byteData1);
}
System.out.println(data1);
System.out.println("3");
// Perform housekeeping
out.close();
sc.close();
}
sc.close();
} catch (IOException e) {
System.out.println(e);
}
}
The problem seems to be that you are opening several input streams to the same socket for reading commands.
You should open one InputStream for reading, one OutputStream for writing, and keep them both open till the end of the connection to your robot.
Then you can wrap those streams into helper classes for your text-line based protocol like Scanner and PrintWriter.
Sample program to put you on track (can't test with your hardware so it might need little tweaks to work):
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class RobotTester implements AutoCloseable {
private Socket clientSocket;
private Scanner inputReader;
private PrintWriter outWriter;
private int incounter;
private int outcounter;
public static void main(String[] args) {
System.out.println("Program started. Connecting to robot");
try (RobotTester robot = new RobotTester("127.0.0.1", 29999)) {
System.out.println("Connected to robot.");
robot.nextInput(); //Read and print robot's welcome message
robot.writeCommand("play"); //Send command
String resp = robot.nextInput(); //Read result
if (resp.toLowerCase().startsWith("fail")) {
throw new Exception("Play command failed: " + resp);
}
System.out.println("Command succeeded!");
} catch (Throwable t) {
t.printStackTrace();
}
}
public RobotTester(String host, int port) throws UnknownHostException, IOException {
clientSocket = new Socket(host, port);
inputReader = new Scanner(clientSocket.getInputStream());
outWriter = new PrintWriter(clientSocket.getOutputStream());
}
public String nextInput() {
String mess = inputReader.nextLine();
System.out.println("< " + (++incounter) + ": " + mess);
return mess;
}
public void writeCommand(String command) {
System.out.println("> " + (++outcounter) + ": " + command);
outWriter.print(command);
outWriter.print('\n');
outWriter.flush();
}
#Override
public void close() throws Exception {
if (inputReader != null) {
inputReader.close();
inputReader = null;
}
if (outWriter != null) {
outWriter.close();
outWriter = null;
}
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
}
In addition, you're using 127.0.0.1 as server IP address, which is the loopback on your PC. Unless the interface to your robot works in a very peculiar way, the actual IP you should use is probably not this one.
I'm refering to this part of documentation here:
Setup a static IP-address and subnet mask on PC, so it matches the
robot, e.g.:
PC: IP-addr: 192.168.3.10 Robot: IP-addr: 192.168.3.3
Subnet: 255.255.255.0 Subnet: 255.255.255.0
Edit
If you've got more commands to put, use it like this:
//Inside your actual main class
public static void main(String[] args) {
System.out.println("Program started. Connecting to robot");
try (RobotTester robot = new RobotTester("127.0.0.1", 29999)) {
System.out.println("Connected to robot.");
robot.nextInput(); //Read and print robot's welcome message
robot.writeCommand("play"); //Send command
String resp = robot.nextInput(); //Read result
if (resp.toLowerCase().startsWith("fail")) {
throw new Exception("Play command failed: " + resp);
}
System.out.println("Command succeeded!");
robot.writeCommand("command1"); //Send command
resp = robot.nextInput(); //Read result
//Process result for command1
robot.writeCommand("command2"); //Send command
resp = robot.nextInput(); //Read result
//Process result for command2
//...
} catch (Throwable t) {
t.printStackTrace();
}
}
The latest update is that I have moved all the functions in the same Dialog and just called them straight from there, and is still not working.
I already double check there is just one stream and one writer and reader in the entire project.
JButton btnNewButton_2 = new JButton("START");
btnNewButton_2.setBackground(Color.GREEN);
btnNewButton_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
RobotTester("127.0.0.1", 29999);
nextInput();
String command="play";
writeCommand(command);
nextInput();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
close();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} });
public void RobotTester(String host, int port) throws UnknownHostException, IOException {
clientSocket = new Socket(host, port);
inputReader = new Scanner(clientSocket.getInputStream());
outWriter = new PrintWriter(clientSocket.getOutputStream());
}
public String nextInput() {
String mess = inputReader.nextLine();
System.out.println("< " + (++incounter) + ": " + mess);
return mess;
}
public void writeCommand(String command) {
System.out.println("> " + (++outcounter) + ": " + command);
outWriter.print(command);
outWriter.print('\n');
outWriter.flush();
}
public void close() throws Exception {
if (inputReader != null) {
inputReader.close();
inputReader = null;
}
if (outWriter != null) {
outWriter.close();
outWriter = null;
}
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
I have found a solution to the issue of reading the from the socket multiple times with a Swing GUI.
public void sendPlay() {
Thread appThread = new Thread() {
public void run() {
try {
RobotTester robot = new RobotTester("127.0.0.1", 29999);
System.out.println("Connected to robot.");
robot.nextInput(); //Read and print robot's welcome message
robot.writeCommand("play"); //Send command
String resp = robot.nextInput(); //Read result
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Finished on " + Thread.currentThread());
}
};
appThread.start();}
It seems that the background socket reading needs to be on a separate thread. This was causing the entire robot to be blocked. The idea was from an forum. It was not mine, but hey, it works.
Thank you very much!

Socket connection using BufferedReader / BufferedWriter

My server is not sending a response with BufferedWriter out to the client. It seems as if the code stops at int amountOfNumbersToBeGenerated = Integer.parseInt(bufferedReader.readLine()); I believe the bufferedreader.readline() call on the client side is causing and issue and blocking the connection in some sense.
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
public class ThreadedConnection implements Runnable {
private Socket connection;
private InputStream in;
private OutputStream out;
public ThreadedConnection(Socket connection) {
this.connection = connection;
try {
this.in = this.connection.getInputStream();
this.out = this.connection.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(out));
try {
String lotteryType = bufferedReader.readLine(); //reads first line of input stream
int amountOfNumbersToBeGenerated = Integer.parseInt(bufferedReader.readLine());
System.out.println("3"+amountOfNumbersToBeGenerated);
switch (lotteryType) {
case "LuckyForLife":
generateLotteryNumbers(amountOfNumbersToBeGenerated, 48, 18, bufferedWriter);
break;
case "MegaMillions":
generateLotteryNumbers(amountOfNumbersToBeGenerated, 70, 25, bufferedWriter);
break;
case "PowerBall":
generateLotteryNumbers(amountOfNumbersToBeGenerated, 69, 26, bufferedWriter);
break;
default:
break;
}
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
connection.close();
bufferedReader.close();
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void generateLotteryNumbers(int amountOfNumbersToBeGenerated, int upperLimitOfGeneratedNumbers, int upperLimitOfExtraNumber, BufferedWriter bufferedWriter){
RandomNumberGenerator randomNumbers = new RandomNumberGenerator(amountOfNumbersToBeGenerated,upperLimitOfGeneratedNumbers);
RandomNumberGenerator extraNumber = new RandomNumberGenerator(1,upperLimitOfExtraNumber);
ArrayList randomNumbersArrayList = randomNumbers.NumberGenerator();
ArrayList extraNumberArrayList = extraNumber.NumberGenerator();
String randomNumbersString = randomNumbersArrayList.toString();
randomNumbersString = randomNumbersString.substring(1, randomNumbersString.length()-1);
String extraNumberString = extraNumberArrayList.toString();
extraNumberString = extraNumberString.substring(1, extraNumberString.length()-1);
try {
bufferedWriter.write(randomNumbersString);
bufferedWriter.newLine();
bufferedWriter.write(extraNumberString);
bufferedWriter.newLine();
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
// System.out.println(randomNumbersString);
// System.out.println(extraNumberString);
}
}
Here is the code for the client side. I think the first String gerneretedNumber = bufferedReader.readLine(); is causing the issue. Almost as if it is called to read when there is nothing being written out from the server and then messing with the server side read. If I block both of the readline() calls the code on the server then works and I can get something to print out on console.
static void runClient(){
OutputStream outputStream;
InputStream inputStream;
Socket client;
BufferedWriter bufferedWriter;
BufferedReader bufferedReader;
try {
System.out.println("Creating client socket ");
client = new Socket("127.0.0.1", 5000);
outputStream = client.getOutputStream();
inputStream = client.getInputStream();
bufferedWriter = new BufferedWriter(new
OutputStreamWriter(outputStream));
//bufferedReader = new BufferedReader(new
InputStreamReader(System.in));
bufferedReader = new BufferedReader(new
InputStreamReader(inputStream));
bufferedWriter.write("LuckyForLife");
bufferedWriter.newLine();
bufferedWriter.write("5");
bufferedWriter.flush();
String generetedNumber = bufferedReader.readLine();
String extraNumber = bufferedReader.readLine();
System.out.println(gerneretedNumber);
System.out.println(extraNumber);
System.out.println("Guess its null");
bufferedReader.close();
bufferedWriter.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
If anymore information is needed I am happy to post it.
your client never sends the 2nd newline.
Given your protocol, client doesn't half close (output close) so the server cannot either detect end of stream.
BTW, try to close streams (tcp FIN) before close socket (tcp RST); it's more "ethical" ! Kidding aside, the tcp rst is a kill, and pending bytes might not be flushed out (although you have plenty of flushes here, it's just good practice).

Error java.net.SocketException: Socket closed in Client-Server communication [duplicate]

This question already has an answer here:
java.net.SocketException: socket closed TCP Client Server Communication [duplicate]
(1 answer)
Closed 7 years ago.
I have a problem with the iterated transfer of ArrayList<Object> between client and server. Infact I have to receive in my client the List and the first time i try it works, but when i return in the program's Home interface and i retry to send the List it launch a java.net.SocketException: Socket closed. I think that my problem could probably be the erroneous closing of my data/object flux or the closing of the Sever Socket. Am i wrong?
Here is my Client code:
private final static int PORT = 6543;
Socket s = null;
DataInputStream in;
DataOutputStream out;
ObjectOutputStream outObj;
ObjectInputStream inObj;
private List<Comunication> pfList = new ArrayList<Comunication>();
public Socket Connect() throws IOException{
System.out.println("Provo a connettermi al server....");
s = new Socket("192.168.1.3",PORT);
System.out.println("Connesso.");
//in = new DataInputStream(s.getInputStream());
out = new DataOutputStream(s.getOutputStream());
inObj = new ObjectInputStream(s.getInputStream());
//outObj = new ObjectOutputStream(s.getOutputStream());
return s;
}
public void getZanzIn() throws IOException{
int i;
System.out.println("Entro in prova");
try {
System.out.println("Dentro prova prima del flusso");
pfList = (ArrayList<Comunication>)inObj.readObject();
System.out.println("Dentro prova dopo il flusso");
inObj.close();
//s.close();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
for (Communication pfList1 : pfList) {
System.out.println(pfList1.getIdOrdine()+ " " + pfList1.getNome() + " " + pfList1.getTipo() + " " + pfList1.getRiferimento()+" "+pfList1.getAltezza()+" "+pfList1.getLarghezza()+" "+pfList1.getTipoMisura()+" "+pfList1.getData()+" "+pfList1.getColore()+" "+pfList1.getAttaccoFrontale()+" "+pfList1.getFrizione()+" "+pfList1.getStatoTelaio()+" "+pfList1.getStatoRete()+" "+pfList1.getStatoLavorazione());
}
pfList.clear();
}
public void CommunicateServer () {
try {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String str = "getZanzCut";
System.out.print(">> ");
out.writeUTF(str);
out.flush();
//str2=in.readUTF();
//System.out.println("Server says: "+str2);
out.close();
//s.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
Here is the server code:
public class Server {
public final static int PORT = 6543;
ServerSocket ss = null;
Socket s = null;
DataInputStream in;
DataOutputStream out;
ObjectInputStream objIn;
ObjectOutputStream objOut;
Connection conn;
protected final static String NOMEDRIVER = "com.mysql.jdbc.Driver";
protected final static String SERVERURL = "jdbc:mysql://localhost:3306/datazanzariere?zeroDateTimeBehavior=convertToNull";
protected final static String USER = "root";
protected final static String PASSWORD = "admin";
public Socket WaitObj(){
try {
System.out.println("inizializzo il server");
ss = new ServerSocket(PORT);
System.out.println("server pronto in ascolto");
s = ss.accept();
System.out.println("connessione stabilita");
in = new DataInputStream(s.getInputStream());
objOut = new ObjectOutputStream(s.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
return s;
}
public void CommunicateClient(){
try {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String str="";
str=in.readUTF();
System.out.println("client says: "+str);
System.out.print(":: ");
if(str.equals("getZanzCut")){
this.getZanzCut();
}
in.close();
//s.close();
//ss.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void getZanzCut(){
try {
List<Comunication> comList = new ArrayList();
Class.forName(NOMEDRIVER);
conn = DriverManager.getConnection(SERVERURL, USER, PASSWORD);
Statement st = conn.createStatement();
Statement st2 = conn.createStatement();
Statement st3 = conn.createStatement();
Statement stm4 = conn.createStatement();
Statement stm5 = conn.createStatement();
st.execute("Create view Modello (ID, Tipo) as select ZanzarieraV, Tipo from verticale union all select Zanzariera, Tipo from laterale");
st2.execute("CREATE view DatiCliente (ID, Nome) as SELECT ClienteF, Cognome FROM personafisica UNION SELECT Cliente, NomeAzienda FROM personagiuridica");
ResultSet rs = st3.executeQuery("SELECT IdOrdine, D.Nome, Tipo, Riferimento, Larghezza, Altezza, TipoMisura, Data, C.Colore, Frizione, AttaccoFrontale\n" +
"FROM riepilogoordine R JOIN Colore C ON R.Colore = C.IdColore\n" +
"JOIN Modello M ON R.ZanzarieraO = M.ID \n" +
"JOIN DatiCliente D ON R.ClienteO = D.ID\n" +
"WHERE StatoRete = 'Da tagliare'");
while(rs.next()) {
Comunication com = new Comunication();
com.setIdOrdine(rs.getInt("IdOrdine"));
com.setNome(rs.getString("Nome"));
com.setTipo(rs.getString("Tipo"));
com.setRiferimento(rs.getString("Riferimento"));
com.setLarghezza(rs.getInt("Larghezza"));
com.setAltezza(rs.getInt("Altezza"));
com.setTipoMisura(rs.getString("TipoMisura"));
com.setData(rs.getDate("Data"));
com.setColore(rs.getString("Colore"));
com.setFrizione(rs.getString("Frizione"));
com.setAttaccoFrontale(rs.getString("AttaccoFrontale"));
comList.add(com);
}
objOut.writeObject(comList);
stm4.execute("drop view modello");
stm5.execute("drop view DatiCliente");
comList.clear();
conn.close();
objOut.close();
//s.close();
//ss.close();
} catch (ClassNotFoundException | SQLException | IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
Closing the input stream or output stream of a socket closes the socket.
Solution: don't, until you're done with the socket.

SimpleClient - GET request

I got this training task on my school which says: Make a change in "SimpleClient" so that it makes a GET request to a address given on the command line and stores the content of the response to a file on disk.
import java.net.*;
import java.io.*;
public class SimpleClient {
public static void main(String[] args) {
try {
Socket con = new Socket(args[0], Integer.parseInt(args[1]));
PrintStream out = new PrintStream(con.getOutputStream());
out.print(args[2]);
out.write(0); // mark end of message
out.flush();
InputStreamReader in = new InputStreamReader(con.getInputStream());
int c;
while ((c = in.read())!=-1)
System.out.print((char)c);
con.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
As far as I can se the "con" instance of Socket should make a connection to a host (args[0] eg. www.google.com) through a port number (args[1]). Then a PrintStream "out" is made, but what is the function of out.print(args[2]) and out.write(0)? I do not understand the program completely so I would appreciate if someone could explain it to me and maybe tell what should be changed to make it work.
Opening a socket connection is not the same as firing a GET request. Have a look at Using java.net.URLConnection to fire and handle HTTP requests
Okay, I found a solution if anyone should be interested.
import java.net.*;
import java.io.*;
public class SimpleClient {
public static void main(String[] args) {
try {
FileWriter fw = new FileWriter(args[args.length - 1]);
BufferedWriter bw = new BufferedWriter(fw);
try {
Socket con = new Socket(args[0], Integer.parseInt(args[1]));
PrintStream out = new PrintStream(con.getOutputStream());
out.println("GET /search?q=" + args[2] + " HTTP/1.1");
out.println("Host: www.google.com");
out.println("");
out.write(0); // mark end of message
out.flush();
InputStreamReader in = new InputStreamReader(
con.getInputStream());
int c;
while ((c = in.read()) != -1)
bw.write((char) c);
con.close();
} catch (IOException e) {
System.err.println(e);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}

Java client app freezes when sending object through sockets

i have this client/server application, and the client application sometimes completely freezes when i try send object via sockets
public Client client = new Client();
petriNetList = client.query(client.actionLoadPetriNetList, MainWindow.loginUsername);
here is the code of the client
public class Client {
public static Socket kkSocket = null;
public static PrintWriter out = null;
public static BufferedReader in = null;
public static BufferedReader stdIn = null;
public static OutputStream outputStream = null ;
public static ObjectOutputStream objectOutputStream = null ;
public static InputStream inputStream = null ;
public static ObjectInputStream objectInputStream = null ;
public String actionSavePetriNet = "SAVE PETRI NET START";
/*
* Save petri net to server
*
* #param action identifies query
* #param petriName name of the petri net
* #param username username
* #param xml content of the petri net
*
* #return int response form server
*/
public int query (String action,String petriName,String username,String xml) throws IOException {
int size ;
int result = 0;
connect();
if (action.equals(actionSavePetriNet)) {
out.println(action); // save petri net
out.println(petriName); //petri net name
out.println(username); //username
System.out.println("(Client:)" + xml);
objectOutputStream.writeObject(xml); //send object over the network
System.out.println("Dostali sme sa sem ?");
result = Integer.parseInt(in.readLine()); //read response from server
}
disconnect();
return result;
}
/*
* connect to server
* TODO: ADD hostname and port as parameter
*/
public static void connect() throws IOException {
try {
kkSocket = new Socket("osiris-PC", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
System.exit(1);
}
stdIn = new BufferedReader(new InputStreamReader(System.in));
outputStream = kkSocket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
inputStream = kkSocket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
}
/*
* Disconnect from server
* close all input/output streams
*
*/
public static void disconnect() throws IOException {
out.close();
in.close();
stdIn.close();
objectOutputStream.close();
outputStream.close();
objectInputStream.close();
inputStream.close();
kkSocket.close();
}
}
and this is the code of server
public class PetriServer {
public static Protocol kkp = new Protocol();
public static InputStream inputStream = null ;
public static ObjectInputStream objectInputStream = null ;
public static OutputStream outputStream = null ;
public static ObjectOutputStream objectOutputStream = null ;
public static void main(String[] args) throws IOException, ClassNotFoundException {
kkp.loadUsers();
while(true) {
ServerSocket serverSocket = null;
inputStream = null ;
objectInputStream = null ;
outputStream = null ;
objectOutputStream = null ;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
inputStream = clientSocket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
outputStream = clientSocket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
inputLine = in.readLine();
String inputLine;
if (inputLine.equals("SAVE PETRI NET START")) {
String petriName;
String username;
String xml ;
String input;
int result;
int size ;
petriName = in.readLine(); //read petri name
System.out.println("(Server): prijali sme poziadavok na ulozenie " + petriName );
username = in.readLine(); //read username
System.out.println("(Server): poziadavok ide od usera: " + username);
while(true) {
//this is the line where is occasionally freezes
xml = (String)objectInputStream.readObject(); //read object over the network
if (!xml.isEmpty()) break;
}
System.out.println("(Server):" + xml);
result = kkp.savePetrinet(username, petriName,xml); //save it to the file
out.println(result);
}
out.close();
in.close();
objectInputStream.close();
inputStream.close();
objectOutputStream.close();
outputStream.close();
clientSocket.close();
serverSocket.close();
}
}
}
Does anybody know what can be problem ?
cheers.
You have the Socket InputStream on the server attached to two different inputs, ObjectInputStream and BufferedReader. InputStreams are not intended to be used this way, and doing so can cause a lot of problems. BufferedReaders, by their nature, are going to be pulling more data off the InputStream than you are actually reading. If they happen to buffer data that makes up an object, then your subsequent attempt to read the object off the ObjectInputStream will block, because the data has already been removed.
You need to pick one method or the other to read data. If you need to be able to read both Strings and Objects off the Socket, then you will have to go to a byte-oriented mode of operation where you read the bytes off into a byte array, then process the byte array yourself to insure that you don't loose any data.
Edit based on #Dunes comment below
Seems your best bet is to stick entirely with ObjectInputStream and make use of its other methods that allow you to read arbitrary primitive types from the stream. And, if you don't mind the deprecated call, it even has a readLine method.

Categories

Resources