Java socket - the server response is always null - java

I have to connect with a server (I don´t have access to the server code) but the transmission protocol (Socket) is:
(client) --> data
ack <-- (server)
data response <-- (server)
(client) --> ack
It's assumed that the server should always respond quickly. I connect to the server, I send the data but the response is NULL and if I debug my code, an exception occurs when I catch the response:
"java.net.SocketException: Software caused connection abort: recv failed"
My code:
public static void main(String[] args){
try{
String order = "datahere";
String responseServer;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket();
InetSocketAddress sa = new InetSocketAddress("XXX.XX.XX.XX", 9300);
clientSocket.connect(sa,500);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(order);
responseServer = inFromServer.readLine();//exception if I try to debug my code
System.out.println("From server: " + responseServer); //responseServer is NULL
clientSocket.close();
} catch (IOException ex) {
System.out.println("Error: "+ex);
}
}
That's wrong? Any idea?
I tried to disable the firewall and also add a rule for the port 9300 but the result is the same.
The client gave me an example code in Vb.Net that it's supposed to work and I try to replicate it in Java.
Code in Vb.Net:
Dim message As String = "datahere";
Try
Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)
Dim client As New TcpClient(ip, port)
Dim stream As NetworkStream = client.GetStream()
stream.Write(data, 0, data.Length)
data = New [Byte](2048) {}
Dim responseData As [String] = [String].Empty
Dim bytes As Integer = stream.Read(data, 0, data.Length)
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
stream.Close()
client.Close()
Catch ex As Exception
End Try
SOLUTION:
Socket clientSocket = new Socket();
InetSocketAddress sa = new InetSocketAddress("XXX.XX.XX.XX", 9300);
clientSocket.connect(sa,500);
clientSocket.getOutputStream().write(order.getBytes("ASCII"));
byte[] data = new byte[2048];
int bytes = clientSocket.getInputStream().read(data, 0, data.length);
String responseData = new String(data, 0, bytes, "ASCII");
System.out.println("From server: " + responseData);
//Another way to catch the response:
//InputStreamReader in = new InputStreamReader(clientSocket.getInputStream());
//int data1 = in.read();
//while(data1 != -1) {
// System.out.print((char) data1);
// data1 = in.read();
//}
clientSocket.close();

Here is a translation of your VB code in java
public static void main(String[] args) throws IOException {
String order = "datahere";
// Try-with-resource statement will close your socket automatically
try (Socket clientSocket = new Socket("XXX.XX.XX.XX", 9300)) {
// Send to the sever the order encoded in ASCII
clientSocket.getOutputStream().write(order.getBytes("ASCII"));
// Sleep until we have bytes to read available
while (clientSocket.getInputStream().available() == 0) {
Thread.sleep(100L);
}
// Create the buffer of exactly the amount of bytes available without blocking
byte[] data = new byte[clientSocket.getInputStream().available()];
// Read the bytes from the server and put it into the buffer
int bytes = clientSocket.getInputStream().read(data, 0, data.length);
// Decode what has been read from the server that was encoded in ASCII
String responseData = new String(data, 0, bytes, "ASCII");
System.out.println("From server: " + responseData);
}
}

DataInputStream dis = new DataInputStream( new InputStreamReader(clientSocket.getInputStream()));
while(dis.available()>0){
//reads characters encoded with modified UTF-8
String temp = dis.readUTF();
System.out.print(temp+" ");
}
try to use a dataInputStream instead of bufferedReader and use readUTF() method in dataInputStream to read UTF characters.

Related

Socket intermittently reads only 1448/2896 bytes

I am using Commons-IO to read and write from Socket. Things all works till payload size is either 1448/2896 max.
Below is the code snippet. Really unsure how to handle it.
Checked system buffer size too
$ cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
public static void usingCommonsIO(){
Socket socket = null;
try {
socket = new Socket(serverIP, 55000);
IOUtils.write(request.getBytes(), socket.getOutputStream());
System.out.println("Message Sent....");
StringBuilder response = new StringBuilder();
String resp =IOUtils.toString(socket.getInputStream(), "UTF-8");
System.out.println(resp);
} catch (IOException e) {
e.printStackTrace();
}
}
Alternatively tried using DataInputStream but no luck. Code snipped is below.
public static void usingDataIOStream(String requestStr){
Socket socket = null;
try {
socket = new Socket("192.168.1.6", 55000);
System.out.println("Request Length -:" + request.length());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.write(requestStr.getBytes("UTF-8"), 0, requestStr.length());
out.flush();
System.out.println("Message Sent....");
DataInputStream din = new DataInputStream(socket.getInputStream());
byte[] response = new byte[16*1024];
int responseLength = din.read(response);
System.out.println("Response -:" + new java.lang.String(response, 0, responseLength));
} catch (IOException e) {
e.printStackTrace();
}
}
Confusing part is that the same code works with only 1448 bytes sometimes and max of 2896 bytes sometimes. There are no specific patterns.
Update 1
To simulate it, tried writing Server socket on my own and code is as below. Strange thing noticed with this is, on first request payload of size 6500 was read and received properly. Connection Reset from second request onwards. Am I missing something here?
public static void usingBAOS() throws IOException {
server = new ServerSocket(port);
Socket socket = null;
DataInputStream din = null;
DataOutputStream dos = null;
while (true) {
System.out.println("Waiting for Client...");
try {
// Accepting Client's connection
socket = server.accept();
System.out.println("Connnected to client " + socket.getInetAddress());
din = new DataInputStream(socket.getInputStream());
// Read request payload from Socket
String requestString = readRequest(din);
System.out.println("Request Read.....");
System.out.println("Writing Response.....");
// Writing response to socket
dos = writeResponse(socket, requestString);
} catch (IOException e) {
e.printStackTrace();
}finally {
//close resources
din.close();
System.out.println("InputStream is closed......");
dos.close();
System.out.println("OutputStream is closed......");
socket.close();
System.out.println("Socket is closed......");
}
}
}
private static DataOutputStream writeResponse(Socket socket, String requestString) throws IOException {
String responseString = "Hi Client" + requestString;
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//write object to Socket
dos.write(responseString.getBytes(),0, responseString.getBytes().length);
dos.flush();
return dos;
}
private static String readRequest(DataInputStream din) throws IOException {
byte[] response = new byte[16*1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int n = 0;
boolean read = true;
while(read){
n = din.read(response);
baos.write(response, 0, n);
if(baos.toString().length() == n){
read = false;
}
}
baos.flush();
String requestString = baos.toString();
return requestString;
}
Although this question is old at the time of writing this answer I'm putting this here for others in case it solves their problem. I encountered the same issue when using buffered data input and output streams on Android 8.0 devices where I had naively assumed that doing this:
int len = 2304;
byte[] data = new byte[len];
inputStream.read(data, 0, len);
would read all the data I sent down the socket. But as suggested by #Kayaman in the comments, this does not guarantee that len bytes of data are actually read from the buffer even if there are bytes available. In fact, this is in the documentation:
public final int read(byte[] b, int off, int len) throws IOException
Reads up to len bytes of data from the contained input stream into an array of bytes. An attempt is made to read as many as len bytes, but a smaller number may be read, possibly zero. The number of bytes actually read is returned as an integer.
In fact, if it doesn't read all the data, the only way to tell is to capture the returned value. My solution was then to monitor the amount of bytes actually read from the stream and just call read() in a loop as:
int i = 0;
len = 2304;
byte[] data = new byte[len];
while (i < len)
{
i += socket.inputStream.read(data, i, len - i);
}
Hope this helps someone.

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! :)

JAVA Server receiving whitespace

I'm trying to receive data from a client (the data sent with unknown format).
the data that I'm receiving has a lot of white spaces for example:
the client send the number 1.50 I get in the server 1 . 5 0,
how can I convert it to normal double back?
int port = 1245;
ServerSocket serverSocket = new ServerSocket(port);
try {
while(true)
{
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
console.getOut().println(number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
}
}
catch(Exception e) {
console.getOut().println("Whoops! It didn't work!\n");
}
}
catch(Exception e) {
console.getOut().println("Whoops! It didn't work!\n");
}

android thread stops with unknown cause

I'm communicating Android Device - PC with TCP Sockets. I sent network packets to the server succesfully but when I try to get response from the server, The thread stops I don't know cause.
Android Client :
public class ClientThread implements Runnable
{
public void run()
{
try
{
Socket socket = new Socket("192.168.1.12", 4444);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
out.write(msg);
out.flush();
Log.v("Naber", "One");
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // get the client message
String inMsg = bufferedReader.readLine();
inputStreamReader.close();
Log.v("Naber", "Two");
socket.close();
}
catch (Exception e)
{
Log.v("Hata", e.getMessage());
}
}
}
Log Verbose Output :
09-25 22:25:37.163 15351-15532/com.mytracia.kumanda9 V/Naber﹕ One
I don't know why does it stops when it came to this line :
String inMsg = bufferedReader.readLine();
My Server Application with C#
static void Main(string[] args)
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 4444);
while (true)
{
tcpListener.Start();
//Program blocks on Accept() until a client connects.
Socket soTcp = tcpListener.AcceptSocket();
Byte[] received = new Byte[1024];
int bytesReceived = soTcp.Receive(received, received.Length, 0);
String dataReceived = System.Text.Encoding.ASCII.GetString(received);
dataReceived = dataReceived.Replace("\0", "");
Console.WriteLine(dataReceived);
String returningString = "Naber1";
Byte[] returningByte = System.Text.Encoding.ASCII.GetBytes(returningString.ToCharArray());
//Returning a confirmation string back to the client.
soTcp.Send(returningByte, returningByte.Length, 0);
tcpListener.Stop();
}
}
Server answer with new line? "\n"
public String readLine () Added in API level 1 Returns the next line
of text available from this reader. A line is represented by zero or
more characters followed by '\n', '\r', "\r\n" or the end of the
reader. The string does not include the newline sequence.
Returns the contents of the line or null if no characters were read
before the end of the reader has been reached.
Try:
String returningString = "Naber1\n";

How to receive plain Text through Socket in Java

I was trying to send plain text through Socket. So I found a post in StackOverflow, I followed it and I guess it that I did it write However, How can I accept that plain text as string in the client?
I used BufferedReader() and InputStreamReader() class, but exception has been thrown.
Exception : exception java.net.SocketException: Broken pipe
Here is the code:
Server:
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
osw.write(fileName, 0, fileName.length());
Client:
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
br.close();
Some help would be great. :) Thank you.
Client side code:
public void soc_client() throws Exception {
long time = System.currentTimeMillis();
long totalRecieved = 0;
try {
Socket sock = new Socket("172.16.27.106", 55000);
System.out.println("Hello Client");
InputStream in = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
File outputFile = new File(fileName + "");
br.close(); // CLOSING BufferedReader
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[100 * 1024];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
totalRecieved += bytesRead;
System.out.println("Recieved " + (totalRecieved / 1024)
+ " kilobytes in "
+ ((System.currentTimeMillis() - time) / 1000)
+ " seconds");
}
fileOutputStream.close();
sock.close();
} catch (Exception e) {
System.out.println("Exception " + e);
} finally {
System.out.println("Recieved " + totalRecieved + " bytes in "
+ (System.currentTimeMillis() - time) + "ms.");
}
}
You're reading a line but you aren't sending a line, and you aren't closing the OutputWriter either. So readLine() will block forever waiting for a line terminator or an EOS that is never coming.
Add a newline to the message.
Close the OutputWriter.
Well to use sockets to send and transfer text in client server fashion , i'm posting a simple basic code , which upon running send a HELLO WORLD response to client.
//Server Side
ServerSocket server= new ServerSocket(1166); // //1166 -port no. u can use any other too.
Socket s= server.accept(); // makes a connection whenever a client requests.
OutputStream os= socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("Hello World");
dos.close();
// Client Side
Socket socket= new Socket("Ip address of you server" , 1166) ;
InputStream is= new InputStream();
DataInputStream dis = new DataInputStream(is);
String msg=dis.readUTF();
System.out.println(msg);
dis.close();
now after you run the code once on server computer , then run the client side code and the server will now respond you with Hello World.

Categories

Resources