I tried installing tinyb from the repository: https://github.com/intel-iot-devkit/tinyb
I've build the tinyb.jar and add it to the IntellJ project as a library.
I ran the sample code provided in tinyb examples with small modification(commented out some code in the main method before the Bluetooth Manager initialization):
import tinyb.*;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.TimeUnit;
public class HelloTinyB {
private static final float SCALE_LSB = 0.03125f;
static boolean running = true;
static void printDevice(BluetoothDevice device) {
System.out.print("Address = " + device.getAddress());
System.out.print(" Name = " + device.getName());
System.out.print(" Connected = " + device.getConnected());
System.out.println();
}
static float convertCelsius(int raw) {
return raw / 128f;
}
/*
* After discovery is started, new devices will be detected. We can get a list of all devices through the manager's
* getDevices method. We can the look through the list of devices to find the device with the MAC which we provided
* as a parameter. We continue looking until we find it, or we try 15 times (1 minutes).
*/
static BluetoothDevice getDevice(String address) throws InterruptedException {
BluetoothManager manager = BluetoothManager.getBluetoothManager();
BluetoothDevice sensor = null;
for (int i = 0; (i < 15) && running; ++i) {
List<BluetoothDevice> list = manager.getDevices();
if (list == null)
return null;
for (BluetoothDevice device : list) {
printDevice(device);
/*
* Here we check if the address matches.
*/
if (device.getAddress().equals(address))
sensor = device;
}
if (sensor != null) {
return sensor;
}
Thread.sleep(4000);
}
return null;
}
/*
* Our device should expose a temperature service, which has a UUID we can find out from the data sheet. The service
* description of the SensorTag can be found here:
* http://processors.wiki.ti.com/images/a/a8/BLE_SensorTag_GATT_Server.pdf. The service we are looking for has the
* short UUID AA00 which we insert into the TI Base UUID: f000XXXX-0451-4000-b000-000000000000
*/
static BluetoothGattService getService(BluetoothDevice device, String UUID) throws InterruptedException {
System.out.println("Services exposed by device:");
BluetoothGattService tempService = null;
List<BluetoothGattService> bluetoothServices = null;
do {
bluetoothServices = device.getServices();
if (bluetoothServices == null)
return null;
for (BluetoothGattService service : bluetoothServices) {
System.out.println("UUID: " + service.getUUID());
if (service.getUUID().equals(UUID))
tempService = service;
}
Thread.sleep(4000);
} while (bluetoothServices.isEmpty() && running);
return tempService;
}
static BluetoothGattCharacteristic getCharacteristic(BluetoothGattService service, String UUID) {
List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
if (characteristics == null)
return null;
for (BluetoothGattCharacteristic characteristic : characteristics) {
if (characteristic.getUUID().equals(UUID))
return characteristic;
}
return null;
}
/*
* This program connects to a TI SensorTag 2.0 and reads the temperature characteristic exposed by the device over
* Bluetooth Low Energy. The parameter provided to the program should be the MAC address of the device.
*
* A wiki describing the sensor is found here: http://processors.wiki.ti.com/index.php/CC2650_SensorTag_User's_Guide
*
* The API used in this example is based on TinyB v0.3, which only supports polling, but v0.4 will introduce a
* simplied API for discovering devices and services.
*/
public static void main(String[] args) throws InterruptedException {
// if (args.length < 1) {
// System.err.println("Run with <device_address> argument");
// System.exit(-1);
// }
/*
* To start looking of the device, we first must initialize the TinyB library. The way of interacting with the
* library is through the BluetoothManager. There can be only one BluetoothManager at one time, and the
* reference to it is obtained through the getBluetoothManager method.
*/
BluetoothManager manager = BluetoothManager.getBluetoothManager();
/*
* The manager will try to initialize a BluetoothAdapter if any adapter is present in the system. To initialize
* discovery we can call startDiscovery, which will put the default adapter in discovery mode.
*/
boolean discoveryStarted = manager.startDiscovery();
System.out.println("The discovery started: " + (discoveryStarted ? "true" : "false"));
BluetoothDevice sensor = getDevice(args[0]);
/*
* After we find the device we can stop looking for other devices.
*/
try {
manager.stopDiscovery();
} catch (BluetoothException e) {
System.err.println("Discovery could not be stopped.");
}
if (sensor == null) {
System.err.println("No sensor found with the provided address.");
System.exit(-1);
}
System.out.print("Found device: ");
printDevice(sensor);
if (sensor.connect())
System.out.println("Sensor with the provided address connected");
else {
System.out.println("Could not connect device.");
System.exit(-1);
}
Lock lock = new ReentrantLock();
Condition cv = lock.newCondition();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
running = false;
lock.lock();
try {
cv.signalAll();
} finally {
lock.unlock();
}
}
});
BluetoothGattService tempService = getService(sensor, "f000aa00-0451-4000-b000-000000000000");
if (tempService == null) {
System.err.println("This device does not have the temperature service we are looking for.");
sensor.disconnect();
System.exit(-1);
}
System.out.println("Found service " + tempService.getUUID());
BluetoothGattCharacteristic tempValue = getCharacteristic(tempService, "f000aa01-0451-4000-b000-000000000000");
BluetoothGattCharacteristic tempConfig = getCharacteristic(tempService, "f000aa02-0451-4000-b000-000000000000");
BluetoothGattCharacteristic tempPeriod = getCharacteristic(tempService, "f000aa03-0451-4000-b000-000000000000");
if (tempValue == null || tempConfig == null || tempPeriod == null) {
System.err.println("Could not find the correct characteristics.");
sensor.disconnect();
System.exit(-1);
}
System.out.println("Found the temperature characteristics");
/*
* Turn on the Temperature Service by writing 1 in the configuration characteristic, as mentioned in the PDF
* mentioned above. We could also modify the update interval, by writing in the period characteristic, but the
* default 1s is good enough for our purposes.
*/
byte[] config = { 0x01 };
tempConfig.writeValue(config);
/*
* Each second read the value characteristic and display it in a human readable format.
*/
while (running) {
byte[] tempRaw = tempValue.readValue();
System.out.print("Temp raw = {");
for (byte b : tempRaw) {
System.out.print(String.format("%02x,", b));
}
System.out.print("}");
/*
* The temperature service returns the data in an encoded format which can be found in the wiki. Convert the
* raw temperature format to celsius and print it. Conversion for object temperature depends on ambient
* according to wiki, but assume result is good enough for our purposes without conversion.
*/
int objectTempRaw = (tempRaw[0] & 0xff) | (tempRaw[1] << 8);
int ambientTempRaw = (tempRaw[2] & 0xff) | (tempRaw[3] << 8);
float objectTempCelsius = convertCelsius(objectTempRaw);
float ambientTempCelsius = convertCelsius(ambientTempRaw);
System.out.println(
String.format(" Temp: Object = %fC, Ambient = %fC", objectTempCelsius, ambientTempCelsius));
lock.lock();
try {
cv.await(1, TimeUnit.SECONDS);
} finally {
lock.unlock();
}
}
sensor.disconnect();
}
}
I got the following stack error when I run it (image below) :
I've tried many solution such as this fix:
https://github.com/intel-iot-devkit/tinyb/issues/75
but gave me the same error.
Any tips and tricks appreciated Thanks.
I figured it out, for tinyb to work properly it need library files generated from the build. For me it was in /home/user/Desktop/tinyb-master/src where those files are in the folder (libtinyb.so, libtinyb.so.0, libtinyb.so.0.5.0) and also in :/home/user/Desktop/tinyb-master/java/jni where those files are in the folder (libjavatiny.so, libjavatinyb.so.0, libjavatinyb.so.0.5.0).These two path must be added in the VM Option as follow:
-Djava.library.path=/home/user/Desktop/tinyb-master/java/jni:/home/user/Desktop/tinyb-master/src and also don't forget the tinyb.jar (../tinyb-master/java/tinyb.jar) that need to be added in the java project.
Related
I modified an open-source project on github for a school project to fit my needs
it had a broadcast() method to send messages and it was called in the run() method in a while loop but the problem is that broadcast() sends a message to all users in a userList<>i wanted to add the ability to send a private message to one of the users by writing #username.
Here is the code for broadcast method:
private synchronized void broadcast(String msg) {
for (int i = 0; i < clientList.size(); i++) {
clientList.get(i).write(msg);
}
System.out.println("Log: Message broadcast --> " + msg);
}
and here is the run() method
public void run() {
System.out.println("Log: Got input/output streams for connected client.");
/** Get the first message from the client, attempt communication */
String clientMsg = null;
boolean accepted = false;
/** Allow client to create an account, login, or quit */
do {
clientMsg = client.read();
if (clientMsg.equals("QUIT")) {
System.out.println("Log: Client disconnected without signing in.");
client.disconnect();
return;
}
else if (clientMsg.startsWith("NEWUSER: ")) {
createUser(clientMsg);
}
else if (clientMsg.startsWith("LOGIN: ")) {
accepted = authenticate(clientMsg);
}
else
{
System.out.println("Log: Unexpected client message -> " + clientMsg);
client.disconnect();
return;
}
} while(!accepted);
/** Run main chat loop. Will read from the client, and broadcast each read
* until the client disconnects. */
while (true) {
int i=0;
String username= clientList.get(i).getUsername();
String line = client.read();
if (line == null) break;
else if(line.startsWith("#"+username)){
broadcastp(line,username);
}
else {
broadcast(line);
}
i++;
}
/** The only way for the client to exit the above loop is to disconnect.
* Therefore, call the handler's exit routine */
exit();
}
Here is the broadcastp() method that i tried to implement this feature with, but it doesn't work. It compiles and runs perfectly though just without the private chat feature.
private synchronized void broadcastp(String msg,String username) {
for (int i = 0; i < clientList.size(); i++) {
username = clientList.get(i).getUsername();
if(msg.startsWith("#"+username))
{clientList.get(i).write(msg);}
else {
continue;
}}
System.out.println("Log: Message broadcast --> " + msg);}
I do not have the full picture of how your program works, but you say the program runs perfectly, but does not do the private messaging part.
If I look at your code, in the while loop you always take the first username from the clientList (i = 0) and only call broadcastp if the line starts with that name.
First of all.. is broadcastp ever invoked? In broadcastp you have another loop, but that will always match on i == 0 given the way you invoke it (with the line and username from the while loop).
The problem seems to be be there. So something like this within the while loop might work for you (remove the i variable, and no need for broadcastp):
boolean isPrivate = false;
String line = client.read();
for (User user : clientList) {
if (line.startsWith("#" + user.getUsername())) {
user.write(line);
isPrivate = true;
break;
}
}
if (!isPrivate) {
broadcast(line);
}
I have tried a program which download files parallely using java.nio by creating a thread per file download.
package com.java.tftp.nio;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* This class is used to download files concurrently from tftp server by
* configuring the filenames, no of files.
*
* #author SHRIRAM
*
*/
public class TFTP_NIO_Client {
/**
* destination folder
* */
private String destinationFolder;
/**
* list of files names to download
* */
private List<String> fileNames;
/**
* integer indicates the number of files to download concurrently
* */
private int noOfFilesToDownload;
public TFTP_NIO_Client(List<String> fileNames, String destinationFolder,
int noOfFilesToDownload) {
this.destinationFolder = destinationFolder;
this.fileNames = fileNames;
this.noOfFilesToDownload = noOfFilesToDownload;
initializeHandlers();
}
/**
* This method creates threads to register the channel to process download
* files concurrently.
*
* #param noOfFilesToDownload
* - no of files to download
*/
private void initializeHandlers() {
for (int i = 0; i < noOfFilesToDownload; i++) {
try {
Selector aSelector = Selector.open();
SelectorHandler theSelectionHandler = new SelectorHandler(
aSelector, fileNames.get(i));
theSelectionHandler.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Setup RRQ/WRQ packet Packet : | Opcode | FileName | 0 | mode | 0 |
* Filename -> Filename in array of bytes. 0 -> indicates end of file mode
* -> string in byte array 'netascii' or 'octet'
*
* #param aOpcode
* #param aMode
* #param aFileName
* #throws IOException
*/
private void sendRequest(int aOpcode, int aMode, String aFileName,
DatagramChannel aChannel, InetSocketAddress aAddress)
throws IOException {
// Read request packet
TFTPReadRequestPacket theRequestPacket = new TFTPReadRequestPacket();
aChannel.send(
theRequestPacket.constructReadRequestPacket(aFileName, aMode),
aAddress);
}
/**
* sends TFTP ACK Packet Packet : | opcode | Block# | opcode -> 4 -> 2 bytes
* Block -> block number -> 2bytes
*
* #param aBlock
*/
private ByteBuffer sendAckPacket(int aBlockNumber) {
// acknowledge packet
TFTPAckPacket theAckPacket = new TFTPAckPacket();
return theAckPacket.getTFTPAckPacket(aBlockNumber);
}
/**
* This class is used to handle concurrent downloads from the server.
*
* */
public class SelectorHandler extends Thread {
private Selector selector;
private String fileName;
/**
* flag to indicate the file completion.
* */
private boolean isFileReadFinished = false;
public SelectorHandler(Selector aSelector, String aFileName)
throws IOException {
this.selector = aSelector;
this.fileName = aFileName;
registerChannel();
}
private void registerChannel() throws IOException {
DatagramChannel theChannel = DatagramChannel.open();
theChannel.configureBlocking(false);
selector.wakeup();
theChannel.register(selector, SelectionKey.OP_READ);
sendRequest(Constants.OP_READ, Constants.ASCII_MODE, fileName,
theChannel, new InetSocketAddress(Constants.HOST,
Constants.TFTP_PORT));
}
#Override
public void run() {
process();
}
private void process() {
System.out.println("Download started for " + fileName + " ");
File theFile = new File(destinationFolder
+ fileName.substring(fileName.lastIndexOf("/")));
FileOutputStream theFout = null;
try {
theFout = new FileOutputStream(theFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (!isFileReadFinished) {
try {
if (selector.select() == 0) {
try {
// sleep 2sec was introduced because selector is
// thread safe but keys are not thread safe
Thread.sleep(2000);
} catch (InterruptedException e) {
continue;
}
continue;
}
Set<SelectionKey> theSet = selector.selectedKeys();
Iterator<SelectionKey> theSelectedKeys = theSet.iterator();
synchronized (theSelectedKeys) {
while (theSelectedKeys.hasNext()) {
SelectionKey theKey = theSelectedKeys.next();
theSelectedKeys.remove();
if (theKey.isReadable()) {
isFileReadFinished = read(theKey, theFout,
fileName);
if (!isFileReadFinished) {
theKey.interestOps(SelectionKey.OP_READ);
}
} else if (theKey.isWritable()) {
// there is no implementation for file write to
// server.
theKey.interestOps(SelectionKey.OP_READ);
}
}
}
} catch (IOException ie) {
ie.printStackTrace();
}
}
System.out.println("Download finished for " + fileName);
try {
if (selector.isOpen()) {
selector.close();
}
if (theFout != null) {
theFout.close();
}
} catch (IOException ie) {
}
}
}
/**
* #param aKey
* registered key for the selector
* #param aOutStream
* - file output stream to write the file contents.
* #return boolean
* #throws IOException
*/
private boolean read(SelectionKey aKey, OutputStream aOutStream,
String aFileName) throws IOException {
DatagramChannel theChannel = (DatagramChannel) aKey.channel();
// data packet
TFTPDataPacket theDataPacket = new TFTPDataPacket();
ByteBuffer theReceivedBuffer = theDataPacket.constructTFTPDataPacket();
SocketAddress theSocketAddress = theChannel.receive(theReceivedBuffer);
theReceivedBuffer.flip();
byte[] theBuffer = theReceivedBuffer.array();
byte[] theDataBuffer = theDataPacket.getDataBlock();
if (theDataPacket.getOpCode() == Constants.OP_DATA) {
int theLimit = theDataPacket.getLimit();
// checks the limit of the buffer because a packet with data less
// than 512 bytes of content signals that it is the last packet in
// transmission for this particular file
if (theLimit != Constants.MAX_BUFFER_SIZE
&& theLimit < Constants.MAX_BUFFER_SIZE) {
byte[] theLastBlock = new byte[theLimit];
System.arraycopy(theBuffer, 0, theLastBlock, 0, theLimit);
// writes the lastblock
aOutStream.write(theLastBlock);
// sends an acknowledgment to the server using TFTP packet
// block number
theChannel
.send(sendAckPacket((((theBuffer[2] & 0xff) << 8) | (theBuffer[3] & 0xff))),
theSocketAddress);
if (theChannel.isOpen()) {
theChannel.close();
}
return true;
} else {
aOutStream.write(theDataBuffer);
// sends an acknowledgment to the server using TFTP packet
// block number
theChannel
.send(sendAckPacket((((theBuffer[2] & 0xff) << 8) | (theBuffer[3] & 0xff))),
theSocketAddress);
return false;
}
} else if (Integer.valueOf(theBuffer[1]) == Constants.OP_ERROR) {
System.out.println("File : " + aFileName + " not found ");
handleError(theReceivedBuffer);
}
return false;
}
/**
* This method handles the error packet received from Server.
*
* #param aBuffer
*/
private void handleError(ByteBuffer aBuffer) {
// Error packet
new TFTPErrorPacket(aBuffer);
}
}
Is it possible to download multiple files in parallel using java.nio by not creating a thread per file download? If yes can anybody suggest a solution to proceed further.
I would provide an approach to achieve what you are aiming for :
Let L the list of files to be downloaded.
Create a Map M which will hold the mapping of File name to be downloaded and the corresponding Selector instance.
For each file F in L
Get Selector SK from M corresponding to F
Process the state of the Selector by checking for any of the events being ready.
If processing is complete then set the Selector corresponding to F as null. This will help in identifying files
whose
processing is completed.Alternatively, you can remove F from
L; so that the next time you are looping you only process files that are not yet completely downloaded.
The above being said, I am curious to understand why you would want to attempt such a feat? If the thought process behind this requirement is to reduce the number of threads to 1 then it is not correct. Remember, you would end up really taxing the single thread running and for sure your throughput would not necessarily be optimal since the single thread would be dealing with both network as well as disk I/O. Also, consider the case of encountering an exception while writing one of the several files to the disk - you would end up aborting the transfer for all the files; something I am sure you do not want.
A better and more scalable approach would be to poll selectors on a single thread, but hand off any I/O activity to a worker thread. A better approach still would be to read the techniques presented in Doug Lea's paper and implement them. In fact Netty library already implements this pattern and is widely used in production.
I've got a .mod file and I can run it in java(Using netbeans).
The file gets data from another file .dat, because the guy who was developing it used GUSEK. Now we need to implement it in java, but i dont know how to put data in the K constant in the .mod file.
Doesn't matter the way, can be through database querys or file reading.
I dont know anything about math programming, i just need to add values to the already made glpk function.
Here's the .mod function:
# OPRE
set K;
param mc {k in K};
param phi {k in K};
param cman {k in K};
param ni {k in K};
param cesp;
param mf;
var x {k in K} binary;
minimize custo: sum {k in K} (mc[k]*phi[k]*(1-x[k]) + cman[k]*phi[k]*x[k]);
s.t. recursos: sum {k in K} (cman[k]*phi[k]*x[k]) - cesp <= 0;
s.t. ocorrencias: sum {k in K} (ni[k] + (1-x[k])*phi[k]) - mf <= 0;
end;
And here's the java code:
package br.com.genera.service.otimi;
import org.gnu.glpk.*;
public class Gmpl implements GlpkCallbackListener, GlpkTerminalListener {
private boolean hookUsed = false;
public static void main(String[] arg) {
String[] nomeArquivo = new String[2];
nomeArquivo[0] = "C:\\PodaEquipamento.mod";
System.out.println(nomeArquivo[0]);
GLPK.glp_java_set_numeric_locale("C");
System.out.println(nomeArquivo[0]);
new Gmpl().solve(nomeArquivo);
}
public void solve(String[] arg) {
glp_prob lp = null;
glp_tran tran;
glp_iocp iocp;
String fname;
int skip = 0;
int ret;
// listen to callbacks
GlpkCallback.addListener(this);
// listen to terminal output
GlpkTerminal.addListener(this);
fname = arg[0];
lp = GLPK.glp_create_prob();
System.out.println("Problem created");
tran = GLPK.glp_mpl_alloc_wksp();
ret = GLPK.glp_mpl_read_model(tran, fname, skip);
if (ret != 0) {
GLPK.glp_mpl_free_wksp(tran);
GLPK.glp_delete_prob(lp);
throw new RuntimeException("Model file not found: " + fname);
}
// generate model
GLPK.glp_mpl_generate(tran, null);
// build model
GLPK.glp_mpl_build_prob(tran, lp);
// set solver parameters
iocp = new glp_iocp();
GLPK.glp_init_iocp(iocp);
iocp.setPresolve(GLPKConstants.GLP_ON);
// do not listen to output anymore
GlpkTerminal.removeListener(this);
// solve model
ret = GLPK.glp_intopt(lp, iocp);
// postsolve model
if (ret == 0) {
GLPK.glp_mpl_postsolve(tran, lp, GLPKConstants.GLP_MIP);
}
// free memory
GLPK.glp_mpl_free_wksp(tran);
GLPK.glp_delete_prob(lp);
// do not listen for callbacks anymore
GlpkCallback.removeListener(this);
// check that the hook function has been used for terminal output.
if (!hookUsed) {
System.out.println("Error: The terminal output hook was not used.");
System.exit(1);
}
}
#Override
public boolean output(String str) {
hookUsed = true;
System.out.print(str);
return false;
}
#Override
public void callback(glp_tree tree) {
int reason = GLPK.glp_ios_reason(tree);
if (reason == GLPKConstants.GLP_IBINGO) {
System.out.println("Better solution found");
}
}
}
And i'm getting this in the console:
Reading model section from C:\PodaEquipamento.mod...
33 lines were read
Generating custo...
C:\PodaEquipamento.mod:24: no value for K
glp_mpl_build_prob: invalid call sequence
Hope someone can help, thanks.
The best way would be to read the data file the same way you read the modelfile.
ret = GLPK.glp_mpl_read_data(tran, fname_data, skip);
if (ret != 0) {
GLPK.glp_mpl_free_wksp(tran);
GLPK.glp_delete_prob(lp);
throw new RuntimeException("Data file not found: " + fname_data);
}
I resolved just copying the data block from the .data file into the .mod file.
Anyway,Thanks puhgee.
So I am writing my own piece of stuff using jzmq GIT master branch and ZeroMQ 3.2.3.
After installation I tried to test the following simple PUB/SUB program, where a publisher and a subscriber talk in a single process. Since the test is under Windows, I used TCP.
public class ZMQReadynessTest {
private ZMQ.Context context;
#Before
public void setUp() {
context = ZMQ.context(1);
}
#Test
public void testSimpleMessage() {
String topic = "tcp://127.0.0.1:31216";
final AtomicInteger counter = new AtomicInteger();
// _____________________________________ create a simple subscriber
final ZMQ.Socket subscribeSocket = context.socket(ZMQ.SUB);
subscribeSocket.connect(topic);
subscribeSocket.subscribe("TestTopic".getBytes());
Thread subThread = new Thread() {
#Override
public void run() {
while (true) {
String value = null;
// This would result in trouble /\/\/\/\/\/\/\/\/\
{
ByteBuffer buffer = ByteBuffer.allocateDirect(100);
if (subscribeSocket.recvZeroCopy( buffer,
buffer.remaining(),
ZMQ.DONTWAIT
) > 0 ) {
buffer.flip();
value = buffer.asCharBuffer().toString();
System.out.println(buffer.asCharBuffer().toString());
}
}
// This works perfectly + + + + + + + + + + + + +
/*
{
byte[] bytes = subscribeSocket.recv(ZMQ.DONTWAIT);
if (bytes == null || bytes.length == 0) {
continue;
}
value = new String(bytes);
}
*/
if (value != null && value.length() > 0) {
counter.incrementAndGet();
System.out.println(value);
break;
}
}
}
};
subThread.start();
// _____________________________ create a simple publisher
ZMQ.Socket publishSocket = context.socket(ZMQ.PUB);
publishSocket.bind("tcp://*:31216");
try {
Thread.sleep(3000); // + wait 3 sec to make sure its ready
} catch (InterruptedException e) {
e.printStackTrace();
fail();
}
// publish a sample message
try {
publishSocket.send("TestTopic".getBytes(), ZMQ.SNDMORE);
publishSocket.send("This is test string".getBytes(), 0);
subThread.join(100);
} catch (InterruptedException e) {
e.printStackTrace();
fail();
}
assertTrue(counter.get() > 0);
System.out.println(counter.get());
}
}
Now as you can see, in the subscriber if I use a simple .recv(ZMQ.DONTWAIT) method, it works perfectly. However, if I am using the direct byte buffer I got nothing returned - and I got the following exception, seems like on program exit:
Exception in thread "Thread-0" org.zeromq.ZMQException: Resource temporarily unavailable(0xb)
at org.zeromq.ZMQ$Socket.recvZeroCopy(Native Method)
at ZMQReadynessTest$1.run(ZMQReadynessTest.java:48)
I also tried to use a simple ByteBuffer (not a direct buffer), which doesn't throw the exception above; but also return me nothing.
Does anybody know how to resolve the above?
I don't want to create byte[] objects all around, as I am doing some high performance system. If this cannot be resolved, I might simply use Unsafe instead. But I really want to work in the "supposed way".
Thanks in advance.
Alex
I have written the following code for a program which could measure the total data usage of the computer. I have used the method getTotalSize() of the class PcapPacket. Is it directly indicative of the data usage (if added continuously) or should I use some other method.
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.protocol.JProtocol;
public class CapturePacket{
public static void main(String[] args) throws Exception {
List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with
// NICs
StringBuilder errbuf = new StringBuilder(); // For any error msgs
int r = Pcap.findAllDevs(alldevs, errbuf);
if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
System.err.printf("Can't read list of devices, error is %s", errbuf
.toString());
return;
}
PcapIf device = (PcapIf) alldevs.get(0); // We know we have at least 1 device
String ad = device.getHardwareAddress().toString();
System.out.println("\nCurrently open adapter MAC:" + ad);
int snaplen = 64 * 1024; // Capture all packets, no truncation
int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
int timeout = 10; //10*1000; // No timeout, non-interactive traffic
final Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout,
errbuf);
if (pcap == null) {
System.err.printf("Error while opening device for capture: "
+ errbuf.toString());
return;
}
PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>()
{
long total_traffic = 0,count = 0;
int i;
public void nextPacket(PcapPacket packet, String user) {
count += packet.getTotalSize();
if( count>1048576 )
{
i++;
total_traffic += count;
System.out.println(i+"MB"+"\t total:"+total_traffic);
count=count-1048576;
}
};
};
pcap.loop(-1,jpacketHandler," ");
pcap.close();
}
}
The above is a code I've written in an attempt to count the traffic passing through the network. Is it directly indicative (if not perfectly accurate) of the data usage of the computer?
You should use
packet.getPacketWirelen()
According to the documentation, it gets the original length as seen on the wire, even if the captured packet is truncated.
Additionally you should check if the packet is from or to your internal network only, so then it shouldn't count towards your data usage(I'm assuming you want data usage as seen by your ISP).
After that it should be indicative of your data usage.