I am having an issue with the response I am getting when I try to get the authorization code I need to start the authenticated client. The response appears (at least to me) to be some sort of binary data, (with one or two recognizable string fragments in it), but I have no idea how to deal with it. The code from the API's 'hello world' program seems to be parsing this data as a string, but when I try it, it fails because it isn't in the expected format.
This is adapted from the 'Hello World' program (from the box api github wiki) found here in order to show what the problem appears to be.
import java.awt.Desktop;
import java.io.*;
import java.net.*;
public class HelloBox {
public static final int socket_port = 4000;
public static final String
redirect_uri = "https://localhost:" + socket_port,
client_id = /* [...] */, client_secret = /* [...] */;
public static void main(String[] args) throws Exception{
Desktop.getDesktop().browse(URI.create(
"https://www.box.com/api/oauth2/authorize?" +
"response_type=code" +
"&client_id=" + client_id +
"&redirect_uri=" + redirect_uri));
ServerSocket serverSocket = new ServerSocket(socket_port);
Socket socket = serverSocket.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(new FileWriter("output.txt"));
for(int idx = 0; idx < 4; idx++){
String line = in.readLine();
System.out.println(line);
out.println(line);
}
//[... closing all the streams and sockets ...]
}
}
All the lines after the fourth are just null, so that is why I stopped it after four lines.
You can see the result in my output.txt file here. My computer refuses to paste the string, so I couldn't include it itself in the question. I have tried examining the output with a hex editor, but I couldn't see any obvious pattern to it. (Bursts of stuff separated by occasional NULL?)
Myriad Google searches turned up nothing that appears to be of relevance for this issue, and neither the Javadoc nor the API tutorials were helpful here, either.
How can I deal with this issue? If my code is wrong, please tell me how I can correct it.
EDIT:
So I tried replacing the socket and serverSocket with
SSLServerSocket serverSocket = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(socket_port);
SSLSocket socket = (SSLSocket) serverSocket.accept();
but now I am getting
javax.net.ssl.SSLHandshakeException: no cipher suites in common at the line where it first tries to read from the stream.
Related
I want to have Server - Client relation. Once client gets connected to a server, server sends a message to a client every 1.5 seconds. Server doesn't do anything with messages from client for simplicity. In client's code, I want to use System.in to send messages to server (which don't mean anything) and when I send it, I want to read server's response (all accumulated messages from server). Code is not a snippet, but "real code".
Client:
public class ClientClass {
public static final String IP_ADDRESS = "127.0.0.1";
public static final int PORT = 9090;
public static void main (String[] args) throws IOException {
Socket socket = new Socket (IP_ADDRESS,PORT);
PrintWriter output = new PrintWriter (socket.getOutputStream (),true);
BufferedReader input = new BufferedReader (new InputStreamReader (socket.getInputStream ()));
BufferedReader keyboard = new BufferedReader (new InputStreamReader (System.in));
while (true){
System.out.println ("Enter message you want to send to server:");
String msg = keyboard.readLine ();
output.println (msg);
String serverResponses = input.readLine ();
while (serverResponses!=null){
System.out.println (serverResponses);
serverResponses=input.readLine ();
}
}
}
}
Server:
public class ServerClass {
public static int PORT = 9090;
public static void main (String[] args) throws IOException, InterruptedException {
ServerSocket server = new ServerSocket (PORT);
Socket client = server.accept ();
PrintWriter output = new PrintWriter (client.getOutputStream (),true);
while (true){
output.println ("hello from server");
Thread.sleep (1500);
}
}
}
//My comment: readLine() method in client is blocking, so I can't read server's messages until I actually read something from keyboard. That is why I have loop to "pick up" all lines from inputStream. I expect that once I read all the lines, variable stringResponses gets null and breaks from inner while loop. Then I thought that I would get a print to console of "enter message you want to send to server" found in outer loop. Unfortunately, my code never breaks out from inner while loop and I want to know why. How is it never null, when I am writing to a stream every 1.5s, meaning there is plenty of time for it to be null and break from loop.
ACTUAL OUTPUT:
Enter message you want to send to server:
hey! //this is what I typed
hello from server
hello from server
hello from server
//these three popped immediately, as they accumulated.
hello from server
hello from server
hello from server
hello from server
//keeps printing "hello from server" every 1.5s and never comes back to "enter your message" -WHY?
readLine returns null at the end of stream. Since the Server Socket isn't closed. It is never null in your inner loop.
Link - https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()
A String containing the contents of the line, not including any
line-termination characters, or null if the end of the stream has been
reached
What do you expect the behaviour when readLine got invoked in a loop on your keyboard object ?
String msg = keyboard.readLine();
while(msg != null)
msg = keyboard.readLine();
This too will keep on taking inputs from the System.in. The loop would never end.
Solutions
As quoted above from java documentation, readLine method blocks for an input. That is the reason, there is no effect of delaying server response. The method returns null only at the end of the stream.
Solution 1 - Making use of ready method
ready method returns false when the read methods has to wait for an input data. As the Server code is sleeping for 1.5 sec, this method should return false during that time.
The downside of this approach is that if Server is not finished with all the response lines on time, then the inner loop where you collect all Server Responses will break.
while (true){
System.out.println ("Enter message you want to send to server:");
String msg = keyboard.readLine ();
output.println (msg);
String serverResponses = input.readLine ();
System.out.println (serverResponses);
while (input.ready()){
serverResponses=input.readLine ();
System.out.println (serverResponses);
}
}
Solution 2 - Server sends total lines
If the server knows about the total number of lines, then that can be sent as the first line in the stream. Depending upon total lines, client code can read those many lines. The downside of this approach is that an extra line has to be added in the Server response.
while (true){
System.out.println ("Enter message you want to send to server:");
String msg = keyboard.readLine ();
output.println (msg);
Integer linesCount = Integer.parseInt(input.readLine ());
for (int i=0; i< linesCount; i++){
String serverResponses=input.readLine ();
System.out.println (serverResponses);
}
}
I am trying to work through a socket chat with just one client and the server. I have it successfully running, as in the server is capable of passing messages back and forth, but when I attempt to make the server side implementation a bit more complex, adding commands and such, that the client can use, the communication fails. It appears it might go out of sync even as using the same commands over and over again can produce different results, even though I flush everything after every command.
Example of simplistic output, this works as expected, every time:
Client:
import java.io.*;
import java.net.*;
public class Test1Client
{
public static void main(String args[])
{
InputStreamReader convert = new InputStreamReader(System.in);
BufferedReader stdin = new BufferedReader(convert);
try
{
Socket echoClient = new Socket("localhost", 17);
PrintStream outs = new PrintStream(echoClient.getOutputStream());
BufferedReader ins = new BufferedReader(new InputStreamReader(echoClient.getInputStream()));
while(true){
System.out.print("Type whatever you want: ");
String line = stdin.readLine();
outs.println(line);
System.out.println("Server says: " + ins.readLine());
}
}
catch (IOException e)
{
System.out.println(e);
}
}
}
Server:
import java.net.*;
import java.util.ArrayList;
import java.io.*;
public class Test1Server
{
public static void main(String args[])
{
try
{
ServerSocket socket= new ServerSocket(12167);
//Try not to use port number < 2000.
System.out.println("Waiting for a client to connect...");
Socket s = socket.accept();
System.out.println("Client Connected.");
BufferedReader ins = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintStream outs = new PrintStream(s.getOutputStream());
while (true)
{
String line = ins.readLine();
outs.println(line);
}
}
catch (IOException e)
{
e.getStackTrace();
}
}
}
I get output like this, it works every time just spitting it back out:
Type whatever you want: login
Server says: login
Type whatever you want: login
Server says: login
Type whatever you want: login
Server says: login
Type whatever you want: login
Server says: login
But when I make the server side a bit more complex by replacing its while(true) block with the following, I get a much more messy result:
String line = ins.readLine();
String response = manager.process(line);
outs.println(response);
outs.flush();
process:
msg= "User logged in successfully \n";
return msg;
You'll also notice some commented lines in the process command code. When I give back a simple message the server seems to keep up, but when I use the login function as well it gives the terrible output like this:
Type whatever you want: login ryanne
Server says: ryanne logged in successfully
Type whatever you want: login ryanne
Server says:
Type whatever you want: login ryanne
Server says: You may already be logged in or did not use correct username or password
Type whatever you want: login ryanne
Server says:
Type whatever you want: newuser jeff
Server says: You may already be logged in or did not use correct username or password
Type whatever you want: newuser jeff 12345
Server says:
Type whatever you want: new user jeff 12345
Server says: You may already be logged in or did not use correct username or password
Type whatever you want:
Again, notice the blanks where nothing comes back from the server, and then even the change in the commands does not prompt different responses. Its as if it went out of sync, just by using one additional function?
You have some "\n" at the end of some strings.
If you both put "\n" and use println, you will have double carriage returns, which will mess up your protocol. Remove the "\n"'s, and it should work better.
Maybe, data you sent was not flushed. Use outs.flush(); after outs.println(line); or change it's constructor call to PrintStream(echoClient.getOutputStream(),true); (enable auto-flush on printing new line)
I am new to java Network programming.I was googling the code for a TCP client in java.I came across the following example.
import java.lang.*;
import java.io.*;
import java.net.*;
class Client {
public static void main(String args[]) {
try {
Socket skt = new Socket("localhost", 1234);
BufferedReader in = new BufferedReader(new
InputStreamReader(skt.getInputStream()));
System.out.print("Received string: '");
while (!in.ready()) {}
System.out.println(in.readLine()); // Read one line and output it
System.out.print("'\n");
in.close();
}
catch(Exception e) {
System.out.print("Whoops! It didn't work!\n");
}
}
}
The client seems to read out the data one "line" at a time?. I am connecting to a server that is streaming OpenFlow packets.A wireshark screenshot of OpenFlow packets is given below.
[http://www.openflow.org/downloads/screenshot-openflow-dissector-2008-07-15-2103.jpg][1]
Once I recieve the complete packets I want to dump that to a file and then later read it using wireshark for example.In the above code they are using calss BufferedReader to read the data in "lines"? At least that is how I understand it.Is there someway in which I can get full packets and then write it to the file?
Readers are for working with text data. If you are working with binary data (it's not entirely clear from that screenshot), you should be working with some type of Stream (either InputStream or possibly DataInputStream). Don't just look for random examples on online, try to find ones that actually apply to what you are interested in doing.
also, don't ever use InputStream.available, it's pretty much useless. as is any example code using it.
also, a simple google search for "OpenFlow java" had some interesting hits. are you sure you need to write something from scratch?
No, but there are libraries that provides such functions. See for example Guava
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io/ByteStreams.html
If you don't want to (or can't) use libraries you shoud consume a stream like this
List<String> lst = new ArrayList<String>();
String line;
while ((line = in.readLine()) != null) {
lst.add(line);
}
or
String str = "";
String line;
while ((line = in.readLine()) != null) {
str += line + "\n";
}
Note that the BufferedReader.readLine() method will give you a new line on linebreaks ('\n'). If the InputStream is binary you should work with bytes instead.
I wrote two small java programs: a TCP client which sends many lines of data from a txt file, and a TCP Server which accepts connection and receives line by line.
It works, but Server receives all the lines together, when transmission is over and client closes the socket. I don't understand why, because I'm using flush after each line sent into the Client, and I always thought that was to avoid this kind of situation.
If my test.txt file contents the numbers 1 2 3 ... 10, each one in a new line, Server's output is: "12345678910" and then in a new line it writes in console "null".
Server code:
import java.io.*;
import java.net.*;
class ServidorTCP {
private String HOST;
static final int PUERTO = 20001;
public ServidorTCP( ) {
try{
ServerSocket skServidor = new ServerSocket(PUERTO);
Socket skCliente = skServidor.accept();
DataInputStream inFromClient = new DataInputStream(new BufferedInputStream(skCliente.getInputStream()));
while(true){
String lineaLeida = inFromClient.readUTF();
if(lineaLeida.equals("END")) break;
System.out.println(lineaLeida);
}
inFromClient.close();
skCliente.close();
skServidor.close();
System.out.println( "Transmission ended" );
} catch( Exception e ) {
System.out.println( e.getMessage() );
}
}
public static void main( String[] arg ) {
new ServidorTCP();
}
}
Cliente code:
import java.io.*;
import java.net.*;
class ClienteTCP {
static final String HOST = "192.168.1.201";
static final int PUERTO = 20001;
public ClienteTCP( ) {
try{
Socket skCliente = new Socket(HOST, PUERTO);
if(skCliente.isConnected()) System.out.println("Connected!");
DataOutputStream outToServer = new DataOutputStream(skCliente.getOutputStream());
File testFile = new File("test.txt");
BufferedReader input = new BufferedReader(new FileReader(testFile));
String line;
while((line=input.readLine())!=null) {
if(!line.endsWith("\n")) line = line + "\n";
System.out.println("Sending: " + line);
outToServer.writeBytes(line);
outToServer.flush();
Thread.currentThread().sleep(1000);
}
outToServer.writeBytes("END");
input.close();
outToServer.close();
skCliente.close();
} catch( Exception e ) {
System.out.println( e.getMessage() );
}
}
public static void main( String[] arg ) {
new ClienteTCP();
}
}
Where is the problem?
EDIT: I have edited the code as suggested. Now doesn't receive anyhing
The fact of the matter is that your code doesn't work at all, let alone before or after the socket is closed. You are writing with writeUTF() and reading with readLine(). This does not work. You need to:
write with DataOutputStream.writeUTF() and read with DataInputStream.readUTF()
write with println() (supplied by several I/O classes), or write() or print() (supplied by several I/O classes), followed by BufferedWriter.newline(), or
write with ObjectOutputStream.writeObject() and read with ObjectInputStream.readObject().
Etc. Writing with one API and reading with a non-symmetrical API doesn't work.
The problem is not with reading or writing (or at least not explicitly). The problem is your string. input.readLine() removes the end of line which means the string you're sending is just the number. On the server side then you receive a lot of strings but inFromClient.readLine() waits until it gets an end of line which never arrives until the stream closes and sends an end of file.
Just add an end of line to every string you're sending and it should work.
I'm coding a little program that checks an online store for new items in a specific department. When it does find that a new item has been added, it's supposed to send that info to a simple IRC-bot, which in turn writes it out in a channel so I can see it immediately.
The problem is that the IRC part only works once. So while the parser successfully announce every new item at the store in my console, the IRC bot only shows the first. So the problem is most likely my socket code.
I shall tell you that I'm a complete noob with sockets, so it can be a really simple problem(for you, that is).
Enough talk, here's the relevant code:
The bot:
public void openSocket() throws IOException{
serversock = new ServerSocket(1551);
Socket sock = serversock.accept();
BufferedReader incoming = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String inString = incoming.readLine();
sendMessage("#channel", inString);
}
public static void main(String[] args) throws Exception {
XanaduBot bot = new XanaduBot();
bot.setVerbose(true);
bot.connect("irc.server.net");
bot.joinChannel("#channel");
bot.openSocket();
}
And the socket part on the scraper:
if(old == false){
Socket client = new Socket("localhost",1551);
DataOutputStream toBot = new DataOutputStream(client.getOutputStream());
String infoToSend = "New product! "+ info;
toBot.writeBytes(infoToSend + '\n');
toBot.flush();
System.out.println(infoToSend);
}
The variable old is false whenever the program finds a new item. And I know that exceptions are handled pretty bad here, sorry for that!
Any help appreciated!