I want to make a simple http response without much to it, but it somehow screwes up. It makes around 3 connections but sometimes sending the 2nd or 3rd response before the request when i checked it with Wireshark. I am confused big time!
Here is the code:
public static int letThrough() throws IOException
{
ServerSocket serverSocket = new ServerSocket(80);
Socket connectionSocket = null;
while(running)
{
connectionSocket = serverSocket.accept();
System.out.println("Client: " + connectionSocket.getPort());
makeSession(connectionSocket);
}
serverSocket.close();
return 1;
}
static public Runnable makeSession(Socket connectionSocket)
{
Runnable rSession = new Runnable(){
#Override
public void run()
{
try
{
String clientIp = connectionSocket.getInetAddress().getHostAddress();
System.out.println("Client verbunden... (" + clientIp + ")");
PrintWriter oPWriter;
oPWriter = new PrintWriter(connectionSocket.getOutputStream(), false);
System.out.println("Streams erstellt...");
Date today = new Date();
Thread.sleep(10);
oPWriter.println("HTTP/1.1 200 OK");
oPWriter.println("Content-Type: text/html");
oPWriter.println("Server: Bot");
// this blank line signals the end of the headers
oPWriter.println("");
// Send the HTML page
oPWriter.println("<H1>Welcome to the Ultra Mini-WebServer</H2><br><H2>"+today.toString());
oPWriter.flush();
oPWriter.close();
connectionSocket.shutdownOutput();
while(connectionSocket.isOutputShutdown() == false)
{
Thread.sleep(100);
}
connectionSocket.close();
while(connectionSocket.isClosed() == false)
{
Thread.sleep(100);
}
}
catch (IOException | InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
new Thread(rSession).start();
return rSession;
}
I tried already some things, like the last two while-loops with sleep. Any Idea how i even can debug this?
Problem found! There was no real Problem with my code, it was the stupid chrome browser establishing connnections without using them. Or maybe there used for secret things that i cant see.
Related
I have a situation with a Java Socket Input reader.
I am trying to develop an URCAP for Universal Robots and for this I need to use JAVA.
The situation is as follow:
I connect to the Dashboard server through a socket on IP 127.0.0.1, and port 29999.
After that the server send me a message "Connected: Universal Robots Dashboard Server".
The next step I send the command "play".
Here starts the problem. If I leave it like this everything works.
If I want to read the reply from the server which is "Starting program" then everything is blocked.
I have tried the following:
-read straight from the input stream-no solution
-read from an buffered reader- no solution
-read into an byte array with an while loop-no solution
I have tried all of the solution presented here and again no solution for my case.
I have tried even copying some code from the Socket Test application and again no solution.
This is strange because as mentioned the Socket Test app is working with no issues.
Below is the link from the URCAP documentation:
https://www.universal-robots.com/articles/ur/dashboard-server-cb-series-port-29999/
I do not see any reason to post all the trials code because I have tried everything.
Below is the last variant of code maybe someone has an idea where I try to read from 2 different buffered readers. The numbers 1,2,3 are there just so I can see in the terminal where the code blocks.
In conclusion the question is: How I can read from a JAVA socket 2 times?
Thank you in advance!
public void sendPlay() {
try {
// Create a new Socket Client
Socket sc = new Socket("127.0.0.1", 29999);
if (sc.isConnected()) {
InputStream is = sc.getInputStream();
BufferedInputStream in = new BufferedInputStream(is);
String data = "";
int s = in.read();
data += ""+(char)s;
int len = in.available();
System.out.println("Len got : "+len);
if(len > 0) {
byte[] byteData = new byte[len];
in.read(byteData);
data += new String(byteData);
}
System.out.println(data);
System.out.println("1");
// Create stream for data
DataOutputStream out;
out = new DataOutputStream(sc.getOutputStream());
String command = new String();
command = "play"+"\n";
// Send command
out.write(command.getBytes("US-ASCII"));
out.flush();
System.out.println("2");
InputStream is1 = sc.getInputStream();
BufferedInputStream in1 = new BufferedInputStream(is1);
String data1 = "";
int s1 = in1.read();
data1 += ""+(char)s1;
int len1 = in1.available();
System.out.println("Len got : "+len1);
if(len1 > 0) {
byte[] byteData1 = new byte[len1];
in.read(byteData1);
data1 += new String(byteData1);
}
System.out.println(data1);
System.out.println("3");
// Perform housekeeping
out.close();
sc.close();
}
sc.close();
} catch (IOException e) {
System.out.println(e);
}
}
The problem seems to be that you are opening several input streams to the same socket for reading commands.
You should open one InputStream for reading, one OutputStream for writing, and keep them both open till the end of the connection to your robot.
Then you can wrap those streams into helper classes for your text-line based protocol like Scanner and PrintWriter.
Sample program to put you on track (can't test with your hardware so it might need little tweaks to work):
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class RobotTester implements AutoCloseable {
private Socket clientSocket;
private Scanner inputReader;
private PrintWriter outWriter;
private int incounter;
private int outcounter;
public static void main(String[] args) {
System.out.println("Program started. Connecting to robot");
try (RobotTester robot = new RobotTester("127.0.0.1", 29999)) {
System.out.println("Connected to robot.");
robot.nextInput(); //Read and print robot's welcome message
robot.writeCommand("play"); //Send command
String resp = robot.nextInput(); //Read result
if (resp.toLowerCase().startsWith("fail")) {
throw new Exception("Play command failed: " + resp);
}
System.out.println("Command succeeded!");
} catch (Throwable t) {
t.printStackTrace();
}
}
public RobotTester(String host, int port) throws UnknownHostException, IOException {
clientSocket = new Socket(host, port);
inputReader = new Scanner(clientSocket.getInputStream());
outWriter = new PrintWriter(clientSocket.getOutputStream());
}
public String nextInput() {
String mess = inputReader.nextLine();
System.out.println("< " + (++incounter) + ": " + mess);
return mess;
}
public void writeCommand(String command) {
System.out.println("> " + (++outcounter) + ": " + command);
outWriter.print(command);
outWriter.print('\n');
outWriter.flush();
}
#Override
public void close() throws Exception {
if (inputReader != null) {
inputReader.close();
inputReader = null;
}
if (outWriter != null) {
outWriter.close();
outWriter = null;
}
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
}
In addition, you're using 127.0.0.1 as server IP address, which is the loopback on your PC. Unless the interface to your robot works in a very peculiar way, the actual IP you should use is probably not this one.
I'm refering to this part of documentation here:
Setup a static IP-address and subnet mask on PC, so it matches the
robot, e.g.:
PC: IP-addr: 192.168.3.10 Robot: IP-addr: 192.168.3.3
Subnet: 255.255.255.0 Subnet: 255.255.255.0
Edit
If you've got more commands to put, use it like this:
//Inside your actual main class
public static void main(String[] args) {
System.out.println("Program started. Connecting to robot");
try (RobotTester robot = new RobotTester("127.0.0.1", 29999)) {
System.out.println("Connected to robot.");
robot.nextInput(); //Read and print robot's welcome message
robot.writeCommand("play"); //Send command
String resp = robot.nextInput(); //Read result
if (resp.toLowerCase().startsWith("fail")) {
throw new Exception("Play command failed: " + resp);
}
System.out.println("Command succeeded!");
robot.writeCommand("command1"); //Send command
resp = robot.nextInput(); //Read result
//Process result for command1
robot.writeCommand("command2"); //Send command
resp = robot.nextInput(); //Read result
//Process result for command2
//...
} catch (Throwable t) {
t.printStackTrace();
}
}
The latest update is that I have moved all the functions in the same Dialog and just called them straight from there, and is still not working.
I already double check there is just one stream and one writer and reader in the entire project.
JButton btnNewButton_2 = new JButton("START");
btnNewButton_2.setBackground(Color.GREEN);
btnNewButton_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
RobotTester("127.0.0.1", 29999);
nextInput();
String command="play";
writeCommand(command);
nextInput();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
close();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} });
public void RobotTester(String host, int port) throws UnknownHostException, IOException {
clientSocket = new Socket(host, port);
inputReader = new Scanner(clientSocket.getInputStream());
outWriter = new PrintWriter(clientSocket.getOutputStream());
}
public String nextInput() {
String mess = inputReader.nextLine();
System.out.println("< " + (++incounter) + ": " + mess);
return mess;
}
public void writeCommand(String command) {
System.out.println("> " + (++outcounter) + ": " + command);
outWriter.print(command);
outWriter.print('\n');
outWriter.flush();
}
public void close() throws Exception {
if (inputReader != null) {
inputReader.close();
inputReader = null;
}
if (outWriter != null) {
outWriter.close();
outWriter = null;
}
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
I have found a solution to the issue of reading the from the socket multiple times with a Swing GUI.
public void sendPlay() {
Thread appThread = new Thread() {
public void run() {
try {
RobotTester robot = new RobotTester("127.0.0.1", 29999);
System.out.println("Connected to robot.");
robot.nextInput(); //Read and print robot's welcome message
robot.writeCommand("play"); //Send command
String resp = robot.nextInput(); //Read result
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Finished on " + Thread.currentThread());
}
};
appThread.start();}
It seems that the background socket reading needs to be on a separate thread. This was causing the entire robot to be blocked. The idea was from an forum. It was not mine, but hey, it works.
Thank you very much!
thank you for your help.
I'm trying to stream sensor data from my android device to a server via TCP socket. I'm fairly new to Android and threads are a tough concept for me to grasp.
I have two methods, connectToServer() and sendDataToServer(). connectToServer() is called once at startup and sendDataToSever() is called over and over again at about 100 HZ. I would like to open the socket at connectToServer() and leave it open always, so that sendDataToServer() can send data on that socket repeatedly.
public static void connectToServer(){
sendThread = new Thread(new Runnable() {
public void run() {
mySocket = null;
os = null;
try {
mySocket = new Socket(PC_IP, PORT);
os = new DataOutputStream(mySocket.getOutputStream());
} catch (UnknownHostException exception) {
Log.d("sunnyDay", exception.getMessage());
} catch (IOException exception) {
Log.d("sunnyDay", exception.getMessage());
}
}
});
sendThread.start();
}
public static void sendDataToServer(byte[] data) {
String dataString = Arrays.toString(data);
// send this String to the server
sendThread = new Thread(new Runnable() {
public void run() {
if (mySocket != null && os != null) {
try {
os.writeBytes(dataString + "\n");
} catch (IOException exception) {
Log.d("sunnyDay", exception.getMessage());
}
}
}
});
sendThread.start();
}
The only way I've been able to repeatedly send data is by closing and reopening the socket every time in the same thread call, although I feel like this is not the solution.
I tried to have them both on the same thread so that the socket connection is still there, I'm assuming this is where I'm missing something about threads.
Any input is greatly appreciated.
Thanks!
os.flush() after os.writeBytes(dataString + "\n");
I need to have multiple client talk to multiple servers and process responses from them.
So far, I have been able to write the server code which binds to multiple clients (spawns a thread for each client) and client connect to multiple servers.
The place where I facing problem is on the client side - I am not able to receive responses from the servers.
The sequence of operations are as below -
Suppose I have 2 servers and 1 client. client connects to both servers, sends them messages, both servers receive it and both send a reply to the client - I am not able to receive this reply.
Server Code -
#Override
public void run() {
try {
// create a serversocket to listen to requests
ServerSocket serverSocket = new ServerSocket(port);
// create n sockets to listen to 5 client
for (int i = 0; i < n; i++) {
Socket socket = serverSocket.accept();
// create a processor thread for each to read and process the incoming Messages
Processor processor = new Processor(socket);
processor.start();
}
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
Processor at server code -
#Override
public void run() {
try {
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
while (true) {
String str = in.readObject();
System.out.println(message);
out.write("Got your message " + message.toString());
}
} catch (IOException e) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Processor completed " );
}
Client code -
public static void main(String[] args) throws IOException, InterruptedException {
// make the connections with other nodes
connections = connect();
// connect() creates connections from the client to all servers and stores the socket and out objects in the object called Connections.Code omitted to avoid clutter
// process all the commands
while(!commands.isEmpty()){
for(int i=0 ; i<2; i++){
send(commands.poll() , i);
}
Thread.sleep(500);
}
}
// Sends Message m to the node i
public static synchronized void send(Message m, int i) {
try {
connections.outs[i].writeInt(m.nodeId);
connections.outs[i].writeInt(m.timestamp);
connections.outs[i].writeObject(m.type);
connections.outs[i].writeObject(m.value);
connections.outs[i].flush();
InputStreamReader isr = new InputStreamReader(connections.sockets[i].getInputStream());
final BufferedReader br = new BufferedReader(isr);
new Thread() {
public void run() {
try {
while (true) {
String message = br.readLine();
System.out.println("Message received from the server : " +message);
}
} catch(IOException e) {
e.printStackTrace();
}
}
}.start();
} catch (IOException e) {
e.printStackTrace();
}
}
I am sure I am doing something wrong when listening to the message. Any suggestion no how to receive and process messages from multiple servers would be very helpful.
TIA
I am facing two problems:
1. You did not flush.
out.write("Got your message " + message.toString());
2. In the server you send no \n
The problem is the method readLine
new Thread() {
public void run() {
try {
while (true) {
String message = br.readLine();
System.out.println("Message received from the server : " +message);
}
} catch(IOException e) {
e.printStackTrace();
}
}
}.start();
from Documentation:
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
But the Server neither send a \n nor a \r. Try
out.write("Got your message " + message.toString() + "\n");
Im sorry I am coding 12 hours now and now I have a "brainlag".
I made a little Client Server programm.
Client:
public void send(String send) {
DataOutputStream out;
Socket client;
try {
client = new Socket("192.168.0.138", port);
out = new DataOutputStream(client.getOutputStream());
out.writeChars(send + '\n');
Thread.sleep(100L);
} catch (IOException ex) {
System.err.println("Can't connect to Server!");
} catch (InterruptedException ex) {
System.err.println("Cant sleep!");
}
}
Server:
public static void main(String[] args) throws IOException {
int port = 5000;
String cIn;
System.out.println("Running on Port 5000");
ServerSocket sock = new ServerSocket(port);
Socket client;
BufferedReader inFromClient;
while (true) {
client = sock.accept();
inFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
cIn = inFromClient.readLine();
System.out.println("" + cln);
}
}
Now my question. How can i make it that my string (data) is sending in a loop to the server while I input a new data.
If a make a normal while loop, my string is sending permanently to the server. If i change my String it doesn't matter.
I would make it that if i change my String, that the new String is sending to the server.
I'm sorry for my bad english. I hope you will understand.
how about sending the data with a new thread whichs sends the data in a loop. when you input some new data interupt the old thread and start a new one and so on?
I think you need to add a bufferedReader close at the end of the while loop.
while (true) {
client = sock.accept();
inFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
cIn = inFromClient.readLine();
System.out.println("" + cln);
inFromClient.close() //add this
}
If I resume:
- you need a console app (or window/awt/swing ...) or main client app which take a String, and sometimes change this String.
- this String must be sent by your function "send", continuously, with the last String
I propose you:
1 - to fix the loop (1 sec, 2, sec, x seconds ?)
2 - to use a share variable (in critical section, or synchronized), your main client app writes it, and changes it when you want, and your "send" function read it every x seconds and sends it.
Your client could look like that:
// SHARED VARIABLE
static String warning="";
final static Object warning_sync=new Object();
// Alert function
class Thread_alert extends Thread
{
// YOUR CODE
public void send(String send) {
DataOutputStream out;
Socket client;
int port=80;
try {
client = new Socket("192.168.0.138", port);
out = new DataOutputStream(client.getOutputStream());
out.writeChars(send + '\n');
Thread.sleep(100L);
} catch (IOException ex) {
System.err.println("Can't connect to Server!");
} catch (InterruptedException ex) {
System.err.println("Cant sleep!");
}
}
public Thread_alert()
{
super();
}
public void run()
{
while (true)
{
// WHAT YOU HAVE TO DO
synchronized(warning_sync)
{
System.err.println("WARN: "+warning);
send(warning);
}
// Sleep 5 seconds
try {
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// while (true)
}
// public void run()
}
// class Thread_alert
public void console_client ()
{
// START THE THREAD
Thread_alert lethread=new Thread_alert();
lethread.start();
// INPUT LOOP
Scanner s = new Scanner(System.in);
String line;
while ((line=s.nextLine())!=null)
{
System.out.println("STRING:'"+line+"'");
// Fix the warning
synchronized(warning_sync)
{
warning=line;
}
// bonus
// IF STOP: STOP
if (warning.equals("STOP"))
{
lethread.stop();
break;
}
}
// while ((line=s.nextLine())!=null)
// safe
s.close();
}
I have a TCP socket connection which works well on Android 2.3 but now facing some problems on Android 4.1.
The problem is that InputStream.read() method always returns -1 (without blocking), like the connection is closed.
Creating socket:
SocketFactory socketFactory = SocketFactory.getDefault();
Socket socket = socketFactory.createSocket("c.whatsapp.net", 5222);
socket.setSoTimeout(3*60*1000);
socket.setTcpNoDelay(true);
Retrieving input and output streams and writing some initial data:
InputStream inputStream = new BufferedInputStream(socket.getInputStream());
OutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
outputStream.write(87);
outputStream.write(65);
outputStream.write(1);
outputStream.write(2);
outputStream.flush();
Then, this condition always passes without blocking:
int c = inputStream.read();
if (c < 0) {
Log.d(TAG, "End of stream");
}
This code is running in a background thread. And it was working on Gingerbread.
Tried to use InputStreamReader and OutputStreamWriter instead of direct streams - no effect.
I have seen that very same error before, although this answer might look offtopic give it a chance and let me know if it worked, for some reason sockets are having strange behavior on jellybean even when they were working completely fine in lower android versions, the way I fixed this issue was to move the targetSdkVersion to jelly bean as well as the Project Build Target under Android properties of the project, didn't modify one single line of code, just that, and for some reason it does the trick...
Hope this helps.
Regards!
I had some similar issue where the inputStream.read() returned -1 and I did not get any Exception. In fact the server was down and the connection broken. I didn't test it with different versions, only with 4.0.
Here's the Google Bug Report about this behavior.
Unfortunately status of the bug seems to be 'closed' as not reproduceable.
My work around was to interpret the -1 as a close of the socket and an unreachable server. When you try to reconnect, you get the right errors.
I have had a similar problem and fixed it with a workaround like this
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
private static class WatchDog implements Runnable{
private Thread thread = Thread.currentThread();
public void run() {
Log.d(LOG_TAG, "Interrupting read due to timeout");
thread.interrupt();
}
}
private void read(InputStream in, ByteBuffer bb, long waitTime) throws IOException {
int startingPos = bb.position();
long timeout = System.currentTimeMillis() + RESPONSE_TIMEOUT;
ScheduledFuture<?> watchdogFuture = executor.schedule(new WatchDog(), RESPONSE_TIMEOUT, TimeUnit.MILLISECONDS);
try {
while(System.currentTimeMillis() < timeout && bb.hasRemaining()){ //workaround fixing timeout after 1ms
try{
int read = in.read(bb.array(), bb.position(), bb.remaining());
if(read > 0){
bb.position(bb.position()+read);
}
} catch(SocketTimeoutException e){}
if(bb.hasRemaining()){
Thread.sleep(5);
}
}
watchdogFuture.cancel(true);
} catch (InterruptedException e) {}
if(bb.hasRemaining()){
throw new SocketTimeoutException("Unable to read requested bytes: "
+ (bb.position()-startingPos) + "/" + (bb.limit()-startingPos)
+ " after " + (System.currentTimeMillis() - timeout + RESPONSE_TIMEOUT) + "ms");
}
}
Using BufferedReader and PrintWriter works on all versions for me and is extremely convenient for sending and receiving anything you want (even JSON strings) via any communication protocol. Try saving them as member variables when starting your background thread like this:
mInput = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
mOutput = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
For asynchronous communication your background thread might then look like this:
#Override
public final void run() {
while (!Thread.currentThread().isInterrupted()) {
if (mInput == null) {
break;
}
String message = null;
try {
message = mInput.readLine();
} catch (IOException e) {
// handle the exception as you like
break;
}
if (Thread.currentThread().isInterrupted()) {
// thread was interrupted while reading
break;
} else if (message != null) {
// handle the message as you like
}
}
}
Use another background thread to send messages:
#Override
public void run() {
if (mOutput != null) {
mOutput.println(<message to be );
if (mOutput == null) {
// the above thread was interrupted while writing
} else if (!mOutput.checkError()) {
// everything went fine
} else {
// handle the exception
}
}
}
Also, you will have to close the streams from outside to make sure readLine doesn't block forever:
try {
mOutput.close();
mInput.close();
mOutput = null;
mInput = null;
} catch (IOException e) {
// log the exception
}
Now, since you're using TCP sockets it may happen that the socket is actually dead and readLine is still blocking. You have to detect that and close the streams just like above. For that, you will have to add another thread (oh well) that periodically sends keep-alive-messages. If no message was received from the remote device for X seconds, it has to close the streams.
This whole approach makes sure the socket is closed and all threads finish at all circumstances. Of course you can make the communication synchronous, if that is what you need, by removing the sender-thread and including println() inside the reader-thread instead. I hope that helps you (even though the answer comes 8 months late).
Friend,
try inputStream.readLine(); (i.e) DataInputStream.readLine(); (Deprecated method)
this worked for me...
Try this code -
Runnable runnable = new Runnable() {
#Override
public void run() {
synchronized (this) {
Socket s = null;
String inMsg = null, msg2 = null;
try {
try {
s = new Socket(server, port);
} catch (Exception e) {
return;
}
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
try {
inMsg = in.readLine()
+ System.getProperty("line.separator");
} catch (Exception e) {
return;
}
out.write(message + "\n\r");
out.flush();
try {
msg2 = in.readLine();
if (msg2 == null) {
return;
}
} catch (Exception e) {
return;
}
out.close();
s.close();
} catch (Exception e) {
return;
}
}
}
};
It works for me.
You should use Apache Commons IO: http://commons.apache.org/proper/commons-io/
See IOUtils.copy() http://commons.apache.org/proper/commons-io/javadocs/api-release/index.html?org/apache/commons/io/package-summary.html