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

发布于 2024-07-25 22:20:55 字数 309 浏览 2 评论 0原文

我正在尝试测试从 USB 端口(连接设备时为 COM25)读取数据的代码,该端口是在设备连接到我的计算机和船上时创建的。 我不在船上时无法为 USB 设备供电,因此测试很困难。 有人可以让我知道如何模拟 COM 端口并向其写入数据,以便我的测试程序能够连接到该模拟 COM 端口并读取该数据吗?

我正在从 Java 程序中读取此内容,但模拟不需要使用 Java 或任何特定语言。 只是一个模拟 COM 端口并允许我连接到它的程序。 我从 AGG Software 下载了一个 COM 端口模拟器,它似乎正在写入我认为的 COM25,但我无法从 Java 测试连接到它。

I'm trying to test my code that reads from a USB port (COM25 when the device is connected) that is created when a device is connected to my computer and to a boat. I cannot power the USB device when not on the boat so testing is difficult. Can someone let me know how to simulate a COM port and write data to it so my test program is able to connect to that simulated COM port and read that data?

I'm reading this from a Java program but the simulation doesn't need to be in Java or any specific language. Just a program that will simulate the COM port and allow me to connect to it. I downloaded a COM port emulator from AGG Software and it appears that it's writing to what I deem COM25 but I'm not able to connect to it from my Java test.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

岁月苍老的讽刺 2024-08-01 22:20:55

此类问题的一般答案是将与 COM 端口通信的代码包装在实现接口的类中。 如果您将其作为外观(模式)执行,那么您还可以使您调用的 COM 方法从您的角度来看变得合理。

然后可以模拟或伪造该接口以进行测试。 (有一篇关于测试对象的很棒的文章,但我还没有找到它。)这里的一个优点是,您可以创建一个假版本,该版本会抛出异常或以其他方式执行端口可能执行的操作,但在实践中很难做到。

The general answer for this kind of problem is to wrap the code that talks to the COM port in a class that implements an interface. If you do this as a Facade (pattern) then you can also make the COM methods you call sensible from your end.

The interface can then be mocked or faked for the test. (There is a great article on test objects, but I haven't been able to find it yet.) One advantage here is that you can create a fake version that throws exceptions or otherwise does things that are possible for the port to do but hard to get it to do in practice.

泪之魂 2024-08-01 22:20:55

在我工作的地方,我们通过让模拟器完全不欺骗 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();
                }
            } 


     }
}

希望这有帮助!

Where I work, we solved a similar issue by having our emulator not spoof a COM port at all. Here's how you can do it:

  • Define an interface for talking with your COM port, something like IUsbCommService
  • Implement your real COM-communcation service, using the standard Java Comm API
  • For your emulator, simply kick of a thread that spits out the same sort of data you can expect from your USB device at regular intervals.
  • Use your IOC framework of choice (e.g., Spring) to wire up either the emulator or the real service.
  • As long as you hide your implementation logic appropriately, and as long as you code to your interface, your service-consumer code won't care whether it's talking to the real USB device or to the emulator.

For example:

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();
                }
            } 


     }
}

Hope this helps!

强者自强 2024-08-01 22:20:55

感谢迄今为止所有的答案! 以下是我根据工作人员的建议最终所做的事情。

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

(我只是随机选择了一个免费的数据模拟器和虚拟串行端口包。那里有很多替代品)

  1. 使用 VSPD 创建虚拟串行端口 24 和 25,并通过虚拟零调制解调器电缆连接它们。 这实际上在 24 处创建了一个写入端口,在 25 处创建了一个读取端口。

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

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

Thanks to all the answers so far! Here's what I ended up doing as a result of recommendations from someone at work.

  1. Downloaded the COM Port Data Emulator (CPDE) from AGG Software
  2. Downloaded the Virtual Serial Port Driver (VSPD) from Eltima Software

(I just randomly picked a free data emulator and virtual serial port package. There are plenty of alternatives out there)

  1. Using VSPD, created virtual serial ports 24 and 25 and connected them via a virtual null modem cable. This effectively creates a write port at 24 and a read port at 25.

  2. Ran the CPDE, connected to 24 and started writing my test data.

  3. Ran my test program, connected to 25 and was able to read the test data from it

伤痕我心 2024-08-01 22:20:55

本节中有很多相关答案。 但就我而言,我个人使用虚拟串口驱动程序,它非常适合我。 但我必须承认,在创建虚拟端口时有很多选择:freevirtualserialports.com; comOcom 等。 但我还没有机会使用它们,所以我解决这个问题的建议是虚拟串口驱动程序。

There are plenty of relevant answers in this section. But as for me, I personally use Virtual Serial Port Driver, which works perfect for me. But I must admit that there are plenty alternatives when it comes to creating virtual ports: freevirtualserialports.com; comOcom to name a few. But I haven't got a chance to use them, so my recommendation for solving this problem is Virtual Serial Port Driver.

无人接听 2024-08-01 22:20:55

我推荐 fabulatech 的虚拟调制解调器。
http://www.virtual-modem.com 获取它

您可能还想获取 COM用于测试的端口监视器 - 您可以在以下位置找到它
http://www.serial-port-monitor.com

祝船好运! :)

I recommend fabulatech's virtual modem.
Get it at http://www.virtual-modem.com

You might also want to get a COM port monitor for your tests - You can find it at
http://www.serial-port-monitor.com

Good luck with the boat! :)

梦归所梦 2024-08-01 22:20:55

我使用 com0com ,它非常适合我的需要。

I use com0com and it works great for what I need.

追星践月 2024-08-01 22:20:55

除了所有其他之外,我还想添加这个漂亮的免费模拟器 https://sites.google.com /site/terminalbpp/ 我确实使用。 我还使用 AGG Com 端口数据模拟器。

In addition all others, I would like to added this nice, free emulator https://sites.google.com/site/terminalbpp/ I do use. I do also use AGG Com port data emulator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文