Capture ping packets throws exception (too many instances) - java

I have written a code snippet to cpature ping using JPCAP. the code I have written is given below :
while (true) {
try {
PacketCapture m_pcap;
m_pcap = new PacketCapture();
m_pcap.open("\\Device\\NPF_{007262BD-....-7EE83D72EBEA}",true);//param 1 is actual device ID
m_pcap.setFilter("proto ICMP", true);
pktlistener a = new pktlistener(); //handles the packet
m_pcap.addPacketListener(a);
System.out.println("going to sleep");
Thread.sleep(1 * 1000);// Waiting for 1 second before ending capture
System.out.println("woken up");
m_pcap.removePacketListener(a);
m_pcap.endCapture();
m_pcap.close();
a = null;
m_pcap = null;
} catch (Exception e) {
e.printStackTrace();
}
}
Now the above code starts a new capture after every one second. The problem with the above is that after 10 runs of the loop, it throws the exception :
Exception in thread "Thread-6" java.lang.Error: Too many instances, exceeds 10
at net.sourceforge.jpcap.capture.PacketCapture.<init>(PacketCapture.java:51)
Q1. How do i prevent this. I need to start a new PacketCapture every second.
Q2. Is there any other simpler way to capture ping messages recived on a system through java?

You cannot use the constructor of PacketCapture more than ten times. This behavior is hardcoded as the constructor looks like this:
/**
* Create a new packet capture instance.
*/
public PacketCapture() {
if (nextInstance >= INSTANCE_MAX) {
throw new Error("Too many instances, exceeds " + INSTANCE_MAX);
}
instanceNum = nextInstance++;
}
To capture ping requests, you should try the following code
public class Main {
public static void main(String[] args) throws CaptureDeviceLookupException {
Capture cap = new Capture();
cap.doCapture();
}
}
class PingListener implements PacketListener {
#Override
public void packetArrived(Packet packet) {
try {
// only ICMP packages
if (packet instanceof ICMPPacket) {
ICMPPacket tcpPacket = (ICMPPacket) packet;
int data = tcpPacket.getMessageCode();
// only echo request packages
if (data == ICMPMessages.ECHO) {
// print source and destination.
String srcHost = tcpPacket.getSourceAddress();
String dstHost = tcpPacket.getDestinationAddress();
System.out.println("Ping from: " + srcHost + " to " + dstHost);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Capture {
public void doCapture() {
// create capture instance
PacketCapture capture = new PacketCapture();
// add listener that handles incomming and outgoing packages
PingListener pingListener = new PingListener();
capture.addPacketListener(pingListener);
// m_pcap.setFilter("filter here or in handler", true);
try {
capture.open("\\Device\\NPF_{...}", true); // connect capture to device
while (true) {
capture.capture(1); // capture one package
}
} catch (Exception e) {
e.printStackTrace(); // exception during capture or handling of
// packages
} finally {
// technically never reached as the loop goes on forever.
// if loop terminates after a while then:
// remove listener
capture.removePacketListener(pingListener);
// end capture (only necessary, if PacketCapture still waits for
// other packages)
capture.endCapture();
// close connection to capture device
capture.close();
}
}
}
I think there is a misunderstanding of the class PacketCapture. It does not actually capture one package and is then discarded. It opens a connection to the device you want to capture packages of and then starts listening for as long as you hold that connection. You then start capturing n packages by calling capture.capture(n). For each package arriving while "capture" blocks your program, the listener is called.
Alternatively you can drop the while-loop and use capture.capture(-1). This will block your program forever until you close the capture from another device.

Related

How to create a Socket connection between Unity/C# Server and Android/Java Client?

I'm working on an academic project that consists in controlling a simulated environment created in Unity3D, from a conventional Android application. I already created the scenario in Unity and the mobile application is completely finished, my problem is in the connection. I chose to use sockets because of its simplicity. I managed to connect the application to a server written in C # through conventional Sockets, I know that information can be sent, but when I implemented it in Unity, everything failed, so I decided to use TCP Listener instead of Sockets in Unity / C # (the client Android still uses a conventional TCP connection through Sockets), and in effect, the application connects but there is no information transfer, because the Unity console throws an error that says: ObjectDisposedException: Can not access to disposed object.
Object name: 'System.Net.Sockets.TcpClient'.(The error is presented in line number 56: stream = client.tcp.GetStream ();) The main objective is to obtain the flow of information that would be represented in something like: "1: 0: 1: 0" and being able to make a Split to that string and according to that value change the state of a light bulb or other element, nevertheless I need the essential thing: to establish the connection flow. I'm not an expert in C # and much less using Unity, I really do not know much about design, but I wanted to do it to deliver an innovative work, I hope someone can guide me.
PD: C# Socket (No Unity yet) server working with Android Java client:
![1] https://imgur.com/a/HuNcDC3
//This is my Unity3D/C# Server:
public class SocketManager : MonoBehaviour
{
private List<ServerClient> connectedClients;
private List<ServerClient> disconectedClients;
private TcpListener server;
private string data;
private NetworkStream stream;
private StreamReader stremaReader;
private bool serverStarted;
public int socketPort = 7691;
private void Start()
{
connectedClients = new List<ServerClient>();
disconectedClients = new List<ServerClient>();
try
{
server = new TcpListener(IPAddress.Parse("192.168.1.64"), socketPort);
server.Start();
serverListening();
serverStarted = true;
Debug.Log("Server started. Port: " + socketPort.ToString());
}
catch (Exception ex)
{
Debug.Log("Server socket error: " + ex);
}
}
private void Update()
{
if (!serverStarted)
return;
foreach (ServerClient client in connectedClients)
{
if (IsConnected(client.tcp))
{
client.tcp.Close();
disconectedClients.Add(client);
continue;
}
else
{
stream = client.tcp.GetStream();
if (stream.DataAvailable)
{
this.stremaReader = new StreamReader(stream, true);
data = stremaReader.ReadLine();
if (data != null)
OnIcomingData(client, data);
}
}
}
}
private void OnIcomingData(ServerClient client, string data)
{
Debug.Log(client.clientName + ": " + data);
}
private bool IsConnected(TcpClient tcp)
{
try
{
if (tcp != null && tcp.Client != null && tcp.Client.Connected)
{
if (tcp.Client.Poll(0, SelectMode.SelectRead))
{
return !(tcp.Client.Receive(new byte[1], SocketFlags.Peek) == 0);
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
private void serverListening()
{
server.BeginAcceptTcpClient(AcceptTcpClient, server);
}
private void AcceptTcpClient(IAsyncResult asyncResult)
{
TcpListener tcplistener = (TcpListener)asyncResult.AsyncState;
connectedClients.Add(new ServerClient(tcplistener.EndAcceptTcpClient(asyncResult)));
serverListening();
}
}
public class ServerClient
{
public TcpClient tcp;
public string clientName;
public ServerClient(TcpClient tcp)
{
this.tcp = tcp;
this.clientName = "Android";
}
}
// This is my Android/Java Client:
public class SocketThread extends Thread {
private Socket adviser;
private DataOutputStream dataOut;
#Override
public void run() {
super.run();
Log.e("Status:", "Thread started");
try {
adviser = new Socket("192.168.1.64", 7691);
dataOut = new DataOutputStream(adviser.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(SocketThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendCommand(String text) {
try {
dataOut.writeUTF(text);
Log.e("Sended Text: ", text);
} catch (IOException ex) {
Logger.getLogger(SocketThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
Here's a more detailed answer than my comment, for future reference.
The problem lies in the following if check if (IsConnected(client.tcp)).
Right now what is happening is that when the client is connected to the server (so the if returns true) you are Closing the connection using client.tcp.Close(); and adding the connection to your disconectedClients list (But you are not removing the client from your connectedClients list! Meaning the client is now in both lists). Then when the next iteration of the foreach loop foreach (ServerClient client in connectedClients) comes around the if (IsConnected(client.tcp)) will return false (the client is no longer connected to the server, since you called close() in the previous iteration.
You then try to call stream = client.tcp.GetStream(); on a stream that is already closed, resulting in an error telling you you cannot get the stream.
This should fix it:
if (IsConnected(client.tcp))
{
client.tcp.Close();
client.tcp.Dispose(); //Dispose of a stream to release it for GC
disconectedClients.Add(client);
connectedClients.Remove(client); //Note to also remove the disconnected client from the connectedClients list.
continue;
}
else
{ ...rest of logic }
Note that i added connectedClients.Remove(client); and client.tcp.Dispose(); to your logic closing the stream. If you don't do this it'll keep getting included in theforeachloop unnecessarily, and the programm will try to callclose()` on a connection that is already closed, resulting in more errors. Disposing of the stream will release it so the garbage collector can collect it, freeing up memory.

Stellar Payment code not working in Java

I have referred documentation on Stellar.
Then I have started to run the send payment and receiving payment code after creating an account in Java.
Send payment code is working , but receiving payment code got terminated. I have mentioned code below :
public class receivePayment {
public static void main(String args[]) {
Server server = new Server("https://horizon-testnet.stellar.org");
KeyPair account = KeyPair.fromAccountId("GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF");
// Create an API call to query payments involving the account.
PaymentsRequestBuilder paymentsRequest = server.payments().forAccount(account);
// If some payments have already been handled, start the results from
// the
// last seen payment. (See below in `handlePayment` where it gets
// saved.)
/*
* String lastToken = loadLastPagingToken(); if (lastToken != null) {
* paymentsRequest.cursor(lastToken); }
*/
// `stream` will send each recorded payment, one by one, then keep the
// connection open and continue to send you new payments as they occur.
paymentsRequest.stream(new EventListener<OperationResponse>() {
#Override
public void onEvent(OperationResponse payment) {
// Record the paging token so we can start from here next time.
// savePagingToken(payment.getPagingToken());
// The payments stream includes both sent and received payments.
// We only
// want to process received payments here.
if (payment instanceof PaymentOperationResponse) {
if (((PaymentOperationResponse) payment).getTo().equals(account)) {
return;
}
String amount = ((PaymentOperationResponse) payment).getAmount();
Asset asset = ((PaymentOperationResponse) payment).getAsset();
String assetName;
if (asset.equals(new AssetTypeNative())) {
assetName = "lumens";
} else {
StringBuilder assetNameBuilder = new StringBuilder();
assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getCode());
assetNameBuilder.append(":");
assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getIssuer().getAccountId());
assetName = assetNameBuilder.toString();
}
StringBuilder output = new StringBuilder();
output.append(amount);
output.append(" ");
output.append(assetName);
output.append(" from ");
output.append(((PaymentOperationResponse) payment).getFrom().getAccountId());
System.out.println(output.toString());
}
}
});
}
}
I don't understand why it gets terminated. If I checked the balance from my account URL, but shows me the sending-receiving result, but it is not showing result in Eclipse.
I have also referred below reference link and follow the answer but still it is not working.
Stellar payments query
Can anyone tell me how to run this code which continuously receive the payments and maintain the logs on console. ?
The thing is this is a streaming service, so if you just run the service in main method then it will obviously terminated while running in main method and the scope will go outside and EventListener will not be able to be executed. As you said you are using eclips,one thing you can do is instead of run try debug and insert a debugpoint at this Server server = new Server("https://horizon-testnet.stellar.org"); line and press F6 and go one by one line. While debugging Once it reaches the last line of the program then wait,don't run. You will see the data in the console. this way you will understand how the program is working.
If you want to run it fast then use the code that I have added with the existing code. I have added two options. you can use any of this. This will display the output.
public class TestStellar2 {
public static void main(String args[]) {
Server server = new Server("https://horizon-testnet.stellar.org");
KeyPair account = KeyPair.fromAccountId("GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF");
PaymentsRequestBuilder paymentsRequest = server.payments().forAccount(account);
paymentsRequest.stream(new EventListener <OperationResponse>(){
#Override
public void onEvent(OperationResponse payment) {
if (payment instanceof PaymentOperationResponse) {
if (((PaymentOperationResponse) payment).getTo().equals(account)) {
return;
}
String amount = ((PaymentOperationResponse) payment).getAmount();
Asset asset = ((PaymentOperationResponse) payment).getAsset();
String assetName;
if (asset.equals(new AssetTypeNative())) {
assetName = "lumens";
} else {
StringBuilder assetNameBuilder = new StringBuilder();
assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getCode());
assetNameBuilder.append(":");
assetNameBuilder.append(((AssetTypeCreditAlphaNum) asset).getIssuer().getAccountId());
assetName = assetNameBuilder.toString();
}
StringBuilder output = new StringBuilder();
output.append(amount);
output.append(" ");
output.append(assetName);
output.append(" from ");
output.append(((PaymentOperationResponse) payment).getFrom().getAccountId());
System.out.println(output.toString());
}
}
});
/**
* option 1
*
*/
/*try {
System.in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
/**
* option 2
*/
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The output will look like below :
10.0000000 lumens from GC2BKLYOOYPDEFJKLKY6FNNRQMGFLVHJKQRGNSSRRGSMPGF32LHCQVGF many line like this

Issue initializing jFrame

I'm creating a client window that retrieves from a javaSpace, this is the code I'm using.
/**
* Create the frame.
*/
public Client()
{
space = SpaceUtils.getSpace();
if (space == null)
{
System.err.println("Failed to find the javaspace");
System.exit(1);
}
initFrame();
setVisible(true);
processPrintJobs();
}
The window is generated inside of initFrame(); and then processPrintJobs checks to see if there are any new messages. If I comment out the processPrintJobs() method call then the window draws correctly but if the method call is there, the window just shows a blank square.
Its like the window is not being created correctly due to the process being checked lots of times, which makes no sense as the window is created before the while loop is run.
public void processPrintJobs()
{
while (true)
{
try
{
Message template = new Message();
if (channel == null)
{
System.out.println("No channel given");
} else
{
template.Channel = channel;
// System.out.println(channel);
template.position = new Integer(getNumber() + 1);
Message msg = (Message) space.read(template, null,
Long.MAX_VALUE);
messageList.append(msg.execute());
}
} catch (Exception e)
{
e.printStackTrace();
}
}
}
This infinite while loop will block the EDT.
while (true)
Simply calling
setVisible(true);
does not guarantee that the JFrame will be painted immediately. Any long-lived processes should be handled by a SwingWorker.
Use
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
processPrintJobs();
}
}
But in general, the architecture of your application is missing some aspects.
Like a thread or whatever.
More:
You could for instance use a swing Timer, for one single job every tick.
import javax.swing.Timer;
To be called at the end of the Client constructor.
Timer printJobsTimer = new Timer(100, new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Process a print job:
if (channel != null) {
Message template = new Message();
template.Channel = channel;
template.position = new Integer(getNumber() + 1);
Message msg = (Message) space.read(template, null,
Long.MAX_VALUE);
messageList.append(msg.execute());
}
}
});
printJobsTimer.setInitialDelay(100);
printJobsTimer.start();
For the rest, consisting naming would have been fine: just class names starting with a capital and other names with a small letter.

Telling a ThreadPoolExecutor when it should go ahead or not

I have to send a set of files to several computers through a certain port. The fact is that, each time that the method that sends the files is called, the destination data (address and port) is calculated. Therefore, using a loop that creates a thread for each method call, and surround the method call with a try-catch statement for a BindException to process the situation of the program trying to use a port which is already in use (different destination addresses may receive the message through the same port) telling the thread to wait some seconds and then restart to retry, and keep trying until the exception is not thrown (the shipping is successfully performed).
I didn't know why (although I could guess it when I first saw it), Netbeans warned me about that sleeping a Thread object inside a loop is not the best choice. Then I googled a bit for further information and found this link to another stackoverflow post, which looked so interesting (I had never heard of the ThreadPoolExecutor class). I've been reading both that link and the API in order to try to improve my program, but I'm not yet pretty sure about how am I supposed to apply that in my program. Could anybody give a helping hand on this please?
EDIT: The important code:
for (Iterator<String> it = ConnectionsPanel.list.getSelectedValuesList().iterator(); it.hasNext();) {
final String x = it.next();
new Thread() {
#Override
public void run() {
ConnectionsPanel.singleAddVideos(x);
}
}.start();
}
private static void singleAddVideos(String connName) {
String newVideosInfo = "";
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
newVideosInfo = newVideosInfo.concat(it.next().toString());
}
try {
MassiveDesktopClient.sendMessage("hi", connName);
if (MassiveDesktopClient.receiveMessage(connName).matches("hello")) {
MassiveDesktopClient.sendMessage(newVideosInfo, connName);
}
} catch (BindException ex) {
MassiveDesktopClient.println("Attempted to use a port which is already being used. Waiting and retrying...", new Exception().getStackTrace()[0].getLineNumber());
try {
Thread.sleep(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS * 1000);
} catch (InterruptedException ex1) {
JOptionPane.showMessageDialog(null, ex1.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
ConnectionsPanel.singleAddVideos(connName);
return;
}
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
try {
MassiveDesktopClient.sendFile(it.next().getAttribute("name"), connName);
} catch (BindException ex) {
MassiveDesktopClient.println("Attempted to use a port which is already being used. Waiting and retrying...", new Exception().getStackTrace()[0].getLineNumber());
try {
Thread.sleep(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS * 1000);
} catch (InterruptedException ex1) {
JOptionPane.showMessageDialog(null, ex1.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
ConnectionsPanel.singleAddVideos(connName);
return;
}
}
}
Your question is not very clear - I understand that you want to rerun your task until it succeeds (no BindException). To do that, you could:
try to run your code without catching the exception
capture the exception from the future
reschedule the task a bit later if it fails
A simplified code would be as below - add error messages and refine as needed:
public static void main(String[] args) throws Exception {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(corePoolSize);
final String x = "video";
Callable<Void> yourTask = new Callable<Void>() {
#Override
public Void call() throws BindException {
ConnectionsPanel.singleAddVideos(x);
return null;
}
};
Future f = scheduler.submit(yourTask);
boolean added = false; //it will retry until success
//you might use an int instead to retry
//n times only and avoid the risk of infinite loop
while (!added) {
try {
f.get();
added = true; //added set to true if no exception caught
} catch (ExecutionException e) {
if (e.getCause() instanceof BindException) {
scheduler.schedule(yourTask, 3, TimeUnit.SECONDS); //reschedule in 3 seconds
} else {
//another exception was thrown => handle it
}
}
}
}
public static class ConnectionsPanel {
private static void singleAddVideos(String connName) throws BindException {
String newVideosInfo = "";
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
newVideosInfo = newVideosInfo.concat(it.next().toString());
}
MassiveDesktopClient.sendMessage("hi", connName);
if (MassiveDesktopClient.receiveMessage(connName).matches("hello")) {
MassiveDesktopClient.sendMessage(newVideosInfo, connName);
}
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
MassiveDesktopClient.sendFile(it.next().getAttribute("name"), connName);
}
}
}

Migrating application made with Processing.org to Eclipse

I made a simple program in Processing, and it works great. Im now attempting to bring my beginner Java skills to Eclipse to make the same program over again. The program takes a Rs232 string that comes from the Com port and sends it over Xmpp.
The issue I'm having is that i cant call newChat.sendMessage(message) like i can in processing from any of the Classes/Tabs. Can someone clue me in to what i should look for to fix this issue. I'm guessing Extending, or implementing the Xmpp class is what i need to do. I love how simple processing handles it..
Any help will be greatly appreciated.
Fyi: the Smack library's are in the code folder for processing.
Main Application:
import processing.net.*;
void setup() {
size(400, 200);
noStroke();
background(0);
LoadSerialPort();
OpenChatConnection();
setupFilterThread ();
}
void draw() {
}
String timestampTime() {
Calendar now = Calendar.getInstance();
return String.format("%1$tH:%1$tM:%1$tS", now);
}
String timestampDate() {
Calendar now = Calendar.getInstance();
return String.format("%1$tm/%1$td/%1$tY", now);
}
Filter Class/Tab:
FilterThread thread1;
List FilteredArchAddressList = new ArrayList();
ArrayList CallList = new ArrayList();
void setupFilterThread () {
thread1 = new FilterThread(100, "a");
thread1.start();
}
void checkForNewCalls() {
if (CallList.size() >=1) {
println("New Call In List, Size: "+CallList.size());
FilterComPortString((String) CallList.get(0));
CallList.remove(0);
}
}
void FilterComPortString(String s) {
Message message = new Message("icu1#broadcast.server", Message.Type.normal);
//message.setTo("icu1#broadcast.x-dev");
message.setSubject("MSG_TYPE_NORMAL");
message.setBody(s);
message.setProperty("systemID", "JS1");
message.setProperty("serverTime", trim(timestampTime()));
message.setProperty("serverDate", trim(timestampDate()));
try {
newChat.sendMessage(message);
}
catch (Exception e) {
println(e);
}
}
}
class FilterThread extends Thread {
boolean running; // Is the thread running? Yes or no?
int wait; // How many milliseconds should we wait in between executions?
String id; // Thread name
int count; // counter
// Constructor, create the thread
// It is not running by default
FilterThread (int w, String s) {
wait = w;
running = false ;
id = s;
count = 0;
}
int getCount() {
return count;
}
// Overriding "start()"
void start () {
// Set running equal to true
running = true ;
// Print messages
println ("Starting thread (will execute every " + wait + " milliseconds.)");
// Do whatever start does in Thread, don't forget this!
super .start();
}
// We must implement run, this gets triggered by start()
void run () {
while (running) {
checkForNewCalls();
// Ok, let's wait for however long we should wait
try {
sleep((long )(wait));
}
catch (Exception e) {
}
}
System.out.println (id + " thread is done!"); // The thread is done when we get to the end of run()
}
// Our method that quits the thread
void quit() {
System.out.println ("Quitting.");
running = false ; // Setting running to false ends the loop in run()
// IUn case the thread is waiting. . .
interrupt();
}
}
Rs232 Class/Tab:
import processing.serial.*;
Serial myPort; // Rs232, Serial Port
String inString; // Input string from serial port:
int lf = 10; // ASCII linefeed
String SelectedCom;
void LoadSerialPort() {
println(Serial.list());
println("________________________________________________________");
try {
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil(lf);
SelectedCom = Serial.list()[0];
println("Connected to Serial Port:");
println("________________________________________________________");
}
catch (ArrayIndexOutOfBoundsException e) {
String exception = e.toString();
if (exception.contains("ArrayIndexOutOfBoundsException: 0")) {
println("NO AVAILABLE COM PORT FOUND");
}
else {
println(e);
}
}
}
void serialEvent(Serial p) {
inString = p.readString();
CallList.add(new String(inString));
}
Xmpp Class/Tab:
String FromXmpp = "";
Chat newChat;
ChatManager chatmanager;
XMPPConnection connection;
public void OpenChatConnection() {
// This is the connection to google talk. If you use jabber, put other stuff in here.
ConnectionConfiguration config = new ConnectionConfiguration("192.168.0.103", 5222, "Jabber/XMPP");
config.setSASLAuthenticationEnabled(false);
configure(ProviderManager.getInstance());
connection = new XMPPConnection(config);
println("Connecting");
try {
//connection.DEBUG_ENABLED = true;
connection.connect();
println("Connected to: "+connection.getServiceName() );
}
catch (XMPPException e1) {
println("NOT Connected");
}
if (connection.isConnected()) {
try {
// This is the username and password of the chat client that is to run within Processing.
println("Connecting");
connection.login("System1", "test");
//connection.login("inside_processing_username#gmail.com", "yourpassword");
}
catch (XMPPException e1) {
// would probably be a good idea to put some user friendly action here.
e1.printStackTrace();
}
println("Logged in as: "+connection.getUser() );
}
chatmanager = connection.getChatManager();
// Eventhandler, to catch incoming chat events
newChat = chatmanager.createChat("icu#broadcast.server", new MessageListener() { //icu1#broadcast.x-dev //admin#x-dev
public void processMessage(Chat chat, Message message) {
// Here you do what you do with the message
FromXmpp = message.getBody();
// Process commands
//println(FromXmpp);
}
}
);
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry entry : entries) {
System.out.println(entry);
}
}
public void configure(ProviderManager pm) {
// Private Data Storage
pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
// Time
try {
pm.addIQProvider("query", "jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
}
catch (ClassNotFoundException e) {
println(("TestClient "+" Can't load class for org.jivesoftware.smackx.packet.Time"));
}
// Roster Exchange
pm.addExtensionProvider("x", "jabber:x:roster", new RosterExchangeProvider());
// Message Events
pm.addExtensionProvider("x", "jabber:x:event", new MessageEventProvider());
// Chat State
pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("composing", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
// XHTML
pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
// Group Chat Invitations
pm.addExtensionProvider("x", "jabber:x:conference", new GroupChatInvitation.Provider());
// Service Discovery # Items
pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
// Service Discovery # Info
pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
// Data Forms
pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
// MUC User
pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider());
// MUC Admin
pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
// MUC Owner
pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
// Delayed Delivery
pm.addExtensionProvider("x", "jabber:x:delay", new DelayInformationProvider());
// Version
try {
pm.addIQProvider("query", "jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
}
catch (ClassNotFoundException e) {
// Not sure what's happening here.
}
// VCard
pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
// Offline Message Requests
pm.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
// Offline Message Indicator
pm.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
// Last Activity
pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
// User Search
pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
// SharedGroupsInfo
pm.addIQProvider("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup", new SharedGroupsInfo.Provider());
// JEP-33: Extended Stanza Addressing
pm.addExtensionProvider("addresses", "http://jabber.org/protocol/address", new MultipleAddressesProvider());
// FileTransfer
pm.addIQProvider("si", "http://jabber.org/protocol/si", new StreamInitiationProvider());
pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
// Privacy
pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());
pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.MalformedActionError());
pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadLocaleError());
pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadPayloadError());
pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadSessionIDError());
pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.SessionExpiredError());
}
If you know your way around eclipse, first you need to create a new Java project and add Processing's core.jar to the build path and start by creating a sublcass of PApplet. If not, there's a really easy to work with eclipse plugin called Proclipsing and video guide to get started with it.
Bringing your code from Processing to eclipse:
You need to understand that all the code you have in a Processing sketch (including tabs) gets merged into a single .java file and the sketch name is the class name. Any classes you define in tabs in the sketch become nested classes in a main single class. Easiest way to see this is to export an applet and have a look in the generated folder for the SketchName.java file. Remember, a tab is not a class (although it can contain one).
So you've got a few options. Here are two basic approaches:
Create a new PApplet subclass and start pasting your whole code in it (including content of tabs). You will need to de explicit about accessors (e.g. public void setup() instead of just void setup()) and be careful with double/float values (e.g. if eclipse complains about 1.0, be explicit: 1.0f)
The other option is to create multiple classes, as I imagine you intend to do if you're using eclipse. The catch is, in Processing, variables defined in tabs are actually 'global' variables. Your code would work the same way if you declare those in the main tab at the top. Also, using PApplet functions needs to be refactored. Some functions can be called using Java's classes (not PApplet's) to break the dependency: e.g. System.out.println() instead of println(), but of others you might want your classes to have access to a PApplet instance:
e.g.
public class FilterThread extends Thread {
boolean running; // Is the thread running? Yes or no?
int wait; // How many milliseconds should we wait in between executions?
String id; // Thread name
int count; // counter
YourSketchClass parent;
// Constructor, create the thread
// It is not running by default
FilterThread (int w, String s,YourSketchClass p) {
wait = w;
running = false ;
id = s;
count = 0;
parent = p;
}
int getCount() {
return count;
}
// Overriding "start()"
public void start () {
// Set running equal to true
running = true ;
// Print messages
System.out.println ("Starting thread (will execute every " + wait + " milliseconds.)");
// Do whatever start does in Thread, don't forget this!
super .start();
}
// We must implement run, this gets triggered by start()
public void run () {
while (running) {
parent.checkForNewCalls();
// Ok, let's wait for however long we should wait
try {
sleep((long )(wait));
}
catch (Exception e) {
}
}
System.out.println (id + " thread is done!"); // The thread is done when we get to the end of run()
}
// Our method that quits the thread
void quit() {
System.out.println ("Quitting.");
running = false ; // Setting running to false ends the loop in run()
// IUn case the thread is waiting. . .
interrupt();
}
}
Every class which uses the chat-functionality, needs to know the chat-object. You can put all your variables and functions which are not in a separate class in the main source-file.
When you declare a variable in Processing, it can be used from any tab, in java global variables do not exist. You can get a similar functionality like this: Create a new file GlobalVars.java with this content:
public class GlobalVars {
public static Chat myChat;
}
Now everytime you want to access the Chat-functions, you have to write e.g. GlobalVars.myChat.sendMessage("Hi!");
Btw, You have to include the net.jar-file. On Mac this is located here:
Processing.app/Contents/Resources/Java/modes/java/libraries/net/library/net.jar

Categories