PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : gnu.io.PortInUseException - warum?



Tobiask
26-09-2006, 17:42
Hi,

und nochwas ;)

Hab jetzt was programmiert, nur manchma spinnt das Programm etwas, wenn ich es ein paar mal laufen lasse und dann nochmal starten will, kommt immer folgende Meldung:


gnu.io.PortInUseException: Unknown Application
at gnu.io.CommPortIdentifier.open(CommPortIdentifier. java:354)
at rs232comm.TwoWaySerialComm.connect(TwoWaySerialCom m.java:41)
at rs232comm.TwoWaySerialComm.main(TwoWaySerialComm.j ava:231)

Bedeutet ja das er nicht auf den COM1 Port zugreifen kann weil er schon genutzt wird, nur wie kann das sein wenn kein anderes Programm drauf zugreift und mein Javaprogramm auch nicht läuft?
Nach einem Neustart von Eclipse und einem ein/ausstöpseln des Kabels geht es sofort wieder ...
Jemand ne Idee?

Hier als Anhang ma das komplette Programm:

package rs232comm;



import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TwoWaySerialComm
{

// Konstruktor, Aufruf der Elternklasse
TwoWaySerialComm()
{
super();
}

// connect() Methode zum Verbindungsaufbau mit RS232 Schnittstelle
// Port wählen und Übertragungsdaten festlegen
// Schreiben und Lesen starten
void connect ( String portName ) throws Exception
{
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if ( portIdentifier.isCurrentlyOwned() )
{
System.out.println("Error: Port is currently in use");
}
else
{
CommPort commPort = portIdentifier.open(this.getClass().getName(),2000 );

if ( commPort instanceof SerialPort )
{
// BaudRate, Datenbits, Stopbits, Parity?
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(1200,SerialPort.DAT ABITS_7,SerialPort.STOPBITS_2,SerialPort.PARITY_NO NE);

// Input- und OutputStreams instanziieren
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();

// 2 Threads starten für Schreiben und Lesen
// Wichtig! Erst Schreiben und dann Lesen (siehe Metex DMM Handbuch)
(new Thread(new SerialWriter(out))).start();
(new Thread(new SerialReader(in))).start();

}
else
{
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}

// Klasse zum Lesen von Daten der RS232 Schnittstelle
public static class SerialReader extends JFrame implements Runnable
{
InputStream in;

public SerialReader ( InputStream in )
{
this.in = in;
}

// Klasse für die Aktionen (implementiert ActionListener)
class ActionLauscher implements ActionListener {

// Wenn eine Aktion getätigt wurde
public void actionPerformed(ActionEvent e){

// gedrückten Button auslesen
String label = e.getActionCommand();

if(label.equals("Exit")){

System.exit(1);

}

}

}

public void run ()
{

// benötigte Variablen setzen
JButton ende;
JLabel freq, relhum;
String frq = "0";

// LayoutManager wählen
setLayout(new FlowLayout());

// Anwendung schliessen wenn auf [x] gedrückt wird
setDefaultCloseOperation(WindowConstants.EXIT_ON_C LOSE);

// JPanel für ganze rechte Seite (Zeilen, Spalten, Abstand x, Abstand y)
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3,2,30,5));

// Bezeichnungen
JLabel freqlabel = new JLabel("Frequenz:");
JLabel relhumlabel = new JLabel("rel. Feuchtigkeit:");
JLabel empty = new JLabel();

// Buttons
ende = new JButton("Programm beenden");

// Datenausgabe
freq = new JLabel("--");
relhum = new JLabel("--");

// Look ändern
freq.setFont(new Font("Verdana",Font.BOLD,30));
relhum.setFont(new Font("Verdana",Font.BOLD,30));
freqlabel.setFont(new Font("Verdana",Font.BOLD,30));
relhumlabel.setFont(new Font("Verdana",Font.BOLD,30));
ende.setVisible(false);

// Adden
panel.add(freqlabel);
panel.add(freq);
panel.add(relhumlabel);
panel.add(relhum);
panel.add(empty);
panel.add(ende);

// panel adden
add(panel);

// ActionListener an Buttons binden
ende.addActionListener(new ActionLauscher());

SerialReader ft1 = new SerialReader(in);
ft1.setSize(800,120);
ft1.setLocationRelativeTo(null);
ft1.setResizable(true);
ft1.setVisible(true);

// Endlosschleife für den Thread, inkl. 2 Sekunden Pause
while(true){

// Datenpuffer anlegen
byte[] buffer = new byte[14];
int len = -1;

// Auslesen starten
try
{
while ( ( len = this.in.read(buffer)) > -1 )
{
System.out.print(new String(buffer,0,len));
frq += new String(buffer,0,len);
if(len == 0)
{
break;
}
}

// Datenformat anpassen und rel. Feuchtigkeit berechnen
String frequenz = frq.substring(4);
double relhumidity = (Integer.parseInt(frequenz.substring(2,5)))*0.25;

// GUI Daten anpassen
freq.setText(frequenz.substring(2,5)+" Hz");
relhum.setText(relhumidity+" %");

// Thread schlafen legen, danach gehts weiter, da Endlosschleife
try {Thread.sleep(2000);} catch (InterruptedException e) {}

}

//(new Thread(new Graphical())).start();

catch ( IOException e )
{
e.printStackTrace();
}

}

}
}

// Klasse zum Schreiben auf der RS232 Schnittstelle
public static class SerialWriter implements Runnable
{
OutputStream out;

public SerialWriter ( OutputStream out )
{
this.out = out;
}

public void run ()
{
try
{
// Wichtig! write() schreibt nur Integer Werte
// Metex DMM benötigt 'D' zum senden der Daten
// daher ein 'D' senden (als Integerwert)
// Beachten: großes D, kleines D würde nicht funktionieren
this.out.write((int)'D');

}
catch ( IOException e )
{
e.printStackTrace();
}
}
}

// main() Methode
public static void main ( String[] args )
{
try
{
// Verbindung herstellen zu COM1
(new TwoWaySerialComm()).connect("COM1");
}
catch ( Exception e )
{
e.printStackTrace();
}
}
}

falke2203
26-09-2006, 17:50
Gibt es eine Methode, um die Verbindung mit dem COM port zu kappen? Wenn ja, solltest du das machen bevor das Programm beendet wird, in etwa in dem folgenden if-Block


if(label.equals("Exit")){
System.exit(1);
}


Da zum Zugriff auf den COM port vermutlich native Bibliotheken verwendet werden, hast du mit dem System.exit nicht unbedingt Einfluss darauf, ob Ressourcen wieder freigegeben werden oder nicht...

Tobiask
26-09-2006, 17:55
Gibt es eine Methode, um die Verbindung mit dem COM port zu kappen? Wenn ja, solltest du das machen bevor das Programm beendet wird, in etwa in dem folgenden if-Block


if(label.equals("Exit")){
System.exit(1);
}


Da zum Zugriff auf den COM port vermutlich native Bibliotheken verwendet werden, hast du mit dem System.exit nicht unbedingt Einfluss darauf, ob Ressourcen wieder freigegeben werden oder nicht...

ja, gibt es, hm, daran könnte es liegen
siehe http://java.sun.com/products/javacomm/reference/api/index.html
void close()
Closes the communications port.
hjabs bis jetzt immer mit dem [x] oben am fenster beendet

falke2203
26-09-2006, 18:35
Da spricht ja auch nichts gegen... Du könntest einen WindowListener (http://java.sun.com/j2se/1.5.0/docs/api/java/awt/event/WindowListener.html) verwenden, um den ComPort zu schließen wenn man die Anwendung über [x] beendet

Tobiask
26-09-2006, 18:37
Da spricht ja auch nichts gegen... Du könntest einen WindowListener (http://java.sun.com/j2se/1.5.0/docs/api/java/awt/event/WindowListener.html) verwenden, um den ComPort zu schließen wenn man die Anwendung über [x] beendet

genau das hab ich eben noch eingebaut :)

falke2203
26-09-2006, 21:03
Dann nehme ich an es läuft jetzt alles so wie es soll?

Tobiask
27-09-2006, 05:55
Dann nehme ich an es läuft jetzt alles so wie es soll?

werde ich gleich testen, kanns zuhause leider nicht komplett machen
weil mir hier die hardware dazu fehlt, werd es gleich im der schule prüfen.