Compressing and decompress data through sockets - java

I'm having issues with this question right now.
For this question, I have to:
Client side: compress each input line from the console, send it to the server and decompress each message from server
Server side: decompress data from client, change the lower-case letters to upper case, compress it and send back to the client
The best I can do is do everything above with only ONE line.
Client Side:
/* SOCKET CONNECTING STUFF UP HERE */
/*PROBLEMS START AROUND HERE */
String line;
BufferedReader bis = new BufferedReader(new InputStreamReader(System.in));
DeflaterOutputStream compress = new DeflaterOutputStream(socket.getOutputStream(), true);
InflaterInputStream decompress = new InflaterInputStream(socket.getInputStream());
BufferedReader fromClient = new BufferedReader(new InputStreamReader(decompress));
line = bis.readLine();
line = line + "\n";
compress.write(line.getBytes(), 0, line.length());
compress.finish();
System.out.println("Message sent: " + line);
System.out.println("Message Returned : " +fromClient.readLine());
/* closing the streams here */
bis.close();
decompress.close();
compress.close();
fromClient.close();
socket.close();
}
}
Server Side:
String line = "";
OutputStream outstream = new FileOutputStream("compessserver.txt");
InflaterInputStream decompress = new InflaterInputStream(clientsocket.getInputStream());
BufferedReader fromClient = new BufferedReader(new InputStreamReader(decompress));
DeflaterOutputStream compress = new DeflaterOutputStream(clientsocket.getOutputStream());
while ((line = fromClient.readLine()) != null) {
String upperLine = line.toUpperCase();
System.out.println("Message received and converted: " + upperLine);
System.out.println();
upperLine = upperLine + "\n";
byte[] input = upperLine.getBytes();
outstream.write(input);
outstream.write("\r\n".getBytes());
compress.write(input);
System.out.println("Message returned : " + upperLine);
compress.finish();
if (upperLine.equalsIgnoreCase("x")) {
break;
}
}
decompress.close();
compress.close();
fromClient.close();
outstream.close();
socket.close();
}
}
I really need help in this please. If I try to make this multiple inputs instead, the whole code just messes up. Been at this for days.
EDIT: Forgot to mention this. What I'm supposed to do is input a line, compress it, send to server, server decompress it and upper case letters, compress it, send back to client. And then I supposed to input more lines until I put in a single letter like "Q" which in case, ends the program
I tried the following code to make it work for multiple lines
Second Try Client Side:
String line;
BufferedReader bis = new BufferedReader(new InputStreamReader(System.in));
DeflaterOutputStream compress = new DeflaterOutputStream(socket.getOutputStream(), true);
InflaterInputStream decompress = new InflaterInputStream(socket.getInputStream());
BufferedReader fromClient = new BufferedReader(new InputStreamReader(decompress));
line = bis.readLine();
while ((!line.equalsIgnoreCase("x"))) {
compress.write(line.getBytes(), 0, line.length());
System.out.println("Message sent: " + line);
System.out.println("Message returned:" +fromClient.readLine() );
line = bis.readLine();
}
bis.close();
fromClient.close();
socket.close();
}
}
Second Try Server Side:
OutputStream outstream = new FileOutputStream("compessserver.txt");
InflaterInputStream decompress = new InflaterInputStream(clientsocket.getInputStream());
BufferedReader fromClient = new BufferedReader(new InputStreamReader(decompress));
DeflaterOutputStream compress = new DeflaterOutputStream(clientsocket.getOutputStream());
while ((line = fromClient.readLine()) != null) {
String upperLine = line.toUpperCase();
System.out.println("Message received and converted: " + upperLine);
System.out.println();
upperLine = upperLine + "\n";
byte[] input = upperLine.getBytes();
outstream.write(input);
outstream.write("\r\n".getBytes());
compress.write(input);
System.out.println("Message returned : " + upperLine);
if (upperLine.equalsIgnoreCase("x")) {
break;
}
}
decompress.close();
fromClient.close();
outstream.close();
socket.close();
}
}

You can't use these streams interactively. You would have to call finish() after every write, or rather before every read, which means you could only do one write. They are designed for large one-way streams, not interactive request/response sessions.
In any case there is no advantage to be gained from compressing single lines. You need a lot of data for compression to start working.
NB compress.write(line.getBytes(), 0, line.length()) isn't valid. It assumes the number of chars in the String is the same as the number of bytes when converted, which isn't always so. It should be compress.write(line.getBytes(), 0, line.getBytes().length()), or more simply compress.write(line.getBytes()).

Related

While loop doesn't break after reading multiple line of text with BufferedReader in Java Socket

I have trying to send multiple lines of code from a client to the server.
Here is the code on the server side
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
//read client input
//multi line
//https://stackoverflow.com/questions/43416889/java-filereader-only-seems-to-be-reading-the-first-line-of-text-document?newreg=2f77b35c458846dbb1290afce8853930
String line = "";
while((line =in.readLine()) != null) {
System.out.println(line);
}
System.out.println("is it here?");
Here is the code on the client side :
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
while (true) {
System.out.print("> ");
//content server input command (put, lamport clock, message)
String command = keyboard.readLine();
if (command.equals("quit")){
break;
}
//read from CSDB/txt1.txt
String message = readFileReturnString("CSDB/txt1.txt", StandardCharsets.UTF_8);
System.out.println(message);
//send to clientHandler through PrintWriter
out.println(command + " 3 \n" + message);
//receive response from ClientHandler (lamport clock)
String serverResponse = input.readLine();
System.out.println(serverResponse + socket);
}
Server side is able to print out all the text that is sent from the client side. However, the while loop doesn't break and System.out.println("is it here?"); has never been executed.
May I know why and how I can solve this problem please?
Your Client is waiting for some response of the Server. But the Server does not send any response. The Server writes to the System.out only. The Server has to write the response with the out.
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
//read client input
//multi line
//https://stackoverflow.com/questions/43416889/java-filereader-only-seems-to-be-reading-the-first-line-of-text-document?newreg=2f77b35c458846dbb1290afce8853930
String line = "";
while((line =in.readLine()) != null) {
System.out.println(line);
out.println(line); // send Server response
}
System.out.println("is it here?");
# talex
Then you need to tell server when it should exit the loop. Yo may send special string or something.
This works fine.
String line = "";
while((line =in.readLine()) != null) {
System.out.println(line);
if (line.equals("break") {
break;
}
}

Error while sending large file over socket in java [duplicate]

I have stucked for 4h already with the sockets, the way I am using is is that there is only one application as client and server, once the client connect it is opening the theard with new client and waiting for message.
Once the message is send to the server, the client will receive respond, that part is working without any problems.
Part of the Client Theard:
while (true)
{
InputStreamReader IR = new InputStreamReader(clientSocket.getInputStream());
BufferedReader BR = new BufferedReader(IR);
PrintStream PS = new PrintStream(clientSocket.getOutputStream());
String message = BR.readLine();
if (message != null)
{
System.out.println(clientSocket.getInetAddress() + ":" + clientSocket.getPort() + " has connected."+message);
if (message.equals("exit"))
{
PS.println("Exiting...");
exit();
}
else if (message.equals("list"))
{
getList(PS);
}
else if ((message.contains("get") && (message.contains(",") && (message.contains(" ")))))
{
String[] spliter = message.split(" ");
String[] file = spliter[1].split(",");
String file_name = file[0];
String file_md5 = file[1];
getFile(file_name, file_md5, clientSocket);
}
}
else
{
break;
}
}
There are 2 messages that the server is supporting, the first one is "list" and the send one command is "get with values".
if client will request command "list" it will run this:
There is a "server/client", it is sending request and receive the one line string and it is working without any problem, I am receiving the list of files from the server.
PrintStream PS = new PrintStream(clientSocket.getOutputStream());
PS.println("list");
InputStreamReader IR = new InputStreamReader(clientSocket.getInputStream());
BufferedReader BR = new BufferedReader(IR);
String lista_plikow = BR.readLine();
if ( lista_plikow != null)
{
return lista_plikow;
}
But I have problems to send the files over the sockets using code found on stackoverflow, but the "receiving" is not working, there is my receive function, the loop is always as 0 (even if first bytes length is correct), but the length of the bytes is correct, it is using newly created file but nothing is happening, the file is always on use, and has 0 bytes instead of content of the PS.println.
PrintStream PS = new PrintStream(clientSocket.getOutputStream());
PS.println("get "+filename+","+file_md5);
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try
{
byte [] mybytearray = new byte [Integer.parseInt(size)];
InputStream is = clientSocket.getInputStream();
fos = new FileOutputStream(filename + ".recived");
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
System.out.println("X" + bytesRead);
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
System.out.println(bytesRead + " = " + current + " " + (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
System.out.println(bytesRead);
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
System.out.println("File " + "recived." +filename.replace(":", " ")
+ " downloaded (" + current + " bytes read)");
}catch (Exception e)
{
System.out.println(e.getMessage());
}
And last part of the scrip the "PS.println("get "+filename+","+file_md5);" is doing exactly this one, the sending is working fine:
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
String the_file = TorrentAppGui.folder+"\\"+file_name.replace(":", " ");
File myFile = new File (the_file);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = clientSocket.getOutputStream();
System.out.println("Sending " + the_file + "(" + mybytearray.length + " bytes)");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
System.out.println("Done.");
I have no idea why I cannot save the bytes received by the "get" command, do you have any ideas?
I know that only the "receve" function is not working, because if I looged to the application via telnet I could get the file in the console, but it doesnt reach my target. See the screen from cli.
You can't mixed buffered and unbuffered streams/readers/writers on the same socket. You will lose data in the buffers. Use the same stream pair for the life of the socket. In this case I would use DataInputStream and DataOutputStream, and the readUTF()/writeUTF() methods for the messages and filenames. You will also need to send the file length ahead of the file, unless the file is the last thing sent over the connection: otherwise the peer won't know when to stop reading the file and go back and start reading messages again.

Simple Client-Server: flushing not working before or after writing in the buffer

I sending strings to a server but the server get strange chars before the string i've send, I'v tried to flush before send, after send and after inicializating the outputstream variable but the result is the same.I Heard a lot about flush() and also search about it, but still didnt find how to solve my problem, maybe its simple but i cant get it.
please Help me!
Client Side
InetAddress endereco = InetAddress.getByName(null);
socket= new Socket(endereco, SServer.PORTO);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new ObjectOutputStream(socket.getOutputStream()),true);
while(true){
System.out.println("Write your Thoughs.. ");
Scanner scanner = new Scanner(System.in);
String Msg = scanner.nextLine();
System.out.println("I Said: ");
System.out.println(Msg);
out.println(Msg);
out.flush();
String s = in.readLine();
System.out.println("Echo: "+s);
}
//Serve Side
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.flush();
}
private void serve() throws IOException {
while(true){
String s = in.readLine();
System.out.println("Server Received: " + s);
if(s.equals("END"))
break;
System.out.println("Server Send: " + s);
out.println(s);
}
I think what is happening is that when you write your strings, you are pushing them through the ObjectOutputStream, which is attempting to serialize them (I think). You are making things more difficult than necessary. Try using
out = new PrintWriter(socket.getOutputStream());
That will just dump the text directly through the line without all the additional stuff.

java send firmware thru telnet

Hallo i an trying to send Firmware file to modem board thru telnet.
Here is my code:
Socket s = null;
try {
SocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName(addr), 23);
s = new Socket();
s.connect(socketAddress, 1000);
InputStream inputStream = s.getInputStream();
OutputStream outputStream = s.getOutputStream();
outputStream.write( (login + "\n") .getBytes());
Thread.sleep(300);
outputStream.write( (password + "\n") .getBytes());
Thread.sleep(300);
outputStream.write(("swupdate" + "\n").getBytes());
Thread.sleep(300);
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(path_frm_vdsl);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
// Read File Line By Line
while ((line = br.readLine()) != null) {
// Print the content on the console
line = br.readLine();
if (line == null) {
Thread.sleep(1000);
} else {
//System.out.println(line);
outputStream.write(line.getBytes());
Log.v("---", line.getBytes() + "" + consumeInput(500, inputStream));
//Log.v("Update_Modem","Updated " + consumeInput(500, inputStream));
//outputStream.write(line.getBytes());
Thread.sleep(10);
}
}
It simply logs in sends swupdate command and dumps firmware file to output. After first line of input i am having java.net.SocketException: Broken pipe
And i can not read all file at once, not enough memory exception. (3Mb)
You know telnet uses in-channel signalling? the data stream contains escaped command instructions. When you open a telnet connection, a whole slew of initial commands are passed back and forth, as the server and client determine each others capabilities and preferences.
You may well find your byte stream is corrupted, if you just take whatever you get turning up at the server. You will need to honour the telnet protocol, e.g. properly understand the byte stream you're receiving.
The line terminator in the Telnet protcol is \r\n.
But why would you want to read the whole file into memory? And why all the sleeps? And why are you skipping every second line? And what is consumeInput()?
Just read and write bytes.
Not sure how your receiving end wants the firmware, plain binary, hex encoded, base64 encoded?
Anyway, here is how you would send it in plain binary
Socket s = null;
try {
SocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName(addr), 23);
s = new Socket();
s.connect(socketAddress, 1000);
InputStream inputStream = s.getInputStream();
OutputStream outputStream = s.getOutputStream();
outputStream.write((login + "\n").getBytes());
Thread.sleep(300);
outputStream.write((password + "\n").getBytes());
Thread.sleep(300);
outputStream.write(("swupdate" + "\n").getBytes());
Thread.sleep(300);
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(path_frm_vdsl);
byte[] buffer = new byte[1024];
int fillSize;
// Read File chunk by chunk
while ((fillSize = fstream.read(buffer)) != -1) {
outputStream.write(buffer, 0, fillSize);
}
outputStream.close();
} finally {
s.close();
}
So, read the file in chunks until there is no more data (read returns -1) and write the chunk (read returns how much was actually read).

how to find size of HTML file and data transfer rate

I want to find the size of an HTML file without HTTP headers and data transfer rate. Below is my code;
import java.net.*;
import java.io.*;
public class HttpCon
{
public static void main ( String[] args ) throws IOException
{
Socket s = null;
try
{
String host = "host1";
String file = "file1";
int port = 80;
s = new Socket(host, port);
OutputStream out = s.getOutputStream();
PrintWriter outw = new PrintWriter(out, false);
outw.print("GET " + file + " HTTP/1.1\r\n");
outw.print("Host: " + host + ":" + port + "\r\n");
outw.print("Accept: text/plain, text/html, text/*\r\n");
outw.print("\r\n");
outw.flush();
InputStream in = s.getInputStream();
InputStreamReader inr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(inr);
String line;
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
br.close();
}
}
}
But I do not have any idea how to do this. Is there a source code that I can look at or any resource that I can apply?
Any help will be appreciated, thanks in advance.
What you are asking for shouldn't be much of a problem. Read the lines until you read an empty line -- that's where the headers end. After that just go on reading and count all the characters you have read and that's your file size. As for transfer rate:
final long start = System.nanoTime();
long charsRead = 0;
... do the transfer, counting chars ...
System.out.println("Transfer rate: " +
(charsRead / (1e-6 * (System.nanoTime() - start))));
The only problem here will be that you are using a BufferedReader so you count chars and not bytes. If you need bytes, then you'll need to use the raw InputStream and then it's going to be a slight pain in the butt to find where the headers end. You can get around that (probably) by using not the BufferedReader but the InputStreamReader, which will not read-ahead anything. When you find the end of headers, switch to the raw InputStream to read the response body.

Categories