I am currently reading sensor values from an android device, and streaming them to a pc client connected.
bzero(buffer,256);
//fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
while(1){
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
sleep(1);
printf("%s\n",buffer);
}
close(sockfd);
return 0;}
Code for the PC client that outputs the data.
while(!stopFlag){
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(s.getOutputStream())), true);
// out.printf(String.valueOf(accel[0]),accel[1],accel[2]);
out.printf(String.valueOf(d.format(accel[0]))+" "+String.valueOf(d.format(accel[1]))+" "+String.valueOf(d.format(accel[2])) + " Accelerometer " + "\n");
out.printf(String.valueOf(d.format(gyro[0]))+" "+String.valueOf(d.format(gyro[1]))+" "+String.valueOf(d.format(gyro[2]))+ " Gyroscope " + "\n");
out.printf(String.valueOf(d.format(magnet[0]))+" "+String.valueOf(d.format(magnet[1]))+" "+String.valueOf(d.format(magnet[2]))+" Magnetometer "+ "\n\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Code Snippet of sensor values being sent.
How would I fix this or what's a cleaner method to output the data? [SOLVED]
Also how do I write the output as a csv formatted file. I've looked around but still not too sure how to read my sensor values, since I have a 4x4, being the sensor values and name of the sensor as seen in the image above.
If I were to add a delay/sleep function on the client side, after closing the sockets on the application side, the client would still show incoming values, any ideas on why ?
Any help or advice would be greatly appreciated!
Regards
Roger has provided me with correct answer, not sure where his post is now though.
Removing the \n (new line) fixed the issue, data now doesn't flow to next line.
Related
I am trying to make a little LAN chat in Java, I have a thread that loops through a list with all the clients and tries to read the next line with 0 set as the timeout.
while(true){
for(ChatClient chater : Server.connections){
try{
chater.sock.setSoTimeout(0);
message = SocketUtils.recvMsg(chater.sock);
System.out.println(chater.getName() + " has sent a message!");
message = chater.getName() + ": " + message;
senderId = chater.getId();
Server.broadcastMsg(message, senderId);
}
catch(SocketTimeoutException e1){
continue;
}
catch(IOException e){
//
}
}
}
I am pretty sure that the bug is between the bug is because the non-blocking sockets aren't implemented correctly.
What would be the best way to receive messages from the users without blocking the loop?
Thanks for taking your time answering the question!
I am building an IM application, from the client side, I write my code like this (I use SocketChannel in blocking mode, history reason, I think it is not related to this problem):
try {
LogUtil.info(TAG, this.label + " tryConnect, attempt = " + (3 - retry));
clientChannel = SocketChannel.open();
clientChannel.configureBlocking(true);
clientChannel.socket().setSoTimeout(100);
clientChannel.socket().setTrafficClass(0x10);
clientChannel.socket().setTcpNoDelay(true);
clientChannel.socket().setPerformancePreferences(3, 3, 1);
clientChannel.socket().connect(address, 10000);
LogUtil.info(TAG, this.label + " socket connected successfully");
break;
} catch (AlreadyConnectedException ace) {
LogUtil.info(TAG, label + " AlreadyConnectedException");
break;
} catch (NotYetConnectedException ace) {
LogUtil.info(TAG, label + " NotYetConnectedException");
break;
} catch (SocketTimeoutException e) {
LogUtil.info(TAG, label + " SocketTimeoutException");
break;
} catch (Exception e) {
clientChannel = null;
throw new SocketConnectionException(label + ", exception = " + ThrowableUtil.stackTraceToString(e));
}
The problem is, when sometimes I shut down the server, the client-side will keeps writing successfully (small chunks of data, less than 50 bytes in total). After about 3 minutes, the client side hits the write fail exception.
Why didn't the client side fail immediately after the server has been closed? How do I fix this problem? Maybe reduce the send buffer to 10 bytes ?
EDIT
Here's how I actually write data:
public void writeXML(ByteBuffer buffer, int retry) {
synchronized (writeLock) {
if (retry < 0) {
throw new SocketConnectionException(label + "Write Exception");
}
tryConnect(false);
try {
int written = 0;
while (buffer.hasRemaining()) {
// I think it should be an exception here after I closed server
written += clientChannel.write(buffer);
}
if (LogUtil.debug) {
LogUtil.info(TAG, "\t successfully written = " + written);
}
} catch (Exception e) {
e.printStackTrace();
tryConnect(true);
writeXML(buffer, --retry);
}
}
}
Because in between you and the peer application there are:
a socket send buffer
a TCP implementation
another TCP implementation
a socket receive buffer.
Normally when you write, the data just gets transferred into your socket send buffer and is sent on the wire asynchronously. So if there is going to be an error sending it you won't find out straight away. You will only find out when the TCP sends have failed enough times over whatever the internal send timeout period is for TCP to decide that an error condition exists. The next write (or read) after that will get the error. It could be some minutes away.
It turns out that the read operation can detect a closed connection(via #EJP's reply, it is different from a lost connection) immediately.
In my reading thread, I have this line:
int read = clientChannel.read(buffer);
, When it returns -1 means the server is shutdown (Shutdown on purpose is different than network unreachable), I guess the write operation needs to fill the TCP send buffer, so there's no way to detect a connection lost quickly.
I have a java method that looks like,
private void exportGpio(){
String fullPath = path + "/export"; // /sys/class/gpio/export
FileWriter writer = null;
try {
writer = new FileWriter(fullPath);
writer.write("" + number);
} catch (IOException e) {
Log.e(TAG + number, "Could not export", e);
}
finally {
if(writer != null){
try {
writer.flush(); <- FAILING HERE
writer.close();
} catch (IOException e) {
Log.e(TAG + number, "Could not close writer", e);
}
}
}
}
Once it gets to the flush it throws an exception
java.io.IOException: Device or resource busyjava.io.IOException:
Device or resource busy at java.io.FileOutputStream.writeBytes(Native
Method) at java.io.FileOutputStream.write(FileOutputStream.java:345)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) at
sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291) at
sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295) at
sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141) at
java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229) at
lights.GPIO.exportGpio(GPIO.java:106) at
lights.GPIO.(GPIO.java:34) at
lights.LightManager.(LightManager.java:34) at
main.Main.createSubsystems(Main.java:17) at
main.Main.main(Main.java:34)
What is going on? Can java not interact with syses on a raspberry pi?
No it can not do it directly so easily.
General Purpose I/O pins are some input/output that we can put some High or Low voltages on them. Or we can read some High or Low voltages from them.
They are not digital port interfaces that we can write bits and bytes of the digital world into them directly. You need some low level programming interfaces to read/write on GPIOs.
These low level programming APIs can translate your 0 or 1 as some high and low voltages.
There is a very elegant library called Pi4J that you can use very easily in your code. They have a very good documentation which help you through working with Raspberry PI board. If you are a programmer from high level programming languages like java, it gives you the good flavor of event based programming with support of EventListeners instead of polling and interrupt for reading from a I/O pins. If you are not forced to work directly on the device it is very good alternative to work with.
Hope this would be helpful.
I did end up figuring this out. I looked at STaefi answers and I think your wrong. The os drivers should handle the voltages. What I discovered was that the FileWritter class in java does not work well with these types of virtual files. I ended up trying the java print writer class and everything works.
PrintWriter writer = null;
try {
writer = new PrintWriter(fullPath, "UTF-8");
writer.write("1");
} catch (IOException e) {
Log.e(TAG + number, "Could not turn on", e);
}
finally {
if(writer != null){
try {
writer.close();
} catch (Exception e) {
Log.e(TAG + number, "Could not close writer", e);
}
}
}
Im still not exactly sure why the file writers don't work but this solution will at least help anyone else that gets stuck here along the way.
I have made a launcher for my game Privateers. It works perfectly, downloads everything needed - But, for some reason, it freezes the entire computer!
The freeze usually occurs when doing something, if I afk at my computer until the download completes, then nothing happens. However, when I tested it on my mothers computer playing the game "World Of Tanks", the computer froze almost immediately. If I play a game then the launcher also has a tendency to freeze my computer.
I use windows 8, my mother uses windows 7.
On my own computer, when this happens I am able to move the mouse very slowly (between 30 second to 2 minute delay), alt+tab won't work, control+alt+delete will work (but when opening task manager the task manager does not appear).
On my mothers' computer it is basically the same except that EVERYTHING is frozen 100% except for the mouse which is working fine.
It only happens when downloading large (5MB+) files. When my launcher downloads smaller files there is no issue.
I use the following code to download files:
void download(String source, String destination, int size) {
File ofile = new File(System.getProperty("user.dir") + "", destination);
System.out.printf("\nDownloading\n\t%s\nTo\n\t%s\n", source, destination);
try {
if (ofile.exists()) ofile.delete();
if (!ofile.createNewFile()) {
throw new IOException("Can't create " + ofile.getAbsolutePath());
}
int inChar = 0;
URL url = new URL(source);
InputStream input = url.openStream();
FileOutputStream fos = new FileOutputStream(ofile);
for (int i = 0; i < size && inChar != -1; i++) {
int percentage = (int) ((i * 100.0f) / size);
progressBar.setValue(((int) ((percentage * 100.0f) / 100)));
fr.setTitle(ofile.getName() + ": " + progressBar.getValue() + "%" + " Total: " + oprogressBar.getValue() + "%");
inChar = input.read();
fos.write(inChar);
}
input.close();
fos.close();
System.out.println("Downloaded " + ofile.getAbsolutePath());
} catch (EOFException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have been unable to find a duplicate of this happening when searching on the internet. Any help is appreciated.
Maybe multithreading will help you out over here.
See more about it in this post
Buffer the input stream, or read more than one character at a time, or both.
EDIT I have it working now thanks to the comments below. I also explained what I fixed in the comments. Thanks for the help guys.
Im working on a multiplayer game in java. It's coming along pretty well so far, but Im having an issue with the server sending information to the client. The process should be that, the server receives information from the client and interprets what it's supposed to do. In this case, the client sends a chat message to the server split with commas. "chat,Bob,the message is here."
At this point in time, the server should essentially send back that same information to the client that sent the message. Somehow, along the way though, the ByteBuffer which is what is housing the information gets corrupted?
The following is the pertinent code for the server:
// Read the data
SocketChannel sc = (SocketChannel) key.channel();
// interpret
int bytesEchoed = 0;
while (true) {
//Clears this buffer.
echoBuffer.clear();
int number_of_bytes;
String message = new String(echoBuffer.array());
String[] splits = message.split(",");
try {
number_of_bytes = sc.read(echoBuffer);
} catch (java.io.IOException e) {
key.cancel();
number_of_bytes = -1;
}
//-----------Interpret Packets--------------------
//-------------Chat-----------------
if (splits[0].contentEquals("chat")) {
//do chat shit
String name = splits[1];
String text = splits[2];
String sendBack = "chat," + name + "," + text + ","+"\r";
System.out.println(sendBack);
if (splits[0].equals("chat")) {
echoBuffer.clear();
echoBuffer.put(sendBack.getBytes());
}
}
//
if (number_of_bytes <= 0) {
break;
}
//
//
echoBuffer.flip();
sc.write(echoBuffer);
bytesEchoed += number_of_bytes;
}
System.out.println("Echoed " + bytesEchoed + " from " + sc);
// once a key is handled, it needs to be removed
it.remove();
}
}
}
}
Can anyone tell me what I am messing up?
I wasn't doing clear() before I was putting the sendBack string to the bytebuffer, and that was adding the text to the end of the buffer, instead of the beginning. Also, on the client side I was using readLine() to get the incoming data, but there was no carriage return "\r" or new line "\n" on the outgoing server data, resulting in my client reading nothing. Those two things fixed, have it working properly.