如何模拟一个COM端口、向其写入数据并从中读取数据?

9
我正在尝试测试从USB端口读取数据的代码(当设备连接时为COM25),该端口是在设备连接到我的电脑和船上时创建的。我无法在不在船上时给USB设备供电,因此测试很困难。请问是否有人能告诉我如何模拟COM端口并向其写入数据,以便我的测试程序能够连接到该模拟的COM端口并读取该数据?
我正在从Java程序中读取这个数据,但模拟程序不需要使用Java或任何特定的语言。只需要一个能够模拟COM端口并允许我连接的程序。我从AGG Software下载了一个COM端口仿真器,它似乎正在写入我认为是COM25的端口,但我无法从我的Java测试中连接到它。
7个回答

5
这种问题的一般解决方案是将与COM端口通信的代码封装在实现接口的类中。如果你将其作为Facade(模式)来实现,那么你还可以使你调用的COM方法变得更加合理。
接口可以被模拟或伪造以进行测试。(有一篇关于测试对象的好文章,但我还没有找到它。)这里的一个优点是你可以创建一个虚假版本,抛出异常或者执行其他在实践中难以实现但端口可能会做的事情。

3
在我工作的地方,我们通过让模拟器不伪造COM端口来解决了类似的问题。以下是您可以执行的操作:
  • 定义一个与您的COM端口通信的接口,例如IUsbCommService
  • 使用标准Java Comm API实现您的真实COM通信服务
  • 对于您的模拟器,只需启动一个线程,以定期间隔输出您可以从USB设备中期望的相同数据。
  • 使用您选择的IOC框架(例如Spring)来连接模拟器或真实服务。
  • 只要适当隐藏您的实现逻辑,并且只要编写符合接口的代码,您的服务使用者代码将不会关心它是与真实的USB设备还是与模拟器进行通信。
例如:
import yourpackage.InaccessibleDeviceException;
import yourpackage.NoDataAvailableException;

public interface IUsbProviderService {

    public void initDevice() throws InaccessibleDeviceException;

    public UsbData getUsbData() 
        throws InaccessibleDeviceException, NoDataAvailableException;
}

// The real service
import javax.comm.SerialPort; //....and the rest of the java comm API 

public class UsbService implements IUsbProviderService {
.
.
.
}

// The emulator
public class UsbServiceEmulator implements IUsbProviderService {
    private Thread listenerThread;
    private static final Long WAITTIMEMS = 10L;
    private String usbData;

    public UsbServiceEmulator(long maxWaitTime) throws InaccessibleDeviceException{
        initialize();
        boolean success = false;
        long slept = 0;

        while (!success && slept < maxWaitTime) {
            Thread.sleep(WAITTIMEMS);
            slept += WAITTIMEMS;

        }
    }

    private void initialize() throws InaccessibleDeviceException{
        listenerThread = new Thread();
        listenerThread.start();
     }

     private class UsbRunner implements Runnable {
        private String[] lines = {"Data line 1", "Data line 2", "Data line 3"};
        public void run() {
            int line = 0;
            while(true) {

                serialEvent(lines[line]);

                if(line == 3) {
                    line = 0;
                } else {
                    line++;
                }

                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    //handle the error
                }
            }

        private void serialEvent(String line) {
            if(/*you have detected you have enough data */) {
                synchronized(this) {
                    usbData = parser.getUsbData();
                }
            } 


     }
}

希望这可以帮到你!

3

感谢到目前为止所有回答!这是我根据工作中某人的建议所做的结果。

  1. 从AGG Software下载了COM端口数据模拟器(CPDE)
  2. 从Eltima Software下载了虚拟串口驱动程序(VSPD)

(我只是随机选择了一个免费的数据模拟器和虚拟串口包。市场上有很多其他的替代品)

  1. 使用VSPD创建虚拟串口24和25,并通过虚拟空模电缆将它们连接起来。这有效地在24处创建了一个写入端口,在25处创建了一个读取端口。

  2. 运行CPDE,连接到24并开始编写我的测试数据。

  3. 运行我的测试程序,连接到25,就能够从中读取测试数据。


2

在这个领域有很多相关的答案。但是就我个人而言,我使用Virtual Serial Port Driver,它对我来说非常完美。但我必须承认,在创建虚拟端口方面,有许多替代方案:比如freevirtualserialports.com和comOcom等。但我还没有用过它们,所以我对解决此问题的建议是使用Virtual Serial Port Driver。


1

1

虚拟调制解调器是否具有可供程序员访问的API?因为从提供的信息中我没有看到。至于监视串行端口,该产品看起来不错。但是如果您只需要输入控制台,HyperTerminal同样可以胜任。 - rtperson

1

我使用com0com,它完全符合我的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接