在com端口上同时读写

时间:2013-11-25 06:22:27

标签: java serial-port

我的问题是,是否可以在一个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没有运行?

2 个答案:

答案 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没有要阅读的元素。