我的问题是,是否可以在一个COM端口上同时读写?这只是为了演示目的,我只会在键盘上按F5
键时读取端口,但出于演示目的,我试图同时读写但不能这样做。它说some other program is using the port
。
更新
package com_port;
import java.io.*;
import java.util.*;
import javax.comm.*;
public class simplerad implements Runnable, SerialPortEventListener
{
static CommPortIdentifier portId;
static Enumeration portList;
InputStream inputStream;
SerialPort serialPort;
Thread readThread;
public static void main(String[] args) throws Exception
{
portList = CommPortIdentifier.getPortIdentifiers();
System.out.println("SimpleRead Started.");
while (portList.hasMoreElements())
{
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
System.out.println ("Found " + portId.getName());
if (portId.getName().equals("COM7"))
{
OutputStream outputStream;
SerialPort writePort = (SerialPort) portId.open("SimpleWriteApp", 2000);
writePort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
outputStream = writePort.getOutputStream();
outputStream.write("AT+CENG=2".getBytes());
System.out.println("write done");
writePort.close();
simplerad reader = new simplerad();
}
}
}
}
public simplerad()
{
try
{
System.out.println("1");
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
}
catch (PortInUseException e)
{
e.printStackTrace();
}
try
{
System.out.println("2");
inputStream = serialPort.getInputStream();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
System.out.println("3");
serialPort.addEventListener(this);
}
catch (TooManyListenersException e)
{
e.printStackTrace();
}
serialPort.notifyOnDataAvailable(true);
try
{
System.out.println("4");
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e)
{
e.printStackTrace();
}
readThread = new Thread(this);
readThread.start();
}
public void run()
{
System.out.println("5");
try
{
System.out.println("6");
Thread.sleep(200);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public void serialEvent(SerialPortEvent event)
{
System.out.println("7");
switch (event.getEventType())
{
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
byte[] readBuffer = new byte[20];
try
{
System.out.println("8");
while (inputStream.available() > 0)
{
int numBytes = inputStream.read(readBuffer);
System.out.print(new String(readBuffer, 0, numBytes, "us-ascii"));
}
System.out.print(new String(readBuffer));
}
catch (IOException e)
{
e.printStackTrace();
}
break;
}
}
}
为什么serialEvent
没有运行?
答案 0 :(得分:3)
这里的问题是你试图打开相同的COM端口两次,答案是否定的,这是行不通的 - 至少你在这里做的方式。原因是底层操作系统只允许每个端口使用一个用户模式句柄。
但是,只要您的COM端口是双向的(大部分都是),您可以同时打开COM端口并对其进行读/写 - 这称为全双工模式。
要在您的应用程序中获得此行为,您希望一次打开“COM7”端口,然后让读取线程访问此原始对象,而不是尝试再次打开它。另一种方法是在打开后立即获取InputStream和OutputStream,然后在应用程序的其余部分使用这些对象。
我不确定为什么你的事件监听器没有被触发,但你的代码看起来有点复杂,你实际上在这里尝试做什么。打开/关闭可能会导致您错过事件通知。
这是一个关于你应该在open上做什么的例子,这应该比在读写之间打开/关闭端口更有效:
// Each of these could be object members so all your class methods have access
OutputStream outputStream;
InputStream inputStream;
SerialPort serialPort;
// Open the port one time, then init your settings
serialPort = (SerialPort)portId.open("SimpleWriteApp", 2000);
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
// Get the input/output streams for use in the application
outputStream = serialPort.getOutputStream();
inputStream = serialPort.getInputStream();
// Finally, add your event listener
serialPort.addEventListener(this);
答案 1 :(得分:0)
不,你不能在同一个端口上同时读写。 因为要避免死锁情况。
我浏览了你的代码,我发现......在while
循环
while (portList.hasMoreElements())
{
}
问题在于while
循环,因为portlist
没有要阅读的元素。