Sending a JSON object over TCP with Java - java

I'm trying to replace a Netcat command that I'm running in my terminal that will reset some data on a server. The netcat command looks like this:
echo '{"id":1, "method":"object.deleteAll", "params":["subscriber"]} ' | nc x.x.x.x 3994
I've been trying to implement it in Java since I would like to be able to call this command from an application I'm developing. I'm having issues with it though, the command is never executed on the server.
This is my java code:
try {
Socket socket = new Socket("x.x.x.x", 3994);
String string = "{\"id\":1,\"method\":\"object.deleteAll\",\"params\":[\"subscriber\"]}";
DataInputStream is = new DataInputStream(socket.getInputStream());
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
os.write(string.getBytes());
os.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
The code also hangs on the while loop that should read the InputStream, I have no idea why. I've been using Wireshark to capture the packets and the data that is going out looks the same:
{"id":1,"method":"object.deleteAll","params":["subscriber"]}
Perhaps the rest of the packets are not shaped in the same way but I really can't understand why that would be. Perhaps I am writing the string in a faulty way to the OutputStream? I have no idea :(
Note that I posted a question similar to this yesterday when I didn't properly understand the problem:
Can't post JSON to server with HTTP Client in Java
EDIT:
These are the possible results I get from running the nc command, I would expect to get the same messages to the InputStream if the OutputStream sends correct data in a correct way:
Wrong arguments:
{"id":1,"error":{"code":-32602,"message":"Invalid entity type: subscribe"}}
Ok, successful:
{"id":1,"result":100}
Nothing to delete:
{"id":1,"result":0}
Wow, I really had no idea. I experimented with some different Writers like "buffered writer" and "print writer" and it seems the PrintWriter was the solution. Although I couldn't use the PrintWriter.write() nor the PrintWriter.print() methods. I had to use PrintWriter.println().
If someone has the answer to why other writers wouldn't work and explain how they would impact the data sent to the server I will gladly accept that as the solution.
try {
Socket socket = new Socket(InetAddress.getByName("x.x.x.x"), 3994);
String string = "{\"id\":1,\"method\":\"object.deleteAll\",\"params\":[\"subscriber\"]}";
DataInputStream is = new DataInputStream(socket.getInputStream());
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
PrintWriter pw = new PrintWriter(os);
pw.println(string);
pw.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}

I think the server is expecting newline at the end of the message. Try to use your original code with write() and add \n at the end to confirm this.

Related

Translate Code from JAVA to C#, Socket Streams

I have a Java code that I have to convert to C#. The code is very basic, includes streams and sockets.
Java Code:
Socket fg = new Socket("localhost", 5400);
BufferedReader in = new BufferedReader(new FileReader("reg_flight.csv"));
PrintWriter out = new PrintWriter(fg.getOutputStream());
String line;
while((line=in.readLine())!=null) {
out.println(line);
out.flush();
Thread.sleep(100);
}
out.close();
in.close();
fg.close();
I was able of course to convert the first line, but I'm having trouble finding in Google a way to output line by line via Sockets. Specifically: PrintWriter out = new PrintWriter(fg.getOutputStream());.
My C# start:
TcpClient s = new TcpClient("localhost", 5400);
NetworkStream stream = s.GetStream();
StreamReader input = new StreamReader("reg_flight.csv");
StreamWriter output = new StreamWriter(stream);
String line;
while ((line = input.ReadLine())!= null) {
Console.WriteLine(line);
output.Write(line);
output.Flush();
System.Threading.Thread.Sleep(100);
}
For some reason, this is not working (the server doesn't receive the data correctly). I've printed the line inside the while loop and the reading seems correct. What could be the reason?
Thanks

Reading from a URL in java: when is a request actually sent?

I have an assignment for school that involves writing a simple web crawler that crawls Wikipedia. The assignment stipulates that I can't use any external libraries so I've been playing around with the java.net.URL class. Based on the official tutorial and some code given by my professor I have:
public static void main(String[] args) {
System.setProperty("sun.net.client.defaultConnectTimeout", "500");
System.setProperty("sun.net.client.defaultReadTimeout", "1000");
try {
URL url = new URL(BASE_URL + "/wiki/Physics");
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String inputLine;
int lineNum = 0;
while ((inputLine = br.readLine()) != null && lineNum < 10) {
System.out.println(inputLine);
lineNum++;
}
is.close();
}
catch (MalformedURLException e) {
System.out.println(e.getMessage());
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
In addition, the assignment requires that:
Your program should not continuously send requests to wiki. Your program
must wait for at least 1 second after every 10 requests
So my question is, where exactly in the above code is the "request" being sent? And how does this connection work? Is the entire webpage being loaded in one go? or is it being downloaded line by line?
I honestly don't really understand much about networking at all so apologies if I'm misunderstanding something fundamental. Any help would be much appreciated.
InputStream is = url.openStream();
at the above line you will be sending request
BufferedReader br = new BufferedReader(new InputStreamReader(is));
at this line getting the input stream and reading.
Calling url.openStream() initiates a new TCP connection to the server that the URL resolves to. An HTTP GET request is then sent over the connection. If all goes right (i.e., 200 OK), the server sends back the HTTP response message that carries the data payload that is served up at the specified URL. You then need to read the bytes from the InputStream that the openStream() method returns in order to retrieve the data payload into your program.

Socket's PrintWriter doesn't send until closed

I have client code that looks like:
Socket s = new Socket(server.getHostName(), server.getPort());
PrintWriter p = new PrintWriter(s.getOutputStream());
p.println(message);
p.flush();
s.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String newLine;
StringBuffer response = new StringBuffer();
while((newLine = br.readLine()) != null)
response.append(newLine);
System.out.println(response.toString());
p.close();
br.close();
and server code that looks like:
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String nextLine;
StringBuffer request = new StringBuffer();
System.out.println("Starting read....");
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
System.out.println("Message recived!!");
System.out.println("Request: " + request);
PrintWriter p = new PrintWriter(s.getOutputStream());
p.println("Hello, fileclient!");
System.out.println("Message sent!!");
p.close();
br.close();
Before I put the line s.shutDownInput() the server code would hang at br.readLine(). The way I managed to fix that is to close the PrintWriter some how, either through p.close() or through the current way which doesn't
shutdown the socket like closing the PrintWriter through p.close() does. After that, the interaction between client and server is perfect.
Why does the PrintWriter or the BufferedReader not send/receive until the PrintWriter is closed somehow?
It doesn't have anything to do with PrintWriter. It is an application protocol error on your part.
The server is looping reading lines until end of stream.
The client is sending one line and then not closing the socket, so no end-of-stream got sent (until you added the shutdown).
The server is then responding.
The client is then reading.
So the client doesn't read anything until the server gets out of the loop, and the server doesn't get out of its loop because the client is reading not closing.
So make up your mind. Probably the server should only read one line.
Both sides are behaving exactly as you told them to do. In particular, you instruct the server specifically to read everything the client sends before dispatching any response:
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
It is important to understand that that will not stop reading until an error or end of stream, where end of stream on a socket corresponds to the other end having been closed and all data having been read. In other words, your server waits for the end of the whole conversation, not the end of a single message, before dispatching a response.
Since that's apparently not what you want, you need to implement a different strategy at the server for determining when to process the data received so far and send a response. If you can be confident that your messages will not contain internal newlines, then that might be as simple as the server performing only one br.readLine() before sending each response.

Java Sockets writing/reading

So I want to read from socket , but it doesn't gives me anything , I am newbie to java networking so please help me , it doesn't gives me any errors but doesn't gives me any output from client socket too... here is a source code:
ServerSocket server = new ServerSocket(4444);
Socket client = server.accept();
PrintWriter out = new PrintWriter(client.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputline = in.readLine();
while(inputline != null)
{
System.out.println("recieved "+inputline);
}
out.close();
in.close();
server.close();
client.close();
You call readLine() exactly once. If it's not null on the first iteration, you've got an infinite loop (because it will forever be non-null). Be sure to update it.

Sending Message using TCP Socket not returning any data

I am using following code
OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);
#SuppressWarnings("unused")
byte[] b = message.getBytes("US-ASCII");
String convertedString = Normalizer.normalize(message, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "");
Log.d("ASCII", convertedString);
output.println(convertedString);
Log.e("TCP Message sent", convertedString);
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//read line(s)
String st = input.readLine();
Log.e("TCP Message received", st);
But I am stuck at String st = input.readLine(); It just hangs there and never proceed to next line. Is this correct way of sending message using TCLP And then get response?
You are getting stuck at readLine() because the connection is still open - android is still waiting for more data to come in, and so can't move on.
This is what I did, but whether this is viable may depend on the protocol you are adhering to.
StringBuilder builder = new StringBuilder();
String line;
while ((line = input.readLine()) != ""){
builder.append(line);
}
Log.i("data", builder.toString());
What you need is flushing your output stream after sending message by:
output.flush();
or use auto flush by passing true while creating Output Stream like this:
PrintWriter output = new PrintWriter(out, true);
Hope this helps

Categories

Resources