Rectify JMF Video Capture - java

I saw the following code in stackoverflow.com and copied to my system submitted by you on JMF:
import Logging.LogRunner; //Logging.LogRunner is absent s error occurs
import java.util.Vector;
import java.awt.*;
import java.awt.event.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import javax.media.datasink.*;
import javax.swing.JButton;
import javax.swing.JOptionPane;
/**
* Records audio and video from a usb camera and saves it to disk. Essentially what is happening
* is we are creating two video streams and an audio stream. We use two video streams
* so one can be sent to the file, and the other can be sent to the gui to show the
* user what they are currently recording. This class is configured to use a certain
* audio and video format, but this can easily be changed to fit dirrenet needs.
* This class was created with
* help from http://www.codeproject.com/KB/audio-video/Java_Video_Capture.aspx.
* Please refer to that site for more information.
* #author dvargo
*/
public class VideoRecorder
{
/**
* The source of the video stream
*/
CaptureDeviceInfo device = null;
/**
* The location of media content
*/
MediaLocator ml = null;
/**
* MediaHandler for rendering and controlling time based media data
*/
Player player = null;
/**
* The screen that will display the video as it is being recorded
*/
Component videoScreen = null;
/**
* The Processor processes data and creates an output in the destination
* format required
*/
Processor processor = null;
/**
* takes a DataSource as input and renders the output to a specified destination
*/
DataSink dataSink = null;
/**
*
*/
TheDataSinkListener dataSinkListener = null;
/**
* The form for the video and other gui compoenents
*/
Frame frm = null;
/**
* A reference to the Starter class.
*/
VideoStarter theForm = null; //VideoStarter does not exist so error occurs
/**
* Used to determine if something went wrong
*/
boolean error = false;
/**
* Basic Constructor to begin recording video to a specified file path. This
* constructor initalizes everything needed to begin recording.
* #param saveFileTo The path and file name of where to save the video.
* #param inForm Reference to the Starter class that initatied this recording.
*/
public VideoRecorder(String saveFileTo,VideoStarter inForm)
{
theForm = inForm;
try
{
//gets a list of devices how support the given video format
Vector deviceList = CaptureDeviceManager.getDeviceList(new YUVFormat());
//if we couldnt find anything to record from
if(deviceList.size() == 0)
{
LogRunner.dialogMessage(this.getClass(),"No video capture devices could be found.");
error = true;
return;
}
// get video device - the first one is almost always the only available camera
device = (CaptureDeviceInfo) deviceList.firstElement();
ml = device.getLocator();
//create a source from the device
DataSource ods = null;
ods = Manager.createDataSource(ml);
/*
* Clone the video source so it can be displayed and used to capture
* the video at the same time. Trying to use the same source for two
* purposes would cause a "source is in use" error
*/
DataSource cloneableDS = Manager.createCloneableDataSource(ods);
DataSource PlayerVidDS = cloneableDS;
// The video capture code will use the clone which is controlled by the player
DataSource CaptureVidDS = ((javax.media.protocol.SourceCloneable) cloneableDS).createClone();
/*
* Display video by starting the player on the source clonable data source
* the clones are fed data stopping the player will stop the video flow
* to the clone data source
*/
player = Manager.createRealizedPlayer(PlayerVidDS);
player.start();
// get an audio device and create an audio data source
deviceList = CaptureDeviceManager.getDeviceList(new javax.media.format.AudioFormat(null));
device = (CaptureDeviceInfo) deviceList.firstElement();
ml = device.getLocator();
DataSource audioDataSource = Manager.createDataSource(ml);
// merge audio and video data sources
DataSource mixedDataSource = null;
DataSource dsArray[] = new DataSource[2];
dsArray[0] = CaptureVidDS; // this is a cloned datasource and is controlled by the master clonable data source
dsArray[1] = audioDataSource;
try
{
mixedDataSource = javax.media.Manager.createMergingDataSource(dsArray);
}
catch (Exception e)
{
//exception handling here
error = true;
System.out.println("Error 1");
e.printStackTrace();
}
// setup output file format to msvideo
FileTypeDescriptor outputType = new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);
// setup output video and audio data format
Format outputFormat[] = new Format[2];
//outputFormat[0] = new VideoFormat(VideoFormat.RGB);
outputFormat[0] = new VideoFormat(VideoFormat.YUV);
outputFormat[1] = new AudioFormat(AudioFormat.LINEAR);
// create a new processor
ProcessorModel processorModel = new ProcessorModel(mixedDataSource, outputFormat, outputType);
try
{
processor = Manager.createRealizedProcessor(processorModel);
}
catch (Exception e) {
// exception handling here
error = true;
System.out.println("Error 2");
e.printStackTrace();
}
try
{
// get the output of the processor to be used as the datasink input
DataSource source = processor.getDataOutput();
// create a File protocol MediaLocator with the location of the file to which bits are to be written
MediaLocator mediadestination = new MediaLocator("file:" + saveFileTo);
// create a datasink to create the video file
dataSink = Manager.createDataSink(source, mediadestination);
// create a listener to control the datasink
dataSinkListener = new TheDataSinkListener();
dataSink.addDataSinkListener(dataSinkListener);
dataSink.open();
// now start the datasink and processor
dataSink.start();
processor.start();
}
catch (Exception e)
{
// exception handling here
error = true;
System.out.println("Error 3");
e.printStackTrace();
}
//set up the gui
createGui();
}
catch (Exception e)
{
System.out.println("Error 4");
LogRunner.getLogger().warning("Error recording video - " + e.getMessage());
e.printStackTrace();
error = true;
}
}
/**
* Flag that determines if something went wrong
* #return True if something did go wrong, false if everything is fine.
*/
public boolean getError()
{
return error;
}
/**
* Creates the gui used to display what is currently being recorded.
*/
private void createGui()
{
videoScreen = player.getVisualComponent();
frm = new Frame("Recording");
frm.setSize(300, 300);
frm.setLayout(new BorderLayout());
frm.add(videoScreen,BorderLayout.CENTER);
JButton close = new JButton("Click Here when done");
frm.add(close,BorderLayout.SOUTH);
close.setVisible(true);
close.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
// Stop the processor doing the movie capture first
processor.stop();
processor.close();
// Closing the processor will end the data stream to the data sink.
// Wait for the end of stream to occur before closing the datasink
dataSinkListener.waitEndOfStream(10);
dataSink.close();
// stop and close the player which closes the video data source
player.stop();
player.close();
theForm.done();
// dispose of the frame and close the application
frm.setVisible(false);
}
});
frm.setAlwaysOnTop(true);
frm.setUndecorated(true);
frm.setLocationRelativeTo(theForm.mainWindow);
frm.setVisible(true);
}
}
/**
*
* Control the ending of the program prior to closing the data sink
*/
class TheDataSinkListener implements DataSinkListener {
boolean endOfStream = false;
// Flag the ending of the data stream
public void dataSinkUpdate(DataSinkEvent event)
{
if (event instanceof javax.media.datasink.EndOfStreamEvent)
{
endOfStream = true;
}
}
/**
* Cause the current thread to sleep if the data stream is still available.
* This makes certain that JMF threads are done prior to closing the data sink
* and finalizing the output file
*/
public void waitEndOfStream(long checkTimeMs) {
while (!endOfStream)
{
try
{
//Thread.currentThread().sleep(checkTimeMs);
Thread.sleep(checkTimeMs);
}
catch (InterruptedException ie)
{
System.out.println("Error 5");
e.printStackTrace();
}
}
}
public static void main(String []args)
{
new VideoRecorder("d:/yusuf/abc.mpg",theForm);
}
}
But where can i get the Logging.LogRunner and VideoStarter. For these my program shows error during compile. The following error messages are shown
1.
symbol: variable LogRunner
location: class VideoRecorder
F:\Tutorials\Java Tutorial\Programs\VideoRecorder\src\VideoRecorder.java:206: error: cannot find symbol
LogRunner.getLogger().warning("Error recording video - " + e.getMessage());
2.
public VideoRecorder(String saveFileTo,VideoStarter inForm)
^
symbol: class VideoStarter
location: class VideoRecorder
Please help

Im the one that acutally wrote that. Sorry for the delayed reply as im sure your far past this, but it may be useful to someone in the future. The LogRunner is a class we use to write our log messages out. You can just remove that, or use whatever youd like for logging.
The VideoStarter is just a JWindow that starts the video recording process. It also is not needed for this class to work.

Related

Raspberry pi with java application high CPU usage

I have a java application running on my raspberry pi but it crashes most of the time. Whenever it crashes it usually has a very high CPU usage (> 100%) from java. How my application works: I have a RFID reader that reads tags and whenever a tag is read, a messageReceived method is called. That method stores the read tags in a specific set. Then I create a new thread which listens to a socket and while the socket is open and when the set has changed, the thread calls some javafx methods to open new screens. However, when I deploy the application to my raspberry pi, it crashes randomly and has a high CPU usage with java. Feel free to ask any questions if I forgot to explain anything .
Edit 1: my thread class.
Edit 2: My question now is: why do I have such a high CPU usage and how can I fix it.
public class RFIDThread implements Runnable {
/**
* The socket for the connection to the LLRP Reader
*/
private Socket socket;
private JSONArray valid_tags;
private JSONArray found_tags;
private TagsListController controller;
private RFIDSet rfidset;
/**
* Thread for constant reading of the stream
*
* #param socket
* #param controller
* #param tags
*/
public RFIDThread(Socket socket, TagsListController controller, JSONArray tags, RFIDSet rfidset) {
this.socket = socket;
this.controller = controller;
this.rfidset = rfidset;
this.found_tags = new JSONArray();
this.valid_tags = tags;
}
/**
* Runnable for this thread.
* First get all the found tags from the xml controller
* Then loop over the rfid set to find any new tags.
* If there are any, display them.
*/
#Override
public void run() {
CopyOnWriteArrayList<Tag> originalSet = new CopyOnWriteArrayList<>();
originalSet.addAll(rfidset.getSet());
boolean started = true;
if (socket.isConnected()) {
while (!socket.isClosed()) {
CopyOnWriteArrayList<Tag> set = new CopyOnWriteArrayList<>();
set.addAll(rfidset.getSet());
if(started || !originalSet.equals(set)) {
started = false;
CopyOnWriteArrayList<String> found_set = new CopyOnWriteArrayList<>();
found_set.addAll(controller.found_tags_list.getItems());
this.found_tags.clear();
this.found_tags.addAll(found_set);
for (Tag found_tag : set) {
if (found_tags.indexOf(found_tag.getId()) < 0) {
Integer index = valid_tags.indexOf(found_tag.getId());
if (index >= 0) {
Platform.runLater(() -> controller.showValid(found_tag.getId()));
} else {
Platform.runLater(() -> controller.showError(found_tag.getId()));
}
found_tags.add(found_tag.getId());
pause(5000);
}
}
originalSet = set;
pause(5000);
}
}
}
}
/**
* Close the socket
*/
public void shutdown() {
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void pause(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Try moving the pause(5000); outside the if (started || !originalSet.equals(set)) { statement.
High cpu usage is usually a tight loop with no pause or I/O or waiting for stuff. In your case whenever the originalSet.equals(set) you will not pause.
You may prefer to just use:
if (started || !originalSet.equals(set)) {
// ...
} else {
pause(0);
}
or similar.

Why do I lose the console output?

I have this code in a JUnit Test :
public class CvsCommandTest {
...
#Test
public void test() {
PServerConnection con = new PServerConnection(root);
GlobalOptions globalOptions = new GlobalOptions();
globalOptions.setCVSRoot(root.toString());
Client client = new Client(con, new StandardAdminHandler());
client.setLocalPath(LOCAL_PATH);
client.getEventManager().addCVSListener(new BasicListener());
CheckoutCommand checkoutCmd = new CheckoutCommand();
checkoutCmd.setBuilder(null);
checkoutCmd.setModule("Outils");
try {
client.getConnection().open();
LOG.info("CVS checkout : " + checkoutCmd.getCVSCommand());
boolean successCheckout = client.executeCommand(checkoutCmd,globalOptions );
LOG.info("Checkout COMPLETED : " + successCheckout);
...
The output, while debugging, is :
[INFO] fr.package.CvsCommandTest - CVS checkout : checkout
-N Outils
cvs checkout: Updating Outils
The first line is my log, the second comes from the listener but I don't get the remaining of my logs.
The basicListener is defined this way :
import java.io.PrintStream;
import org.netbeans.lib.cvsclient.event.CVSAdapter;
import org.netbeans.lib.cvsclient.event.MessageEvent;
public class BasicListener extends CVSAdapter {
/** * Stores a tagged line */
private final StringBuffer taggedLine = new StringBuffer();
/**
* Called when the server wants to send a message to be displayed to the
* user. The message is only for information purposes and clients can choose
* to ignore these messages if they wish.
*
* #param e
* the event
*/
public void messageSent(MessageEvent e) {
String line = e.getMessage();
PrintStream stream = e.isError() ? System.err : System.out;
if (e.isTagged()) {
String message = MessageEvent.parseTaggedMessage(taggedLine, line);
if (message != null) {
stream.println(message);
}
} else {
stream.println(line);
}
stream.close();
}
}
What have I missed?
Turned comment in to answer
System.out stream.close(); --> good night...
Explanation:
Since he is using the System.out to output he's log message when he close the System.out #see end of public void messageSent(MessageEvent e) ,stream.close(); the System.out is closed and can not be used anymore, so good night to System.out
The solution is:
Removing the stream.close(); command

sending sms(text) from java code to mobile phone in windows

Is it possible to send sms from windows machine to mobile phone.
I have searched a lot and got the following code.
Sender.java
package sms;
import java.util.Date;
public class Sender implements Runnable {
private static final long STANDARD=500;
private static final long LONG=2000;
private static final long VERYLONG=20000;
SerialConnection mySerial =null;
static final private char cntrlZ=(char)26;
String in, out;
Thread aThread=null;
private long delay=STANDARD;
String recipient=null;
String message=null;
private String csca="+6596845999"; // the message center
private SerialParameters defaultParameters= new SerialParameters ("COM2",9600,0,0,8,1,0);
public int step;
public int status=-1;
public long messageNo=-1;
public Sender(String recipient, String message){
this.recipient=recipient;
this.message=message;
}
/**
* connect to the port and start the dialogue thread
*/
public int send () throws Exception{
SerialParameters params = defaultParameters;
mySerial =new SerialConnection (params);
mySerial.openConnection();
aThread=new Thread(this);
aThread.start() ;
//log("start");
return 0;
}
/**
* implement the dialogue thread,
* message / response via steps,
* handle time out
*/
public void run(){
boolean timeOut=false;
long startTime=(new Date()).getTime();
while ((step <7) && (!timeOut)){
// log(""+((new Date()).getTime() - startTime);
//check where we are in specified delay
timeOut=((new Date()).getTime() - startTime)>delay;
//if atz does not work, type to send cntrlZ and retry, in case a message was stuck
if (timeOut && (step==1)) {
step=-1;
mySerial.send( ""+cntrlZ);
}
//read incoming string
String result= mySerial.getIncommingString() ;
// log ("<- "+result+"\n--------");
int expectedResult=-1;
try{
//log ("Step:"+step);
switch (step){
case 0:
mySerial.send("atz");
delay=LONG;
startTime=(new Date()).getTime();
break;
case 1:
delay=STANDARD;
mySerial.send("ath0");
startTime=(new Date()).getTime();
break;
case 2:
expectedResult=result.indexOf("OK");
//log ("received ok ="+expectedResult);
if (expectedResult>-1){
mySerial.send("at+cmgf=1");
startTime=(new Date()).getTime();
}else{
step=step-1;
}
break;
case 3:
expectedResult=result.indexOf("OK");
// log ("received ok ="+expectedResult);
if (expectedResult>-1){
mySerial.send("at+csca=\""+csca+"\"");
startTime=(new Date()).getTime();
}else{
step=step-1;
}
break;
case 4:
expectedResult=result.indexOf("OK");
// log ("received ok ="+expectedResult);
if (expectedResult>-1){
mySerial.send("at+cmgs=\""+recipient+"\"");
startTime=(new Date()).getTime();
}else{
step=step-1;
}
break;
case 5:
expectedResult=result.indexOf(">");
// log ("received ok ="+expectedResult);
if (expectedResult>-1){
mySerial.send(message+cntrlZ);
startTime=(new Date()).getTime();
}else{
step=step-1;
}
delay=VERYLONG;//waitning for message ack
break;
case 6:
expectedResult=result.indexOf("OK");
//read message number
if (expectedResult>-1){
int n=result.indexOf("CMGS:");
result=result.substring(n+5);
n=result.indexOf("\n");
status=0;
messageNo=Long.parseLong(result.substring(0,n).trim() );
log ("sent message no:"+messageNo);
}else{
step=step-1;
}
break;
}
step=step+1;
aThread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
}
mySerial.closeConnection() ;
//if timed out set status
if (timeOut ) {
status=-2;
log("*** time out at step "+step+"***");
}
}
/**
* logging function, includes date and class name
*/
private void log(String s){
System.out.println (new java.util.Date()+":"+this.getClass().getName()+":"+s);
}
}
SerialConnection.java
package sms;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.CommPortOwnershipListener;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
/**
A class that handles the details of a serial connection. Reads from one
TextArea and writes to a second TextArea.
Holds the state of the connection.
*/
public class SerialConnection implements SerialPortEventListener,
CommPortOwnershipListener {
private SerialParameters parameters;
private OutputStream os;
private InputStream is;
private KeyHandler keyHandler;
private CommPortIdentifier portId;
private SerialPort sPort;
private boolean open;
private String receptionString="";
public String getIncommingString(){
byte[] bVal= receptionString.getBytes();
receptionString="";
return new String (bVal);
}
public SerialConnection(SerialParameters parameters) {
this.parameters = parameters;
open = false;
}
/**
Attempts to open a serial connection and streams using the parameters
in the SerialParameters object. If it is unsuccesfull at any step it
returns the port to a closed state, throws a
<code>SerialConnectionException</code>, and returns.
Gives a timeout of 30 seconds on the portOpen to allow other applications
to reliquish the port if have it open and no longer need it.
*/
public void openConnection() throws SerialConnectionException {
// System.out.println("OK 0 ");
// Obtain a CommPortIdentifier object for the port you want to open.
try {
// System.out.println(parameters.getPortName());
portId = CommPortIdentifier.getPortIdentifier(parameters.getPortName());
} catch (NoSuchPortException e) {
// System.out.println("Yes the problem is here 1 ");
e.printStackTrace();
// throw new SerialConnectionException(e.getMessage());
}catch(Exception e)
{
// System.out.println("ErrorErrorErrorError");
e.printStackTrace();
}
//System.out.println(portId);
//System.out.println("OK 1 ");
// Open the port represented by the CommPortIdentifier object. Give
// the open call a relatively long timeout of 30 seconds to allow
// a different application to reliquish the port if the user
// wants to.
try {
sPort = (SerialPort)portId.open("SMSConnector", 30000);
} catch (PortInUseException e) {
throw new SerialConnectionException(e.getMessage());
}
//System.out.println("OK 2 ");
sPort.sendBreak(1000);
// Set the parameters of the connection. If they won't set, close the
// port before throwing an exception.
try {
setConnectionParameters();
} catch (SerialConnectionException e) {
sPort.close();
throw e;
}
// System.out.println("OK 3 ");
// Open the input and output streams for the connection. If they won't
// open, close the port before throwing an exception.
try {
os = sPort.getOutputStream();
is = sPort.getInputStream();
} catch (IOException e) {
sPort.close();
throw new SerialConnectionException("Error opening i/o streams");
}
//System.out.println("OK 4 ");
/*
// Create a new KeyHandler to respond to key strokes in the
// messageAreaOut. Add the KeyHandler as a keyListener to the
// messageAreaOut.
keyHandler = new KeyHandler(os);
messageAreaOut.addKeyListener(keyHandler);
*/
// Add this object as an event listener for the serial port.
try {
sPort.addEventListener(this);
} catch (TooManyListenersException e) {
sPort.close();
throw new SerialConnectionException("too many listeners added");
}
//System.out.println("OK 5 ");
// Set notifyOnDataAvailable to true to allow event driven input.
sPort.notifyOnDataAvailable(true);
// Set notifyOnBreakInterrup to allow event driven break handling.
sPort.notifyOnBreakInterrupt(true);
// Set receive timeout to allow breaking out of polling loop during
// input handling.
try {
sPort.enableReceiveTimeout(30);
} catch (UnsupportedCommOperationException e) {
}
//System.out.println("OK 6 ");
// Add ownership listener to allow ownership event handling.
portId.addPortOwnershipListener(this);
open = true;
}
/**
Sets the connection parameters to the setting in the parameters object.
If set fails return the parameters object to origional settings and
throw exception.
*/
public void setConnectionParameters() throws SerialConnectionException {
// Save state of parameters before trying a set.
int oldBaudRate = sPort.getBaudRate();
int oldDatabits = sPort.getDataBits();
int oldStopbits = sPort.getStopBits();
int oldParity = sPort.getParity();
int oldFlowControl = sPort.getFlowControlMode();
// Set connection parameters, if set fails return parameters object
// to original state.
try {
sPort.setSerialPortParams(parameters.getBaudRate(),
parameters.getDatabits(),
parameters.getStopbits(),
parameters.getParity());
} catch (UnsupportedCommOperationException e) {
parameters.setBaudRate(oldBaudRate);
parameters.setDatabits(oldDatabits);
parameters.setStopbits(oldStopbits);
parameters.setParity(oldParity);
throw new SerialConnectionException("Unsupported parameter");
}
// Set flow control.
try {
sPort.setFlowControlMode(parameters.getFlowControlIn()
| parameters.getFlowControlOut());
} catch (UnsupportedCommOperationException e) {
throw new SerialConnectionException("Unsupported flow control");
}
}
/**
Close the port and clean up associated elements.
*/
public void closeConnection() {
// If port is alread closed just return.
if (!open) {
return;
}
// Remove the key listener.
// messageAreaOut.removeKeyListener(keyHandler);
// Check to make sure sPort has reference to avoid a NPE.
if (sPort != null) {
try {
// close the i/o streams.
os.close();
is.close();
} catch (IOException e) {
System.err.println(e);
}
// Close the port.
sPort.close();
// Remove the ownership listener.
portId.removePortOwnershipListener(this);
}
open = false;
}
/**
Send a one second break signal.
*/
public void sendBreak() {
sPort.sendBreak(1000);
}
/**
Reports the open status of the port.
#return true if port is open, false if port is closed.
*/
public boolean isOpen() {
return open;
}
/**
Handles SerialPortEvents. The two types of SerialPortEvents that this
program is registered to listen for are DATA_AVAILABLE and BI. During
DATA_AVAILABLE the port buffer is read until it is drained, when no more
data is availble and 30ms has passed the method returns. When a BI
event occurs the words BREAK RECEIVED are written to the messageAreaIn.
*/
public void serialEvent(SerialPortEvent e) {
// Create a StringBuffer and int to receive input data.
StringBuffer inputBuffer = new StringBuffer();
int newData = 0;
// Determine type of event.
switch (e.getEventType()) {
// Read data until -1 is returned. If \r is received substitute
// \n for correct newline handling.
case SerialPortEvent.DATA_AVAILABLE:
while (newData != -1) {
try {
newData = is.read();
if (newData == -1) {
break;
}
if ('\r' == (char)newData) {
inputBuffer.append('\n');
} else {
inputBuffer.append((char)newData);
}
} catch (IOException ex) {
System.err.println(ex);
return;
}
}
// Append received data to messageAreaIn.
receptionString=receptionString+ (new String(inputBuffer));
//System.out.print("<-"+receptionString);
break;
// If break event append BREAK RECEIVED message.
case SerialPortEvent.BI:
receptionString=receptionString+("\n--- BREAK RECEIVED ---\n");
}
}
/**
Handles ownership events. If a PORT_OWNERSHIP_REQUESTED event is
received a dialog box is created asking the user if they are
willing to give up the port. No action is taken on other types
of ownership events.
*/
public void ownershipChange(int type) {
/*
if (type == CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED) {
PortRequestedDialog prd = new PortRequestedDialog(parent);
}
*/
}
/**
A class to handle <code>KeyEvent</code>s generated by the messageAreaOut.
When a <code>KeyEvent</code> occurs the <code>char</code> that is
generated by the event is read, converted to an <code>int</code> and
writen to the <code>OutputStream</code> for the port.
*/
class KeyHandler extends KeyAdapter {
OutputStream os;
/**
Creates the KeyHandler.
#param os The OutputStream for the port.
*/
public KeyHandler(OutputStream os) {
super();
this.os = os;
}
/**
Handles the KeyEvent.
Gets the <code>char</char> generated by the <code>KeyEvent</code>,
converts it to an <code>int</code>, writes it to the <code>
OutputStream</code> for the port.
*/
public void keyTyped(KeyEvent evt) {
char newCharacter = evt.getKeyChar();
if ((int)newCharacter==10) newCharacter = '\r';
System.out.println ((int)newCharacter);
try {
os.write((int)newCharacter);
} catch (IOException e) {
System.err.println("OutputStream write error: " + e);
}
}
}
public void send(String message) {
byte[] theBytes= (message+"\n").getBytes();
for (int i=0; i<theBytes.length;i++){
char newCharacter = (char)theBytes[i];
if ((int)newCharacter==10) newCharacter = '\r';
try {
os.write((int)newCharacter);
} catch (IOException e) {
System.err.println("OutputStream write error: " + e);
}
}
//System.out.println (">'" +message +"' sent");
}
}
SerialConnection.java
package sms;
public class SerialConnectionException extends Exception {
/**
* Constructs a <code>SerialConnectionException</code>
* with the specified detail message.
*
* #param s the detail message.
*/
public SerialConnectionException(String str) {
super(str);
}
/**
* Constructs a <code>SerialConnectionException</code>
* with no detail message.
*/
public SerialConnectionException() {
super();
}
}
SerialParameters.java
package sms;
import javax.comm.SerialPort;
/**
A class that stores parameters for serial ports.
*/
public class SerialParameters {
private String portName;
private int baudRate;
private int flowControlIn;
private int flowControlOut;
private int databits;
private int stopbits;
private int parity;
/**
Default constructer. Sets parameters to no port, 9600 baud, no flow
control, 8 data bits, 1 stop bit, no parity.
*/
public SerialParameters () {
this("",
9600,
SerialPort.FLOWCONTROL_NONE,
SerialPort.FLOWCONTROL_NONE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE );
}
/**
Paramaterized constructer.
#param portName The name of the port.
#param baudRate The baud rate.
#param flowControlIn Type of flow control for receiving.
#param flowControlOut Type of flow control for sending.
#param databits The number of data bits.
#param stopbits The number of stop bits.
#param parity The type of parity.
*/
public SerialParameters(String portName,
int baudRate,
int flowControlIn,
int flowControlOut,
int databits,
int stopbits,
int parity) {
this.portName = portName;
this.baudRate = baudRate;
this.flowControlIn = flowControlIn;
this.flowControlOut = flowControlOut;
this.databits = databits;
this.stopbits = stopbits;
this.parity = parity;
}
/**
Sets port name.
#param portName New port name.
*/
public void setPortName(String portName) {
this.portName = portName;
}
/**
Gets port name.
#return Current port name.
*/
public String getPortName() {
return portName;
}
/**
Sets baud rate.
#param baudRate New baud rate.
*/
public void setBaudRate(int baudRate) {
this.baudRate = baudRate;
}
/**
Sets baud rate.
#param baudRate New baud rate.
*/
public void setBaudRate(String baudRate) {
this.baudRate = Integer.parseInt(baudRate);
}
/**
Gets baud rate as an <code>int</code>.
#return Current baud rate.
*/
public int getBaudRate() {
return baudRate;
}
/**
Gets baud rate as a <code>String</code>.
#return Current baud rate.
*/
public String getBaudRateString() {
return Integer.toString(baudRate);
}
/**
Sets flow control for reading.
#param flowControlIn New flow control for reading type.
*/
public void setFlowControlIn(int flowControlIn) {
this.flowControlIn = flowControlIn;
}
/**
Sets flow control for reading.
#param flowControlIn New flow control for reading type.
*/
public void setFlowControlIn(String flowControlIn) {
this.flowControlIn = stringToFlow(flowControlIn);
}
/**
Gets flow control for reading as an <code>int</code>.
#return Current flow control type.
*/
public int getFlowControlIn() {
return flowControlIn;
}
/**
Gets flow control for reading as a <code>String</code>.
#return Current flow control type.
*/
public String getFlowControlInString() {
return flowToString(flowControlIn);
}
/**
Sets flow control for writing.
#param flowControlIn New flow control for writing type.
*/
public void setFlowControlOut(int flowControlOut) {
this.flowControlOut = flowControlOut;
}
/**
Sets flow control for writing.
#param flowControlIn New flow control for writing type.
*/
public void setFlowControlOut(String flowControlOut) {
this.flowControlOut = stringToFlow(flowControlOut);
}
/**
Gets flow control for writing as an <code>int</code>.
#return Current flow control type.
*/
public int getFlowControlOut() {
return flowControlOut;
}
/**
Gets flow control for writing as a <code>String</code>.
#return Current flow control type.
*/
public String getFlowControlOutString() {
return flowToString(flowControlOut);
}
/**
Sets data bits.
#param databits New data bits setting.
*/
public void setDatabits(int databits) {
this.databits = databits;
}
/**
Sets data bits.
#param databits New data bits setting.
*/
public void setDatabits(String databits) {
if (databits.equals("5")) {
this.databits = SerialPort.DATABITS_5;
}
if (databits.equals("6")) {
this.databits = SerialPort.DATABITS_6;
}
if (databits.equals("7")) {
this.databits = SerialPort.DATABITS_7;
}
if (databits.equals("8")) {
this.databits = SerialPort.DATABITS_8;
}
}
/**
Gets data bits as an <code>int</code>.
#return Current data bits setting.
*/
public int getDatabits() {
return databits;
}
/**
Gets data bits as a <code>String</code>.
#return Current data bits setting.
*/
public String getDatabitsString() {
switch(databits) {
case SerialPort.DATABITS_5:
return "5";
case SerialPort.DATABITS_6:
return "6";
case SerialPort.DATABITS_7:
return "7";
case SerialPort.DATABITS_8:
return "8";
default:
return "8";
}
}
/**
Sets stop bits.
#param stopbits New stop bits setting.
*/
public void setStopbits(int stopbits) {
this.stopbits = stopbits;
}
/**
Sets stop bits.
#param stopbits New stop bits setting.
*/
public void setStopbits(String stopbits) {
if (stopbits.equals("1")) {
this.stopbits = SerialPort.STOPBITS_1;
}
if (stopbits.equals("1.5")) {
this.stopbits = SerialPort.STOPBITS_1_5;
}
if (stopbits.equals("2")) {
this.stopbits = SerialPort.STOPBITS_2;
}
}
/**
Gets stop bits setting as an <code>int</code>.
#return Current stop bits setting.
*/
public int getStopbits() {
return stopbits;
}
/**
Gets stop bits setting as a <code>String</code>.
#return Current stop bits setting.
*/
public String getStopbitsString() {
switch(stopbits) {
case SerialPort.STOPBITS_1:
return "1";
case SerialPort.STOPBITS_1_5:
return "1.5";
case SerialPort.STOPBITS_2:
return "2";
default:
return "1";
}
}
/**
Sets parity setting.
#param parity New parity setting.
*/
public void setParity(int parity) {
this.parity = parity;
}
/**
Sets parity setting.
#param parity New parity setting.
*/
public void setParity(String parity) {
if (parity.equals("None")) {
this.parity = SerialPort.PARITY_NONE;
}
if (parity.equals("Even")) {
this.parity = SerialPort.PARITY_EVEN;
}
if (parity.equals("Odd")) {
this.parity = SerialPort.PARITY_ODD;
}
}
/**
Gets parity setting as an <code>int</code>.
#return Current parity setting.
*/
public int getParity() {
return parity;
}
/**
Gets parity setting as a <code>String</code>.
#return Current parity setting.
*/
public String getParityString() {
switch(parity) {
case SerialPort.PARITY_NONE:
return "None";
case SerialPort.PARITY_EVEN:
return "Even";
case SerialPort.PARITY_ODD:
return "Odd";
default:
return "None";
}
}
/**
Converts a <code>String</code> describing a flow control type to an
<code>int</code> type defined in <code>SerialPort</code>.
#param flowControl A <code>string</code> describing a flow control type.
#return An <code>int</code> describing a flow control type.
*/
private int stringToFlow(String flowControl) {
if (flowControl.equals("None")) {
return SerialPort.FLOWCONTROL_NONE;
}
if (flowControl.equals("Xon/Xoff Out")) {
return SerialPort.FLOWCONTROL_XONXOFF_OUT;
}
if (flowControl.equals("Xon/Xoff In")) {
return SerialPort.FLOWCONTROL_XONXOFF_IN;
}
if (flowControl.equals("RTS/CTS In")) {
return SerialPort.FLOWCONTROL_RTSCTS_IN;
}
if (flowControl.equals("RTS/CTS Out")) {
return SerialPort.FLOWCONTROL_RTSCTS_OUT;
}
return SerialPort.FLOWCONTROL_NONE;
}
/**
Converts an <code>int</code> describing a flow control type to a
<code>String</code> describing a flow control type.
#param flowControl An <code>int</code> describing a flow control type.
#return A <code>String</code> describing a flow control type.
*/
String flowToString(int flowControl) {
switch(flowControl) {
case SerialPort.FLOWCONTROL_NONE:
return "None";
case SerialPort.FLOWCONTROL_XONXOFF_OUT:
return "Xon/Xoff Out";
case SerialPort.FLOWCONTROL_XONXOFF_IN:
return "Xon/Xoff In";
case SerialPort.FLOWCONTROL_RTSCTS_IN:
return "RTS/CTS In";
case SerialPort.FLOWCONTROL_RTSCTS_OUT:
return "RTS/CTS Out";
default:
return "None";
}
}
}
But when i am trying to run the code, i am getting following error:-
Error loading SolarisSerial: java.lang.UnsatisfiedLinkError: no SolarisSerialParallel in java.library.path
Caught java.lang.UnsatisfiedLinkError: com.sun.comm.SolarisDriver.readRegistrySerial(Ljava/util/Vector;Ljava/lang/String;)I while loading driver com.sun.comm.SolarisDriver
is this code that i have taken OS specific. Or there are any other way to send sms(txt) from pc to mobile.
Please help me.
I think this is a very complicated approach.
If you are developing a commercial application, there are many companies which provide web services that you could use. You just send the sms text to the webservice, and they will send the sms for you, no need to reinvent the wheel.
Unless you are developing a webservice like this yourself!
Your code relies on a JNI driver class "com.sun.comm.SolarisDriver". Your program can't locate the dinamic library SolarisSerialParallel.
The Java virtual machine needs to be able to find the native library. To do this, set the library path adding the path to the library as follows:
Unix or Linux based systems:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH;'/opt/whatever/SolarisSerialParallel.so'
export LD_LIBRARY_PATH
Windows (I guess that in this case, you'll need to search the appropiate DLL, as the one required at your question seems to be exclusive for Solaris environments):
set PATH=%path%;C:\whatever\SolarisSerialParallel.dll
Note that you can point it to the containing directory, if more libraries ar needed.
Reference: Java Native Interface Specification

Problem in java programming on windows7 (working well in windows xp)

I am capturing video from webcam connected to pc.I am using the following code to do so:
import java.util.*;
import javax.media.*;
import javax.media.protocol.*;
import javax.media.control.*;
import javax.media.format.*;
import java.awt.*;
/**
* This is the primary class to run. It gathers an image stream and drives the processing.
*
*/
public class jmfcam05v
{
DataSource dataSource;
PushBufferStream pbs;
Vector camImgSize = new Vector();
Vector camCapDevice = new Vector();
Vector camCapFormat = new Vector();
int camFPS;
int camImgSel;
Processor processor = null;
DataSink datasink = null;
/**
* Main method to instance and run class
*
*/
public static void main(String[] args)
{
jmfcam05v jmfcam = new jmfcam05v();
}
/**
* Constructor and processing method for image stream from a cam
*
*/
public jmfcam05v()
{
// Select webcam format
fetchDeviceFormats();
camImgSel=0; // first format, or otherwise as desired
camFPS = 20; // framerate
// Setup data source
fetchDeviceDataSource();
createPBDSource();
createProcessor(dataSource);
startCapture();
try{Thread.sleep(90000);}catch(Exception e){} // 20 seconds
stopCapture();
}
/**
* Gathers info on a camera
*
*/
boolean fetchDeviceFormats()
{
Vector deviceList = CaptureDeviceManager.getDeviceList(new VideoFormat(null));
CaptureDeviceInfo CapDevice = null;
Format CapFormat = null;
String type = "N/A";
CaptureDeviceInfo deviceInfo=null;boolean VideoFormatMatch=false;
for(int i=0;i<deviceList.size();i++)
{
// search for video device
deviceInfo = (CaptureDeviceInfo)deviceList.elementAt(i);
if(deviceInfo.getName().indexOf("vfw:")<0)continue;
Format deviceFormat[] = deviceInfo.getFormats();
for (int f=0;f<deviceFormat.length;f++)
{
if(deviceFormat[f] instanceof RGBFormat)type="RGB";
if(deviceFormat[f] instanceof YUVFormat)type="YUV";
if(deviceFormat[f] instanceof JPEGFormat)type="JPG";
Dimension size = ((VideoFormat)deviceFormat[f]).getSize();
camImgSize.addElement(type+" "+size.width+"x"+size.height);
CapDevice = deviceInfo;
camCapDevice.addElement(CapDevice);
//System.out.println("Video device = " + deviceInfo.getName());
CapFormat = (VideoFormat)deviceFormat[f];
camCapFormat.addElement(CapFormat);
//System.out.println("Video format = " + deviceFormat[f].toString());
VideoFormatMatch=true; // at least one
}
}
if(VideoFormatMatch==false)
{
if(deviceInfo!=null)System.out.println(deviceInfo);
System.out.println("Video Format not found");
return false;
}
return true;
}
/**
* Finds a camera and sets it up
*
*/
void fetchDeviceDataSource()
{
CaptureDeviceInfo CapDevice = (CaptureDeviceInfo)camCapDevice.elementAt(camImgSel);
System.out.println("Video device = " + CapDevice.getName());
Format CapFormat = (Format)camCapFormat.elementAt(camImgSel);
System.out.println("Video format = " + CapFormat.toString());
MediaLocator loc = CapDevice.getLocator();
try
{
dataSource = Manager.createDataSource(loc);
}
catch(Exception e){}
try
{
// ensures 30 fps or as otherwise preferred, subject to available cam rates but this is frequency of windows request to stream
FormatControl formCont=((CaptureDevice)dataSource).getFormatControls()[0];
VideoFormat formatVideoNew = new VideoFormat(null,null,-1,null,(float)camFPS);
formCont.setFormat(CapFormat.intersects(formatVideoNew));
}
catch(Exception e){}
}
/**
* Gets a stream from the camera (and sets debug)
*
*/
void createPBDSource()
{
try
{
pbs=((PushBufferDataSource)dataSource).getStreams()[0];
}
catch(Exception e){}
}
public void createProcessor(DataSource datasource)
{
FileTypeDescriptor ftd = new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);
Format[] formats = new Format[] {new VideoFormat(VideoFormat.INDEO50)};
ProcessorModel pm = new ProcessorModel(datasource, formats, ftd);
try
{
processor = Manager.createRealizedProcessor(pm);
}
catch(Exception me)
{
System.out.println(me);
// Make sure the capture devices are released
datasource.disconnect();
return;
}
}
private void startCapture()
{
// Get the processor's output, create a DataSink and connect the two.
DataSource outputDS = processor.getDataOutput();
try
{
MediaLocator ml = new MediaLocator("file:capture.avi");
datasink = Manager.createDataSink(outputDS, ml);
datasink.open();
datasink.start();
}catch (Exception e)
{
System.out.println(e);
}
processor.start();
System.out.println("Started saving...");
}
private void pauseCapture()
{
processor.stop();
}
private void resumeCapture()
{
processor.start();
}
private void stopCapture()
{
// Stop the capture and the file writer (DataSink)
processor.stop();
processor.close();
datasink.close();
processor = null;
System.out.println("Done saving.");
}
}
this program works well on windows xp(desktop) and wen i try to use it on windows7(laptop) it gives me the following error:
run: Video Format not found
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:427)
at jmfcam05v.fetchDeviceDataSource(jmfcam05v.java:112)
at jmfcam05v.<init>(jmfcam05v.java:49)
at jmfcam05v.main(jmfcam05v.java:34) Java Result: 1 BUILD SUCCESSFUL (total time: 0 seconds)
my program is not detectin my inbuild webcam on laptop nor it is detecting external web cam.i am using jmf to capture the video and all my webcam's are vfw supported.
Please help me to solve this issue.
Are you mixing 32 and 64-bit installs? I had a similar problem under Windows 7, and it was due to 64-bit incompatibilities between Windows 7, JRE and JMF. In short, JMF is only 32-bit and won't recognize devices if your JRE is 64-bit.
After following these instructions, I was able to recognize my camera and avoid the "Video Format not found" as well as the jmfstudio not detecting the video capture device.
Is it possible that Windows 7 security is preventing you from accessing the device, thus your list shows up as empty from your fetchDeviceDataSource() call.
You can try turning off UAC and see if it fixes your problem.

Threading for distance vector which does not drop packets

I am doing my assignment in Network architecture 1, where I have to implement a distance vector routing at each node.
At each node, I have a thread which listens for incoming DatagramPackets containing routing information from neighboring nodes only on a specific port. When a datagram arrives, the thread processes that datagram, and if there are updates in its internal routing tables, then it sends its routing information to all of its neighbors.
I am trying to do it in Java.
The problem I am facing is that when a datagram arrives, I need to process it. If during that time any other datagram arrives, it is dropped, as the thread is currently processing information. That means I have a loss of information.
Can any one help me with this?
I am using the usual way of reading from a socket in java.
DatagramSocket socket = new DatagramSocket(4445, InetAddress.getByName("127.0.0.1"));
while (true) {
try {
byte[] buf = new byte[2000];
// receive request
DatagramPacket recvRequest = new DatagramPacket(buf, buf.length);
socket.receive(recvRequest);
//Some process of data in datagram
} catch (IOException e) {
e.printStackTrace();
}
}
You can process the received datagram in a thread, so your thread with the socket listener can continue to receive new datagrams.
This the final project that i submitted.
It might be having some improper documentation and some bad usage of Java.
As this project runs on local system, instead of using different IP address and same port number, i am doing it other way.
NetworkBoot.java provides the initial neighbor details to each router.
Thanks
-Sunny Jain
enter code here
/*
* File Name : Router.java
* Public Class Name : Router
*
*/
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import javax.swing.SwingUtilities;
/**
*
* NA1 project 2 spring 2009 semester
* #author sunny jain
*
*
*/
public class Router extends Thread {
/**
* HashMap containing list of neighbors and cost to reach them.
*/
private HashMap<Integer, Integer> hmapDirectNeighbours = new HashMap<Integer, Integer>(61);
/**
* HashMap containing list of destination as key and routing info to them as value.
* Routing info contains RouteDetail object.
* #see RouteDetail
*/
private HashMap<Integer, RouteDetail> hmapRoutes = new HashMap<Integer, RouteDetail>();
/**
* DatagramSocket
*/
private DatagramSocket dSoc;
/**
* DatagramPacket
*/
private DatagramPacket dpackReceive, dpackSend;
/**
* Inetaddress of system on which runs this algorithm.
*/
private InetAddress localAddress;
/**
* port to listen at for incoming route info from neighbors.
*/
int port;
private LinkedBlockingQueue<DatagramPacket> lbq = new LinkedBlockingQueue<DatagramPacket>();
/**
* Made constructor private to force initialization by specifying port
* compulsory.
*/
private Router() {
}
/**
* Constuctor taking port number as parameter and creates a datagramSocket
* to listen for incoming DatagramPacket on that socket.
* #param port
*/
public Router(int port) {
try {
this.port = port;
localAddress = InetAddress.getByName("127.0.0.1");
dSoc = new DatagramSocket(port, localAddress);
} catch (Exception ex) {
System.out.println("Error while creating socket : " + ex.getMessage());
}
this.start();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
while (true) {
try {
received_Route_Info(lbq.take());
} catch (InterruptedException ex) {
System.out.println("Error while reading elements from datagram queue");
}}}});
}
public void setRouterBootInfo(String strNeighboursInfo) {
String[] strNeighbouringNodes = strNeighboursInfo.split(";");
for (int i = 0; i < strNeighbouringNodes.length; i++) {
String[] strNodeIpAndPort = strNeighbouringNodes[i].split(":");
hmapDirectNeighbours.put(Integer.valueOf(strNodeIpAndPort[0]), Integer.valueOf(strNodeIpAndPort[1]));
hmapRoutes.put(Integer.valueOf(strNodeIpAndPort[0]), new RouteDetail(null, Integer.valueOf(strNodeIpAndPort[1])));
}
propagateChanges();
// entry in Route table....No need for infinity as we creat entry when a node is reachable.
}
#Override
public void run() {
while (true) {
try {
byte[] buf = new byte[250];
// receive request
dpackReceive = new DatagramPacket(buf, buf.length);
dSoc.receive(dpackReceive);
lbq.put(dpackReceive);
} catch (InterruptedException ex) {
ex.printStackTrace();
dSoc.close();
} catch (IOException e) {
e.printStackTrace();
dSoc.close();
}
}
}
/**
* This method is called for each DatagramPacket received containing new
* routing information.
*
* This method checks whether this packet came from neighboring node
* (routers) only. If true it applies Distance vector algorithm on data
* present in datagram packet and due to this information if their is any
* change in local routing information that it displays current local
* updated routing information and also sends this updated information to
* other neighbours only.
*
* #param dataPckt
* #see #validate_Is_Packet_From_Neighbor(java.net.DatagramPacket)
* #see #apply_Routing_Algorithm(java.net.DatagramPacket, java.util.HashMap)
* #see #print_route_info()
* #see #send_Updates_To_Neighbors(routesInfo)
*/
private void received_Route_Info(DatagramPacket dataPckt) {
if (dataPckt.getPort() == 4000) {
setRouterBootInfo(getStringFromBytes(dataPckt));
} else if (validate_Is_Packet_From_Neighbor(dataPckt)) {
if (apply_Routing_Algorithm(dataPckt, create_HashMap_Routes(getStringFromBytes(dataPckt)))) {
// if their is change in routing information.
propagateChanges();
}
}
}
/**
* Validates whether the Datagram packet received is from the neighbors only.
* #param datagrampckt DatagramPacket comtaining routing information.
* #return true if datagrampckt is from neighbors only otherwise false.
*/
private boolean validate_Is_Packet_From_Neighbor(DatagramPacket datagrampckt) {
return hmapDirectNeighbours.containsKey(Integer.valueOf(datagrampckt.getPort()));
}
/**
* Returns byte representaion of data contained in DatagramPacket pkt.
* #param pkt DatagramPacket
* #return byte representation of data contained in pkt
*/
private String getStringFromBytes(DatagramPacket pkt) {
String strData = new String(pkt.getData());
return strData.substring(0, strData.lastIndexOf(';'));
}
/**
* Applies Distance Vector algorithm using newly received routing information
* and information presently with this node (Router).
* #param datagrampckt DatagramPacket containing routing information.
* #param newRoutes HashMap of routes new information received with
* destination as key and cost to that destination as value.
*/
private boolean apply_Routing_Algorithm(DatagramPacket dataPckt, HashMap<Integer, Integer> newRoutes) {
boolean updated = false;
Integer pktSourse = Integer.valueOf(dataPckt.getPort());
// Get a set of the routes
Set<Integer> set = newRoutes.keySet();
// Get an iterator
Iterator<Integer> iterator = set.iterator();
// Display elements.
while (iterator.hasNext()) {
Integer key = iterator.next();
Integer nextHopCost = hmapRoutes.get(pktSourse).getPathCost();
int optionalCost = newRoutes.get(key) + (nextHopCost == null ? 0 : nextHopCost);
if (hmapRoutes.containsKey(key)) {
RouteDetail routeDetail = hmapRoutes.get(key);
if (routeDetail.getPathCost().compareTo(optionalCost) > 0) {
routeDetail.setNextHop(pktSourse);
routeDetail.setPathCost(optionalCost);
hmapRoutes.put(key, routeDetail);
updated = true;
// try to verify above statement
}
} else {
if (!key.equals(port)) {
RouteDetail newRouteDetail = new RouteDetail(pktSourse, optionalCost);
hmapRoutes.put(key, newRouteDetail);
updated = true;
}
}
}
return updated;
}
/**
* When internal routing information is chaged, send this information to
* other neighbors.
* #param routesInfo byte representaion of routing information.
*/
private void send_Updates_To_Neighbors(byte[] routesInfo) {
// Get a set of the routes
Set<Integer> set = hmapDirectNeighbours.keySet();
// Get an iterator
Iterator<Integer> iterator = set.iterator();
// Display elements.
while (iterator.hasNext()) {
dpackSend = new DatagramPacket(routesInfo, routesInfo.length, localAddress, iterator.next().intValue());
try {
dSoc.send(dpackSend);
} catch (IOException ex) {
System.out.println("Error while sending route updates : " + ex.getMessage());
}
}
}
/**
* Parses routeInfo to creat an HashMap based on this informationin the
* format as HashMap of <<Integer:Destination>,<Integer: Cost to this destination>>
* #param routeInfo contains routing information as String in the syntax
* of {<Destination>:<Cost to destination>;}
* #return Hashmap<<Integer:Destination>,<Integer: Cost to this destination>>
*/
private HashMap<Integer, Integer> create_HashMap_Routes(String routeInfo) {
HashMap<Integer, Integer> routes = new HashMap<Integer, Integer>();
String[] straRoute = routeInfo.split(";");
for (int i = 0; i < straRoute.length; i++) {
String[] straDestAndCost = straRoute[i].split(":");
routes.put(Integer.parseInt(straDestAndCost[0]), Integer.parseInt(straDestAndCost[1]));
}
return routes;
}
/**
* Converts current routing information stored as HashMap to String
* presentation in format as {<Destination>:<Cost to destination>;}
*
* #return String representaion of routing information.
* #see #hmapRoutes.
*/
private String create_String_Of_Routes() {
StringBuilder strB = new StringBuilder();
// Get a set of the routes
Set<Integer> set = hmapRoutes.keySet();
// Get an iterator
Iterator<Integer> iterator = set.iterator();
// Display elements.
while (iterator.hasNext()) {
Integer destination = iterator.next();
strB.append(destination);
strB.append(":");
strB.append(hmapRoutes.get(destination).getPathCost());
strB.append(";");
}
return strB.toString();
}
/**
* Prints the current routing information stored in <code>hmapRoutes</code>
* to default output stream of this program.
* #see #hmapRoutes.
*/
public void print_route_info() {
RouteDetail route;
StringBuilder builder;
// PRINT THE CURRENT ROUTING INFO AT THIS NODE
System.out.println("");
System.out.println(" TABLE AT NODE WITH PORT : " + port);
System.out.println("--------------------------------------------------------------------------------");
System.out.println("\t\tTo \t|\t Via\t|\tCost\t\t");
System.out.println("--------------------------------------------------------------------------------");
// Get a set of the routes
Set<Integer> set = hmapRoutes.keySet();
// Get an iterator
Iterator<Integer> iterator = set.iterator();
// Display elements.
while (iterator.hasNext()) {
Integer key = iterator.next();
route = hmapRoutes.get(key);
builder = new StringBuilder();
builder.append("\t\t" + key.intValue());
builder.append("\t|\t" + (route.getNextHop() == null ? " -" : route.getNextHop()));
builder.append("\t|\t" + route.getPathCost() + "\t\t");
System.out.println(builder.toString());
}
}
/**
* This class provides details for each destination.
* It provides detail of cost that will be incurred to reach that
* destination and next router on that path.
*/
private class RouteDetail {
Integer nextHop;
Integer pathCost;
public RouteDetail(Integer nextHop, Integer pathCost) {
this.nextHop = nextHop;
this.pathCost = pathCost;
}
public Integer getNextHop() {
return nextHop;
}
public void setNextHop(Integer nextHop) {
this.nextHop = nextHop;
}
public Integer getPathCost() {
return pathCost;
}
public void setPathCost(Integer pathCost) {
this.pathCost = pathCost;
}
}
private void propagateChanges() {
print_route_info();
send_Updates_To_Neighbors(create_String_Of_Routes().getBytes());
}
public static void main(String[] args) {
new Router(Integer.parseInt(args[0]));
}
}
/*
* File Name : NetworkBoot.java
* Public Class Name : NetworkBoot
*
*/
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
*
* NA1 project 2 spring 2009 semester
* #author sunny jain
*
*
*/
public class NetworkBoot {
public static void main(String[] args) {
try {
DatagramSocket dSoc = new DatagramSocket(4000, InetAddress.getByName("127.0.0.1"));
String[] sendD = {"4006:3;4007:5;4009:2;", "4005:3;4007:3;4008:6;", "4005:5;4006:3;", "4009:2;4006:6;", "4008:2;4005:2;"};
for (int i = 0, port = 4005; i < 5; i++) {
dSoc.send(new DatagramPacket(sendD[i].getBytes(), sendD[i].length(), InetAddress.getByName("127.0.0.1"), port++));
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
DatagramSocket socket = new DatagramSocket(4445, InetAddress.getByName("127.0.0.1"));
while (true) {
try {
// note final ..
final byte[] buf = new byte[2000];
// receive request
DatagramPacket recvRequest = new DatagramPacket(buf, buf.length);
socket.receive(recvRequest);
//Some process of data in datagram
(new Thread(new Runnable() {
public void run () {
// do stuff with data in buf
...
}
})).start();
} catch (IOException e) {
e.printStackTrace();
}
}
I haven't done this in Java, but, you can (or should) pass more than one simultaneous datagram buffer to the socket (either with several threads each invoking the synchrnonous receive method, or preferably with one thread invoking an asynchrnonous receive method more than once).
The advantage of passing multiple simultaneous datagram buffers to the socket is obvious: i.e. the socket will still have a buffer (into which to receive the next datagram) even while it has already filled one buffer (with a previous datagram) and passed that buffer back to you.
You might ask, "in what sequence will the buffers be passed back to me?" and the answer to that is, "it shouldn't matter." If the sequence in which you process datagrams is important then the datagrams themselves should contain a sequence number (because datagrams might get out of sequence as they're routed over the network, whether or not you've passed multiple simultaneous to the local socket with a consequent possibility of "simultaneous" receives being delivered back to you out of sequence).
It is worth remembering UDP is lossy transport, while minimising packet loss is a good idea you should never assume you will get every packet, (or that the packets will arrive in the order you sent them)

Categories