BufferedReader doesn't read from tcp server - java

So I have this really strange bug in my android app. I'm trying to connect to a TCP server, and trade some messages, nothing complex, really. I've managed to surpass all the problems it had in the beginning, but now I'm stuck on a bug for which I hope someone knows how to fix.
I connect to the server and get the input and output stream successfully, but then, when reading the response from the server, the program freezes. I've researched this and I know that it's because there's no message from the server. But I also know that the server responds, since I've made the same app for iOS and it received everything alright. Can it be some android problem? or maybe just some setting in the system?
Here's a snippet of the code, showing you that this isn't a big deal. I don't much more stuff in the code, but if you need to look at the rest of it please ask.
Thanks in advance!
try {
InetAddress serverAddr = InetAddress.getByName(serverIP);
tcpSocket = new Socket(serverAddr, serverPort);
Log.e("socket",
"created socket with " + serverIP
+ Integer.toString(serverPort));
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(tcpSocket.getOutputStream())),
true);
Log.e("socket", "output stream created alright");
in = new BufferedReader(new InputStreamReader(
tcpSocket.getInputStream()));
Log.e("socket", "input stream created alright");
out.println("handheld#" + clientID + "#connection request");
fromServer = in.read();
while(fromServer != -1) {
fromServer = in.read(); //updated, still no good
}
connected = true;
Log.e("socket", "connect thread will finnish");
} catch (UnknownHostException e) {
Log.e("socket", "error finding host", e);
} catch (IOException e) {
Log.e("socket", "error creating socket's streams", e);
}

Hope below code work fine
InputStream in = tcpSocket.getInputStream();
if(in == null)
return null;
Log.e("socket", "input stream created alright");
out.println("handheld#" + "1111" + "#connection request");
byte[] buff = new byte[1024];
int read = -1;
long totalRead = 0;
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
Log.i("readed Byte ", new String(buff));
totalRead += read;
if (totalRead % 100 * 1024 == 0)
{
System.out.printf("%d bytes read\n", totalRead);
}
}
i have implemented in my sample which read successfully from inputstream.

Related

Domain fronting proxy in Java, won't get "pull method" proxy to work

I'm currently working on a project that uses a technique called "domain fronting". In short: it send internet traffic to a CDN (in this case Google) over an encrypted connection, and the CDN then passes back this info to the proxy. This way you can circumvent censorship (as long a the CDN isn't blocked), because the real destination is unknown to a observer. (To read more about domain fronting, here is the original paper) A number of applications like Signal and Tor already use this technique, but there isn't a general use proxy that just proxies a tcp socket through Google to the other end. I decided to go work on that and it's almost finished: the HTTP encoding part and the code at Google's servers is working. The only problem is the real proxying part.
This is the structure of the proxy:
source-->client proxy-->[Google]-->server proxy-->destination
The difference with a general proxy is that HTTP is a request based protocol and thus can't do the asynchronous things normal proxies do. My setup is to make a request from the client once in 100ms to the server sending the bytes the client received to the server. The server reads the bytes from the destination and sends them back to the client. Than the server and client both write their received bytes to the original sockets and another roundtrip starts in 100ms.
Here is my code to this point (I only pasted the relevant part, this code is not domain fronting yet):
Client:
try {
ServerSocket serverSocket = new ServerSocket(8082);
System.out.println("client proxy is listening for connections");
Socket source = serverSocket.accept();
BufferedReader sourceIn = new BufferedReader(new InputStreamReader(source.getInputStream()));
PrintWriter sourceOut = new PrintWriter(source.getOutputStream(), false);
while(true) {
Socket server = new Socket("localhost", 8081);
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out = new PrintWriter(server.getOutputStream(), false);
//read what the source has for the server
System.out.println("start reading source socket");
System.out.println("available: " + source.getInputStream().available());
char[] buffer = new char[15000];
int bytesRead = 0;
if(source.getInputStream().available() != 0) {
bytesRead = sourceIn.read(buffer);
byte[] bytesToSend = new byte[bytesRead];
bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
out.print((byte) 1);
out.print(bytesToSend);
out.flush();
System.out.println("Sent to server: " + new String(bytesToSend) + " bytesRead: " + bytesRead);
} else {
out.print((byte) 0);
out.flush();
System.out.println("Sent to server: nothing");
}
//read what the server has for the source
buffer = new char[15000];
bytesRead = 0;
while((bytesRead = in.read(buffer)) == -1) {
System.out.println("didn't receive any bytes from server");
Thread.sleep(20);
}
byte[] bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
if(bytesToSend[0] == '1') {
sourceOut.print(bytesToSend);
sourceOut.flush();
System.out.println("Sent to source: " + new String(bytesToSend));
} else {
System.out.println("Server has nothing for source; bytesToSend: " + new String(bytesToSend));
}
in.close();
out.close();
server.close();
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
Server:
try {
Socket destination = new Socket("192.168.0.150", 22);
BufferedReader destinationIn = new BufferedReader(new InputStreamReader(destination.getInputStream()));
PrintWriter destinationOut = new PrintWriter(destination.getOutputStream(), false);
ServerSocket server = new ServerSocket(8081);
while(true) {
Socket clientSocket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), false);
System.out.println("received new connection from client");
//read what client has for destination
char[] buffer = new char[15000];
int bytesRead = 0;
while((bytesRead = in.read(buffer)) == -1) {
System.out.println("didn't receive any bytes from client");
Thread.sleep(20);
}
byte[] bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
if(bytesToSend[0] == (byte) 1) {
destinationOut.print(bytesToSend);
destinationOut.flush();
System.out.println("Sent to destination: " + new String(bytesToSend));
} else {
System.out.println("Client has nothing for destination");
}
//read what distination has for client
System.out.println("start reading destination socket");
System.out.println("available: " + destination.getInputStream().available());
buffer = new char[15000];
if(destination.getInputStream().available() != 0) {
bytesRead = destinationIn.read(buffer);
bytesToSend = new byte[bytesRead];
bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
out.print("1");
out.print(new String(bytesToSend));
out.flush();
System.out.println("Sent to client: " + new String(bytesToSend) + " bytesRead: " + bytesRead);
} else {
out.print((byte) 0);
out.flush();
System.out.println("Sent to client: nothing");
}
out.close();
in.close();
clientSocket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
When I run this code to connect to a SSH server, the SSH client freezes and it seems like the proxy server doesn't respond to the proxy client anymore.
I really hope someone can help me with this, if you need extra info, just let me know! :)

UDP File Transfer Java

I know UDP is not reliable and should not be used to send files but I have been asked to do that inside of a small part of an application for a small college assignment. For some reason my application freezes when I run the code to upload a file from client to server. Could anyone please help tell me what I'm doing wrong?
Client:
String hostName = hostNameTxt.getText();
String portAsString = portNumTxt.getText();
int portNum = Integer.parseInt(portAsString);
String sentFilePath = "c:/Documents/test.txt";
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(portNum);
while (true) {
System.out.println("Waiting...");
try {
sock = servsock.accept(); //failing here I think
System.out.println("Accepted connection : " + sock);
// send file
File myFile = new File (sentFilePath);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
System.out.println("Sending " + sentFilePath + "(" + mybytearray.length + " bytes)");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Done.");
}
finally {
if (bis != null) bis.close();
if (os != null) os.close();
if (sock!=null) sock.close();
}
}
}
catch (IOException ex) {
Logger.getLogger(Client1Interface.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex);
} finally {
if (servsock != null) try {
servsock.close();
} catch (IOException ex) {
Logger.getLogger(Client1Interface.class.getName()).log(Level.SEVERE, null, ex);
}
}
Server:
String recievedFilePath = "c:/Documents/source.txt";
String hostName = "localhost";
int portNum = 7;
int fileSize = 6022386;
try{
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(hostName, portNum);
System.out.println("Connecting...");
// receive file
byte [] mybytearray = new byte [fileSize];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(recievedFilePath);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
System.out.println("File " + recievedFilePath
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
if (sock != null) sock.close();
}
}
catch(Exception ex){
ex.printStackTrace( );
System.out.println("Error Uploading File");
}
You should try to use another port. The IP port 7 is blocked for the echo service, which will simply send you the same data back.
You should use ports above 1024. Otherwise you need superuser right from you OS to use this port.
The naming of you app is a little bit confusing. Normally the server should provide a ServerSocket on a not already used port and listen. The client must connect with a regular Socket to this port and send the data.
I've been testing your program (both server and client running in the same host), and it works. Still, I've to warn you about some important details (basically all of them have been already told in comments):
Conceptual details
The APIs chosen (java.net.Socket and java.net.ServerSocket) are TCP socket implementations, and not UDP. The UPD APIs are java.net.DatagramSocket and java.net.DatagramPacket.
The first program is no doubt the server, and the second is the client.
Technical details
You have to start first the server, and then, the client.
Server and client must run on different JVMs, so you have to run each one on a different process, either in a command shell or either by running it from your IDE.
(as Lars Repenning said) You have to use any available port over 1024, for example 3000.
Minor technical details
Do not allocate a buffer as big as the file size. To write the data out to a File, you should use the buffering technique: Use a small buffer (4096 bytes or multiple) and on each iteration, fill it with InputStream.read and write it with OutputStream.write. You will avoid memory problems and also will save yourself the need to know a priori the file size.

Client Server EOF Error

My application communicates between a server and a client using DataInputStream and DataOutputStream. The client will be requests from a website to my application, so I created a test client to test input that could come from the website.
The method I decided to use would be that the client would send an integer first deciding the size of the data to be sent and then it would send the data. So, I was testing this method and it worked for the first string of data, but not the second and gave me an EOF error on the second try. I understand why it gave me an EOF because the client closed the connection, but I still have not read the incoming bytes, so the stream should still have more to read from.
Client Code:
Socket socket = new Socket("127.0.0.1", 9000);
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
os.writeInt("Test String".length());
os.write("Test String".getBytes());
os.flush();
os.writeInt("String".length());
os.write("String".getBytes());
os.flush();
os.close();
socket.close();
Server Code:
byte[] data;
try{
DataInputStream input = new DataInputStream(client.getInputStream());
DataOutputStream output = new DataOutputStream(client.getOutputStream());
client.setSoTimeout(SOCKET_TIMEOUT);
logger.log(Level.INFO, "Client connected with IP: " + client.getInetAddress());
data = readNextPacket(input);
if(!(new String(data).contains(PROTOCOL_HEADER)))
throw new IOException("Invalid request from client.");
else
logger.log(Level.INFO, "Valid header: " + new String(data));
data = readNextPacket(input);
logger.log(Level.INFO, new String(data));
}catch(IOException e){
logger.log(Level.SEVERE, e.getMessage(), e);
}finally{
try {
client.close();
} catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
logger.log(Level.INFO, "FINISHED");
}
readNextPacket Method:
private byte[] readNextPacket(DataInputStream stream) throws IOException{
int bytesToRead = stream.readInt();
ByteArrayOutputStream os = new ByteArrayOutputStream();
if(bytesToRead <= MAX_BYTES){
byte[] data = new byte[bytesToRead];
while(stream.read(data) != -1 && os.size() < bytesToRead){
os.write(data);
}
}
return os.toByteArray();
}
Stack Trace:
java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at com.schmidt73.bidwriter.handlers.SocketHandler.readNextPacket(SocketHandler.java:1)
at com.schmidt73.bidwriter.handlers.SocketHandler.parse(SocketHandler.java:16)
at com.schmidt73.bidwriter.handlers.SocketHandler.start(SocketHandler.java:43)
at com.schmidt73.bidwriter.BidWriter.main(BidWriter.java:21)
Okay, so basically my readNextPacket() method would read more data than specified if the entire buffer wasn't read the first time. So, I changed some of the code to fix it by adding an offset and subtracting the amount I've already read to the read() method. However, I realized that would be basically copying the readFully() method and there is no reason to do that, so I just implemented that into the readNextPacket() method.
Here is the new working code:
private byte[] readNextPacket(DataInputStream stream) throws IOException{
int bytesToRead = stream.readInt();
byte[] data = new byte[bytesToRead];
stream.readFully(data);
return data;
}

Sending picture over a socket (Java PC - Android)

I'm new to Java so I need help please. I'm writing an application that will onClick send a String to Server and Server needs to return an image using socket. So my client side is Android and server side is PC - java.
I think that my server side is ok (because he prints out all the system.out.print commands) but my client side is not good. Please tell my where is my mistake? Thanks!
Here is code of my Server (PC) side (socket is delivered thru function parameter):
try {
dataInputStream = new DataInputStream(socket.getInputStream());
poruka = "" + dataInputStream.readUTF();
System.out.print(poruka);
int bytecount = 2048;
byte[] buf = new byte[bytecount];
OutputStream OUT = socket.getOutputStream();
BufferedOutputStream BuffOUT = new BufferedOutputStream(OUT, bytecount);
FileInputStream in = new FileInputStream("screenShot.jpg");
int i = 0;
while ((i = in.read(buf, 0, bytecount)) != -1) {
BuffOUT.write(buf, 0, i);
System.out.print("check" + buf[0]);
BuffOUT.flush();
}
in.close();
BuffOUT.close();
System.out.print("over");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
socket.close();
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and here is my Client (Android) side:
Socket socket = null;
DataOutputStream dataOutputStream = null;
try {
socket = new Socket(IPadresa, 8888);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
slanje = "hy string";
dataOutputStream.writeUTF(slanje);
FileOutputStream outToFile = new FileOutputStream("slika.jpg");
int bytecount = 2048;
byte[] buf = new byte[bytecount];
InputStream IN = socket.getInputStream();
BufferedInputStream BuffIN = new BufferedInputStream(IN, bytecount)
int i = 0;
int filelength = 0;
while((i = BuffIN.read(buf, 0, bytecount)) != -1) {
filelength += i;
outToFile.write(buf, 0, i);
outToFile.flush();
}
IN.close();
BuffIN.close();
dataOutputStream.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
MORE INFORMATIONS:
In server side I can see String that is send from Client. And I have that System.out.print("over"); command printed every time I send String to Server. Also I have System.out.print("check" + buf[0]); printed out from Server many times. So that is why I think that there is something wrong with Client side.
And my Client side doesn't throw any Exceptions... but I noticed that Client side never passed the while loop. It get stuck there.
I don't know what you mean by "my client side is not good", and I can't see any obvious errors that would stop it working entirely. If you could tell us what happens, that would help.
Meanwhile there are a couple of things wrong with the code you have presented:
You are violating industry accepted coding standards with names such as "BuffIn", "IN", "IPaddresa" and so on. All variable names in Java must start with a lowercase letter.
If you do this in private code that is your business. But if you are going to show your Java code to other people, you should conform to the standards. (And posting your code on SO is showing it to other people ...)
Since you are always trying to read a whole buffer's worth of data, replace in.read(buf, 0, bytecount) with in.read(buf).
There is no value in using a BufferedInputStream or BufferedOutputStream if you are only going to do large read or write calls on it. Even more so if you tell the stream to use the same size buffer as your the byte[] you are reading / writing.
Both your client and server side code could leak file descriptors. On the server-side it could leak in. On the client side, any or all of the streams' file descriptors could leak.

Java Android Sockets

I'm currently working on an Android app which sends an string and a file to a java server app running on remote computer. This java server app should find the index on the file and send back the value of this index (The file structure is: index value. Example: 1 blue) The file is properly sent and received on the remote machine and I have a method which finds the value of the received index on the file. But when I'm trying to send the found value back to the phone I get an exception (closed socket), but I'm not closing the socket or any buffer. I'm not sure if the socket which is closed is the mobile app socket or the java server app socket. I'm using the same socket I use to send to receive (which is the way to work on Android). Sending the answer back to the phone is what my project is missing and is what I need help in. Here is my code:
Client app (Android app):
private class HeavyRemProcessing extends AsyncTask<String, Void, String>
{
protected String doInBackground(String... urls)
{
begins = System.currentTimeMillis();
remoteExecution();
ends= System.currentTimeMillis();
procTime=ends-begins;
aux= Long.toString(procTime);
return aux;
} //doInBackground() ends
protected void onPostExecute(String time)
{
textView1.setText("Result: "+result+". Processing Time: "+time+" milisecs");
}// onPostExecute ends
} //HeavyRemProcessing ends
public void executor(View view)
{
key="74FWEJ48DX4ZX8LQ";
HeavyRemProcessing task = new HeavyRemProcessing();
task.execute(new String[] { "????" });
} //executor() ends
public void remoteExecution()
{
// I have fixed IP and port I just deleted
String ip; //SERVER IP
int port; // SERVER PORT
try
{
cliSock = new Socket(ip, port);
file= new File("/mnt/sdcard/download/Test.txt");
long length = file.length();
byte[] bytes = new byte[(int) length];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(cliSock.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(cliSock.getInputStream()));
int count;
key=key+"\r\n";
out.write(key.getBytes());
while ((count = bis.read(bytes)) > 0)
{
out.write(bytes, 0, count);
} //It works perfectly until here
//// PROBABLY HERE IS THE PROBLEM:
out.flush();
out.close();
fis.close();
bis.close();
result= in.readLine(); //RECEIVE A STRING FROM THE REMOTE PC
}catch(IOException ioe)
{
// Toast.makeText(getApplicationContext(),ioe.toString() + ioe.getMessage(),Toast.LENGTH_SHORT).show();
}
}catch(Exception exp)
{
//Toast.makeText(getApplicationContext(),exp.toString() + exp.getMessage(),Toast.LENGTH_SHORT).show();
}
} //remoteExecution ends
Java Server App (Remote PC)
public void receivingFile()
{
System.out.println("Executing Heavy Processing Thread (Port 8888).");
try
{
serverSocket = new ServerSocket(8888);
InputStream is = null;
OutputStream os= null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
BufferedOutputStream boSock =null;
DataOutputStream dataOutputStream=null;
int bufferSize = 0;
try
{
socket = serverSocket.accept();
System.out.println("Heavy Processing Task Connection from ip: " + socket.getInetAddress());
} catch (Exception ex)
{
System.out.println("Can't accept client connection: "+ex);
}
try
{
is = socket.getInputStream();
dataOutputStream = new DataOutputStream(socket.getOutputStream());
bufferSize = socket.getReceiveBufferSize();
}
catch (IOException ex)
{
System.out.println("Can't get socket input stream. ");
}
try
{
fos = new FileOutputStream(path);
bos = new BufferedOutputStream(fos);
}
catch (FileNotFoundException ex)
{
System.out.println("File not found. ");
}
byte[] bytes = new byte[bufferSize];
int count;
System.out.println("Receiving Transfer File!.");
while ((count = is.read(bytes)) > 0)
{
bos.write(bytes, 0, count);
}
System.out.println("File Successfully Received!.");
fos.close();
bos.flush();
bos.close();
is.close();
result= obj.searchIndex();
System.out.println("Found: "+result); //This correctly print the found value
dataOutputStream.writeUTF(result);
dataOutputStream.flush();
dataOutputStream.close();
System.out.println("Data sent back to the Android Client. ");
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} // receivingFile() ends
Please if someone can help me I will really appreciate it. I'm thinking is something probably related with the buffers and the socket. My java server app throws an exception: "Closed Socket"... Thanks for your time,
Alberto.
I think your problem is that you closing the outputstream before closing the inputstream. This is a bug in android. Normally in java closing outputstream only flushes the data and closing inputstream causes the connection to be closed. But in android closing the outputstream closes the connection. That is why you are getting closed socket exception,
Put the statements
out.flush();
out.close();
after
result=in.readLine();
or just avoid those statements(out.flush and out.close). I had also faced a similar problem. See my question

Categories

Resources