How to resolve a Stream Closed Error in java? - java

I am really thankful for everyone who would read this and try to help me, the following is the code I am trying to write for a server class for a socket-programming project for college:
import java.io.*;
import java.net.*;
import java.io.File;
class Server{
public static void main (String[]args)throws IOException{
ServerSocket socket1 = new ServerSocket (8000);
while (true) {
Socket incoming = socket1.accept();
new newclass(incoming).start();
}
}
}
class newclass extends Thread implements Runnable {
Socket incoming;
public newclass(Socket incoming) {
this.incoming = incoming;
}
public void run() {
try {
byte x = 0;
String z;
String s = "HTTP 1.0 200 Document follows";
String s1 = "Bad request message";
BufferedReader input = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
PrintWriter output = new PrintWriter(incoming.getOutputStream(), true);
DataOutputStream sending = new DataOutputStream(incoming.getOutputStream());
File directory = new File("C:\\Documents and Settings\\Ahmed\\Desktop\\bla\\Server");
File[] files = directory.listFiles();
int x1 = files.length;
if ((x1 - 3) < 10) {
boolean done = false;
while (!done) {
String line = input.readLine();
System.out.println(line);
if (line.equals("BYE")) {
output.println("BYE");
done = true;
} else {
if (line.trim().substring(0, 3).equals("GET ")) {
if (line.equals("<javalogo.png> HTTP 1.0")) {
File f = new File("javalogo.png");
int size = (int) f.length();
if (f.exists() == true) {
output.println(s);
output.println(size);
output.println("javalogo1.png");
DataInputStream bytefile = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
while (bytefile.available() != 0) {
x = bytefile.readByte();
sending.write(x);
}
} else {
System.out.println("Getting file from main server");
Socket socket2 = new Socket("127.0.0.1", 8100);
BufferedReader bUsr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pOut = new PrintWriter(socket2.getOutputStream(), true);
BufferedReader bIn = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
pOut.println("GET <javalogo.png> HTTP 1.0");
String rep = bIn.readLine();
if (rep.equals("HTTP 1.0 200 Document follows")) {
int len = Integer.parseInt(bIn.readLine());
String fname = bIn.readLine();
File f1 = new File(fname);
f1.createNewFile();
FileOutputStream fos = new FileOutputStream(f1);
DataInputStream dis = new DataInputStream(socket2.getInputStream());
for (int i = 0; i < len; i++) {
fos.write(dis.read());
}
fos.close();
} else if (rep.equals("File does not exist")) {
output.println("Sorry, but the file was neither found in the proxy server or the main server or the name is wrong.");
}
}
}
File f2 = new File("javalogo.png");
if (f2.exists() == true) {
int size = (int) f2.length();
output.println(s);
output.println(size);
output.println("javalogo.png");
DataInputStream bytefile = new DataInputStream(new BufferedInputStream(new FileInputStream(f2)));
while (bytefile.available() != 0) {
x = bytefile.readByte();
sending.write(x);
}
}
} else {
System.out.println(s1);
output.println(s1);
}
}
}
incoming.close();
}
output.println("Connecting to main server");
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Now I don't understand why am I getting an error when I run the following client on it.
I get this really weird error where the buffered reader reads the first line from the user correctly but with the second one it gives me a null exception as if the client wrote null or something, I dont get it.
Here's the client code anyways, if anyone can help me I would be plenty thankful.
import java.net.*;
import java.io.*;
public class Client {
public static void main(String[] args) throws Exception {
Socket socket1 = new Socket("127.0.0.1", 8000);
BufferedReader bUsr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pOut = new PrintWriter(socket1.getOutputStream(), true);
BufferedReader bIn = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
String cmd;
String rep;
while (true) {
cmd = bUsr.readLine();
pOut.println(cmd);
System.out.println(rep = bIn.readLine());
if (cmd.equals("BYE") || cmd.equals("END"))
break;
else if (rep.equals("HTTP 1.0 200 Document follows")) {
int len = Integer.parseInt(bIn.readLine());
String fname = bIn.readLine();
File f = new File(fname);
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
DataInputStream dis = new DataInputStream(socket1.getInputStream());
for (int i = 0; i < len; i++) {
fos.write(dis.read());
}
fos.close();
System.out.println("Success");
} else if (rep.equals("Connecting to main server")) {
Socket socket1 = new Socket("127.0.0.1", 8100);
BufferedReader bUsr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pOut = new PrintWriter(socket1.getOutputStream(), true);
BufferedReader bIn = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
String cmd;
String rep;
while (true) {
cmd = bUsr.readLine();
pOut.println(cmd);
System.out.println(rep = bIn.readLine());
if (cmd.equals("BYE") || cmd.equals("END"))
break;
else if (rep.equals("HTTP 1.0 200 Document follows")) {
int len = Integer.parseInt(bIn.readLine());
String fname = bIn.readLine();
File f = new File(fname);
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
DataInputStream dis = new DataInputStream(socket1.getInputStream());
for (int i = 0; i < len; i++) {
fos.write(dis.read());
}
fos.close();
System.out.println("Success");
}
}
}
bIn.close();
pOut.close();
socket1.close();
}
}
This is the first time asking anything on this site, so if I did anything wrong I would be more than happy to change what I wrote.
By the way, the part in the server which states "getting file from main server" is a part where the server itself becomes a client for a main server, from where it gets the file and sends it to the client, I didn't add the main server code because it'd be too much code but basically it's the same as server without the if condition restricting it to 10 files in the directory only.

In general, when there is a NullPointerException either:
You have not instantiated your object
Your object has been destroyed (closed) and therefore does not exist
You have an invalid cast
Your code has overwritten your object pointer
You would need to examine your stack dump to see which of these is true.
From the Jav Docs the read can throw IOException if an I/O error occurs and IOException can give you the specified detail message. The error message string can later be retrieved by the Throwable.getMessage() method of class java.lang.Throwable.
Two points:
What does the IOException detail give you?
Since this is for your college course, try asking your classmates or TA for assistance

I'd be lying if I said I fully understand what your code is doing - But if you are getting null data when you are reading from a stream which you expect to contain data it could be that the output stream hasn't 'flushed' the data.
Make sure you call the flush() method on your Output streams after you have written to them

Ahemd, I see a number of potential errors and some actual bugs too in the classes as posted, but the code is too complicated for me to focus on the issue you are seeing. If you're still experiencing network bugs, try reducing the code and both client and server to the minimal possible to get communication going (send/read one line). If that doesn't work for you, post those classes and we'll be able to see the problems much more quickly than with the larger classes posted here.
Good luck.

If you are getting null from a BufferedReader.readLine() it means you have reached the end of input as it states in the javadoc for this method.

The best way to find your errors solution , is to see a trace. Without it I see more than one error in your code.
Regards.

Related

Resuming a file upload in java Socket

package experiments;
import java.io.*;
import java.net.Socket;
/** * * #author User */
/*THE CLIENT*/ public class UploadManager {
public static void setup(String address, int port,String path){
try( Socket s = new Socket(address,port); OutputStream out = s.getOutputStream(); InputStream in = s.getInputStream(); DataOutputStream dos = new DataOutputStream(out);
DataInputStream dis = new DataInputStream(in); )
{
/** * send file name and size to server */
System.out.println("processing file now");
File from = new File(path);
if(from.exists() && from.canRead()){
String FILENAME = from.getName();
long FILESIZE = from.length();
// String FILEHASH
/** * write all ,2 * to SERVER */ dos.writeLong(FILESIZE); dos.writeUTF(FILENAME);
//dos.writeUTF(FILEHASH);
dos.flush();
/** * what does SERVER HAS TO SAY? */
String RESPONSE_FROM_SERVER_1 =dis.readUTF();
if(RESPONSE_FROM_SERVER_1 . equalsIgnoreCase("SEND")){
uploadFresh(from,dos);
}
/** * in case there was an interruption we need * resume from an offset. */
if(RESPONSE_FROM_SERVER_1 . equalsIgnoreCase("RESUME")){
/** * length already sent */
System.out.println("resuming upload");
String LENGTH_ALREADY_READ =dis.readUTF();
long OFF_SET = Long.parseLong(LENGTH_ALREADY_READ);
/** * get the file name so we know the exact file */
String FILE_REAL_NAME = dis.readUTF();
resume(FILE_REAL_NAME,OFF_SET,dos);
}
}else{ System.out.println("Couldn't read: err");
}
}catch(Exception ex){
ex.printStackTrace();
}
}
/** the resume method **/
private static void resume(String FILE_REAL_NAME,long OFF_SET,DataOutputStream to)throws Exception{
/** * copy from the stream or disk to server */
FileInputStream reader = null;
try{
reader = new FileInputStream(new File("c:\\movies\\hallow.mp4",FILE_REAL_NAME)); byte[] size = new byte [8192];
int COUNT_BYTES_READ ; reader.skip(OFF_SET);
//skip the length already written
while( (COUNT_BYTES_READ = reader.read(size)) >0{
to.write(size);
to.flush();
}
}finally{
if( reader != null ) reader.close();
to.close();
}
}
/** and the normal send method which works as expected **/
private static void uploadFresh(File from, DataOutputStream to)throws Exception{
/** * copy from the stream or disk to server */
FileInputStream reader = null;
try{
reader = new FileInputStream(from);
byte[] size = new byte [1024];
int COUNT_BYTES_READ ;
while( (COUNT_BYTES_READ = reader.read(size)) >0){
to.write(size,0,COUNT_BYTES_READ); to.flush();
}
}finally{
if( reader != null ) reader.close();
to.close();
}
}
}
//ThE SERVER
public class UserServer {
String ip_Adress;
int Port;
ServerSocket ss;
String path;
public UserServer(String ip_Adress,int Port ){
this.Port =Port; this.ip_Adress = ip_Adress; this. path = path;
}
public void startserver() throws IOException{
FileOutputStream fos =null;
// String realhash;
out.println("starting server");
this.ss= new ServerSocket(Port);
out.println("starting server on port"+Port); out.println("waiting for client conection......");
Socket visitor = this.ss.accept();
out.println("1 User connected to port");
/**
* reading file name and size from upload
*/
try( OutputStream ot =visitor.getOutputStream(); InputStream in = visitor.getInputStream(); DataOutputStream dos = new DataOutputStream(ot); DataInputStream dis = new DataInputStream(in); ){
System.out.println("processing debug");
long FILE_SIZE = dis.readLong();
System.out.println(FILE_SIZE+"processing");
String FILE_NAME = dis.readUTF(); System.out.println(FILE_NAME+"processing");
//String FILEHASH = dis.readUTF(); // System.out.println(FILEHASH+"processing");
File file = new File("c:\\aylo\\"+FILE_NAME);
/** * what do We Have TO Say? */
if(file.exists()){
long SIZE = file.length();
if(SIZE<FILE_SIZE){
String RESUME = "RESUME";
//tell client to resume the upload
dos.writeUTF(RESUME);
/*sending the resuming length in*/ string String size = String.valueOf(SIZE);
dos.writeUTF(size);
dos.flush();
fos=new FileOutputStream(file,true);
//append to exisiting file
byte[] b = new byte [1024]; int COUNT_BYTES_READ ;
while( (COUNT_BYTES_READ = dis.read(b)) >0){
fos.write(b);
fos.flush();
}
}
} else{
}
if(!file.exists()){
file.getParentFile().mkdirs();
file.createNewFile();
String SEND = "SEND";
dos.writeUTF(SEND);
dos.flush();
fos=new FileOutputStream(file);
byte b[]=new byte[1024];
int s;
while((s=dis.read(b))>0){
fos.write(b,0,s); fos.flush(); System.out.println(s+"processing");
}
}
System.out.println("i'm done reading ");
}catch(Exception ex){
ex.printStackTrace();
}finally{
fos.close();
if(this.ss!=null) this.ss.close();
}
}
//the main
public static void main(String []arg){
UserServer us = new UserServer("localhost", 2089);
us.startserver();
//start client
UploadManager.setup("localhost", 2089, ("c:\\movies\\hallow.mp4"));
}
}
I've searched and searched most forums and OS about this and found nothing.
What I'm trying to do is to learn or figure out how I can resume a file interrupted on upload through java socket.
Right now my code partially works, but there's always a break or gap which I assumed is caused by the new FileOutputStream(from,true); constructor
Can anyone pls check my methods and help point out my mistakes a sample code demo too will be nice. Thanks!
Please review java convention on variable names; it took me quite a while to find your problem, and a lot of it is down to the fact that your code looks unfamiliar. Also, really, review your names. Naming a byte buffer to transfer bytes 'size' is similar to naming your favourite cat 'horse'. It's going to cause confusion.
The problem: You have quite a few places where you do this:
byte[] buffer = new byte[8192];
int bytesRead = networkIn.read(buffer);
fileOut.write(buffer);
and this is incorrect. The 'write' call will write the entire buffer, all 8192 bytes, even if fewer than 8192 bytes were actually read. What you need to do is this:
byte[] buffer = new byte[8192];
int bytesRead = networkIn.read(buffer);
fileOut.write(buffer, 0, bytesRead);
NB: It is possible there are more bugs in your code; the above is one that's definitely going to cause issues and would explain why a resume operation produces a corrupted file.

Java read process output unbuffered / realtime

I want to read the stdout of a process right as it is generated.
The process will send information for a progress indicator, so it doesn't make sense that I get the information all at once, which I do and which is the problem. I tried to use Scanner class as suggested in a post, but I still get the output only after the process has finished.
I realize this question has been asked before, but it hasn't been answered.
You will probably want to look at class StreamGobblerOutput first.
public List<String> executeCall(String fileName)
{
StringBuilder sbOutput = new StringBuilder();
StringBuilder sbError = new StringBuilder();
File file = new File(fileName);
try ( BufferedReader br = new BufferedReader(new FileReader(file)) ) {
String line;
while ((line = br.readLine()) != null) {
String [] parts = line.split("\\s");
if(parts.length<2) {
sbError.append("Command too short for call: " + parts[0]);
continue;
}
List<String> args = new ArrayList<String>();
args.add ("sfb.exe");
for(int i = 1; i <parts.length; ++i) {
args.add (parts[i]);
}
args.add (sfbPassword);
ProcessBuilder pb = new ProcessBuilder (args);
pb.directory(new File(Support.getJustThePathFromFile(file)));
Map<String, String> envs = pb.environment();
String path = envs.get("Path");
envs.put("Path", Paths.get(".").toAbsolutePath().normalize().toString() + ";" +path);
//pb.redirectOutput(new Redirect() {});
Process p = pb.start();
String outputPathPrefix = pb.directory().getCanonicalPath();
// any output?
StreamGobblerOutput outputGobbler = new StreamGobblerOutput(p.getInputStream(), outputPathPrefix);
outputGobbler.start();
// any errors?
StreamGobblerError errorGobbler = new StreamGobblerError(p.getErrorStream());
errorGobbler.start();
try
{
p.waitFor();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
sbOutput = outputGobbler.getOutput();
sbError = errorGobbler.getErrors();
String rootPath= Support.getJustThePathFromFile(new File(fileName));
File rootFile = new File(rootPath + "/..");
String rootFolder = rootFile.getCanonicalFile().getName();
System.err.println("rootFolder: " + rootFolder);
mainApp.addModifiedFiles(outputGobbler.getModifiedFileNames(), rootFolder);
}
} catch ( IOException ex) {
sbError.append(ex.getMessage());
}
mainApp.addOutput(sbOutput.toString());
mainApp.addError(sbError.toString());
return;
}
private class StreamGobblerOutput extends Thread {
private InputStream is;
private String outputPathPrefix;
private StringBuilder sbOutput;
private List<String> modifiedFileNames;
private Scanner scanner;
private StreamGobblerOutput(InputStream is, String outputPathPrefix) {
this.is = is;
this.outputPathPrefix = outputPathPrefix;
sbOutput = new StringBuilder();
modifiedFileNames = new ArrayList<String>();
scanner = new Scanner(is);
}
public StringBuilder getOutput() {
return sbOutput;
}
public List<String> getModifiedFileNames() {
return modifiedFileNames;
}
#Override
public void run() {
//create pattern
Pattern patternProgress = Pattern.compile("\\((\\d+)%\\)");
//InputStreamReader isr = new InputStreamReader(is);
//BufferedReader br = new BufferedReader(isr);
String ligne = null;
while (scanner.hasNextLine()) {
ligne = scanner.nextLine();
sbOutput.append(ligne);
sbOutput.append("\r\n");
//bw.write("\r\n");
Matcher mProgress = patternProgress.matcher(ligne);
if (mProgress.find()) {
int percentage = Integer.parseInt(mProgress.group(1));
System.err.println("percentage=" + percentage);
mainApp.mainWindowController.setProgressExecute(percentage/100.0);
}
}
mainApp.mainWindowController.setProgressExecute(1.0);
if (scanner != null) {
scanner.close();
}
}
}
private class StreamGobblerError extends Thread {
private InputStream is;
private StringBuilder sbError;
private Scanner scanner;
private StreamGobblerError(InputStream is) {
this.is = is;
sbError = new StringBuilder();
scanner = new Scanner(is);
}
public StringBuilder getErrors() {
return sbError;
}
#Override
public void run() {
//InputStreamReader isr = new InputStreamReader(is);
//BufferedReader br = new BufferedReader(isr);
String ligne = null;
while (scanner.hasNextLine()) {
ligne = scanner.nextLine();
sbError.append(ligne);
sbError.append("\r\n");
}
if (scanner != null) {
scanner.close();
}
}
}
Update: I tried redirecting the output to a file and reading from it, but it appears this runs into the same buffering problem as the previous implementation: I get only two data points.
As a workaround, I will have to ask the creator of the .exe to include 4100 extra characters in each line showing the progress.
If your external process is C/C++ (stdio) based, than this is most likely a block buffering issue:
stdio-based programs as a rule are line buffered if they are running interactively in a terminal and block buffered when their stdout is redirected to a pipe. In the latter case, you won't see new lines until the buffer overflows or flushed.
see this answer for more details, and some possible workarounds.
Please also note that according to this, line buffering is not an option on Win32:
_IOLBF
For some systems, this provides line buffering. However, for Win32, the behavior is the same as _IOFBF - Full Buffering.
so if you choose to modify the "exe" program to set a proper output mode with setvbuf, you would have to use:
_IONBF No buffer
instead.
From the Javadocs
Optionally, a PrintStream can be created so as to flush automatically;
this means that the flush method is automatically invoked after a byte
array is written, one of the println methods is invoked, or a newline
character or byte ('\n') is written.
Reference: http://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html
One way to do this is to have output stream flush() after every write.
System.out.flush()
You could also define your own flushable PrintStream and use that.

linux- can not find the files

I have a really strange problem:
(from the main function):
try {
java.io.InputStream is = null;
if (args.length == 0) {
is =
ClassLoader.
getSystemClassLoader().getResourceAsStream("level_sets.txt");
} else {
is =
ClassLoader.getSystemClassLoader().getResourceAsStream(args[0]);
}
LineNumberReader reader = null;
reader = new LineNumberReader(new InputStreamReader(is));
LevelSetReader lsr = new LevelSetReader(reader);
List<String> keyAdderss = lsr.getKeyAdressMap();
for (int i = 0; i < keyAdderss.size(); i++) {
String add = keyAdderss.get(i);
File file = new File(add);
BufferedReader reader2 = null;
try {
reader2 = new BufferedReader(
new InputStreamReader(
new FileInputStream(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
the progrem at first check if there is a single commandline paramete - if don't, go to our default file called: "level_set.txt"(in our bin) otherwise check the file there.
(The level_sets.txt file contein addresses to other txt files.)
After that call every address and analise those too...
The problem is that he can no find those files in linux...
He can find the level_sets.txt but not the other files...
I must mention that it works perfect in eclips!
We tried hundreds of way but failed...
In addition, when we deleted the if-else at the begining it worked!!!
like:
java.io.InputStream is = null;
is =
ClassLoader.
getSystemClassLoader().getResourceAsStream("level_sets.txt");
What to do?
Thanks! :)

how to set and take in a integer to/from a file in java

So this is a very simple question. I have been trying to research it, and yes I have slightly found some answers but i can't find out how it works so i have come to this.
I am making a simple game in java (pong) and their is a high score integer that i would like to be able save and load from a file (I have heard a lot about using a txt file so probably that, but i have also heard about using a xml i believe is what it is, but i did not look into that as much). How exactly do i program this?
Thank you to all who answer.
PS
I have looked into this code but I don't understand how it's workings
String strFilePath = "C://FileIO//WriteInt.txt";
try {
//create FileOutputStream object
FileOutputStream fos = new FileOutputStream(strFilePath);
DataOutputStream dos = new DataOutputStream(fos);
int i = 100;
dos.writeInt(i);
dos.close();
} catch (IOException e) {
System.out.println("IOException : " + e);
}
The most simplest way is to create a file, i.e.
write the score to a file, e.g.
String user = "John";
int score = 100;
f = new BufferedWriter(new FileReader(filepath));
f.write(user + "=" + score); // assuming "=" is not inside the user name
f.close();
then read from the file when you need it, e.g.
f = new BufferedReader(new FileReader(filepath));
String line = f.readLine().trim();
String[] temp = line.split("="); // now temp is of the form ["John", "100"]
String user = temp[0];
int score = Integer.parseInt(temp[1]);
f.close();
I think you can solve this encoding the object into a file,but it wont be an xml, it will be a custom file that only your app will be able to open
public void save(Integer ... integersToEncode){
try{
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream (new File(/*yourFileName*/)));
for(Integer encoding : integersToEncode)
output.writeObject(encoding);
output.close();
}
catch(Exception e){
//What do you want to do if the program could not write the file
}
}
For reading
public Integer[] read(int size){
Integer[] objects = new Integer[size];
try{
ObjectInputStream input = new ObjectInputStream(new FileInputStream (new File(/*yourFileName*/)));
for(int i = 0; i < size ; i++)
objects[i] = (Integer)input.readObject();
input.close();
}
catch(Exception e){
//What do you want to do if the program could not write the file
}
return objects;
}
Maybe you were confused by the way the original code you posted was printing the char 'd' to the output file. This is the character's ASCII value, as you may know. The following modifications to your code make it work the way you were orginally looking at:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class Game {
public static void main(String[] args) throws IOException {
Game game = new Game();
game.writeHighScore();
}
public void writeHighScore() throws IOException{
String strFilePath = "C:/Users/User/workspace/HighScore.txt";
FileInputStream is = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
try
{
//create FileOutputStream object
fos = new FileOutputStream(strFilePath);
dos = new DataOutputStream(fos);
int i = 100;
dos.writeInt(i);
System.out.println("New High Score saved");
dos.close();
// create file input stream
is = new FileInputStream(strFilePath);
// create new data input stream
dis = new DataInputStream(is);
// available stream to be read
while(dis.available()>0)
{
// read four bytes from data input, return int
int k = dis.readInt();
// print int
System.out.print(k+" ");
}
}catch(Exception e){
// if any error occurs
e.printStackTrace();
}finally{
// releases all system resources from the streams
if(is!=null)
is.close();
if(dis!=null)
dis.close();
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
}
}
}

Simple Client Server program

I making an elementary project based on TCP/IP where server listens to the client and then provides a capital sentence of the incoming data.
Server.java:
import java.io.*;
import java.net.*;
public class Server
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(7948);
Socket s= ss.accept();
System.out.print("Server connected\n");
BufferedInputStream bis = new BufferedInputStream (s.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());
while(true)
{
int a = bis.available();
byte b[] = new byte[a];
bis.read(b);
String str = new String(b);
str = str.toUpperCase();
b = str.getBytes();
bos.write(b,0,b.length);
bos.flush();
if(str.equals("BYE"))
break;
else
continue;
}
System.out.print("\nServer Disconnecting");
String str = "Adios Amigo";
bos.write(str.getBytes());
bos.flush();
bis.close();
bos.close();
ss.close();
s.close();
}
}
Client.java:
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws Exception
{
BufferedReader clientStream = new BufferedReader(new InputStreamReader(System.in));
String str;
int a;
byte[] b;
Socket s = new Socket(InetAddress.getLocalHost(), 7948);
BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());
BufferedInputStream bis = new BufferedInputStream (s.getInputStream());
one:while(true)
{
str = clientStream.readLine();
b =str.getBytes();
bos.write(b);
bos.flush();
a=bis.available();
b = new byte[a];
bis.read(b);
str = new String (b);
str.trim();
System.out.print("The server says: "+str);
if (str.equals("BYE"))
{
bis.read(b);
str = new String (b);
System.out.print("The server says: "+str);
break one;
}
}
s.close();
clientStream.close();
bos.close();
bis.close();
}
}
The program is working properly except for one problem, output at client side comes after two inputs. It means that I have to give two inputs from client sides to get the first output, and this continues. I am unable to track the bug.
Can anyone please help ?
in the client, you send data to the server, and then immediately call a.available() - this function does not wait for data to be sent from the server. since the server is unlikely to have responded with data by the time the .available() is called, the function returns zero.
because of this, your byte array b (please use more descriptive variable names in the future) is of length zero.
once the array of size zero is created, you finally wait for data by calling bis.read() - .read() is a blocking call. it will wait for data from the server. this data is not actually read, because the array you are reading in to is size zero. this results in the printing out of an empty string.
the following code will fix the problem, but for the future, i do not recommend using .available() - it is rather unreliable in my experience. you should check if data is available by simplying attempting to read data.
Client.java:
one:while(true)
{
str = clientStream.readLine();
b =str.getBytes();
bos.write(b);
bos.flush();
while (bis.available() <= 0)
{
// wait for data!
}
a=bis.available();
b = new byte[a];
bis.read(b);
str = new String (b);
str.trim();
System.out.print("The server says: "+str);
if (str.equals("BYE"))
{
bis.read(b);
str = new String (b);
System.out.print("The server says: "+str);
break one;
}
}

Categories