简体   繁体   English

使用UDP LabVIEW与UDP c ++套接字通信

[英]Using UDP LabVIEW to comunicate with UDP c++ socket

I have to integrate LabVIEW and C++ code that will eventually go on an off board processor on an FRC Robot. 我必须集成LabVIEW和C ++代码,这些代码最终将用于FRC Robot上的板外处理器。

I only started programming in C++ a couple of months ago, so I have little experience with doing anything too complex in C++. 我几个月前才开始用C ++编程,所以我在C ++中做任何过于复杂的事情都没什么经验。

I decided to integrate LabVIEW and C++ through UDP communication (I chose UDP over TCP because I tried TCP and it generated too much lag for my purposes). 我决定通过UDP通信集成LabVIEW和C ++(我选择UDP over TCP,因为我试过TCP,它为我的目的产生了太多的延迟)。 I wrote my program C++ client UDP program, but when it came to programming my UDP program in LabVIEW, I got confused. 我编写了程序C ++客户端UDP程序,但是当我在LabVIEW中编写UDP程序时,我感到很困惑。

In C++ there seems to be a clear distinction between client and server UDP programs. 在C ++中,客户端和服务器UDP程序之间似乎有明显的区别。 In C++ it seems that the client tries to connect to the server and the server responds. 在C ++中,似乎客户端尝试连接到服务器并且服务器响应。 However, in LabVIEW, the server seems to be determined by who sends first. 但是,在LabVIEW中,服务器似乎取决于谁先发送。

My C++ code is below along with a picture of my attempt at a LabVIEW program that didn't work. 我的C ++代码如下,以及我尝试使用LabVIEW程序的图片。 Thank you for any help you provide (ps if you could show me how to do this using a dll that would be very helpful because I couldn't find any good help). 感谢您提供的任何帮助(ps如果您可以使用dll告诉我如何使用这将非常有用,因为我找不到任何好的帮助)。

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#include <Windows.h>

#pragma comment(lib, "Ws2_32.lib")

using namespace std;

#define Input_PORT "0914"
#define Output_PORT "152120"
#define General_PORT "444"

int main(int argc, char* argv[]) {

    WSADATA wsaData; //data for winsock

    int iResult; //result of intelizing winsock

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }
    printf("WSA Intelized: %d\n", iResult);

    system("pause");

    //Creating Socket
    struct addrinfo *result = NULL, *ptr = NULL, hints;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo(argv[1], General_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    SOCKET ConnectSocket = INVALID_SOCKET; //Create Connecting Socket

                                           // Attempt to connect to the first address returned by
                                           // the call to getaddrinfo
    ptr = result;

    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);


    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    printf("Socket Created\n");
    system("pause");

    // Connect to server.
    iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
    }

    // Should really try the next address returned by getaddrinfo
    // if the connect call failed
    // But for this simple example we just free the resources
    // returned by getaddrinfo and print an error message

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }

    printf("Connected\n");
    system("pause");

    return 0;
}

LabVIEW Block Diagram LabVIEW程序框图

The UDP protocol in general has no "connection", it is connectionless. UDP协议一般没有“连接”,它是无连接的。 A packet gets send out to an IP address and a port and there is no supervision if that packet gets received or not. 数据包会被发送到IP地址和端口,如果收到该数据包,则无法监控。

Both sides can listen on an UDP ports as well as they can send data to another UDP ports/IP addresses in the network. 双方都可以监听UDP端口,也可以将数据发送到网络中的其他UDP端口/ IP地址。 If you call one side server (because it is responding to a command) or client (because it is sending a command an it is awaiting a repsonse to it) is just defined by your application. 如果你调用一方服务器(因为它正在响应一个命令)或客户端(因为它正在发送命令,它正在等待对它的回复)只是由你的应用程序定义。

An UDP packet contains a "destination port number" as well as a "source port number". UDP数据包包含“目标端口号”以及“源端口号”。 A receiver listens on a specific port (which is for the sender the "destination port") and the sender sends data to this port. 接收方侦听特定端口(发送方为“目标端口”),发送方将数据发送到此端口。 The receiver gets with the "source port number" from the sender the information where the other side is listening for the case that it wants to send something back. 接收方从发送方获取“源端口号”,其中另一方正在侦听它想要发送回去的情况。

I found there some helpful information regarding "UDP socket programming in winsock", which I used for my test programm (i cannot post more links right now with my reputation status, so please add http:// on your own to it): www.binarytides.com/udp-socket-programming-in-winsock 我找到了一些有关“winsock中的UDP套接字编程”的有用信息,我用于我的测试程序(我现在无法发布更多链接以及我的声誉状态,所以请自行添加http://):www .binarytides.com / UDP套接字编程功能于winsock的

#include "stdafx.h"

#include<stdio.h>
#include<winsock2.h>
#include <Ws2tcpip.h>

#pragma comment(lib,"ws2_32.lib") // Winsock Library

#define REMOTE_SERVER_NAME "127.0.0.1"  // IP address of udp remote server
#define REMOTE_SERVER_PORT 61557    // UDP port of the remote server which is listening
#define LOCAL_RCV_BUF_LEN 20    // max. length of receiving buffer
#define LOCAL_CMD_MSG_LEN 10    // max. length of command to send

int main(void)
{
    struct sockaddr_in sockaddr_in1;    // the SOCKADDR_IN structure specifies a transport address and port for the AF_INET address family.
    int socket1;    // descriptor referencing the socket
    int sockaddr_in1_len = sizeof(sockaddr_in1);
    char cmd_message[LOCAL_CMD_MSG_LEN];    // command message, read from input keys, send to the UDP server
    char rcv_buf[LOCAL_RCV_BUF_LEN];    // receive buffer to store received data
    WSADATA wsdata1;    // contains information about the Windows Sockets implementation

    // initialise winsock
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2, 2), &wsdata1) != 0)
    {
        printf("Failed. Error Code : %d", WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("Initialised.\n");

    // create socket
    if ((socket1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
    {
        printf("socket() failed with error code : %d", WSAGetLastError());
        exit(EXIT_FAILURE);
    }

    // setup address structure
    memset((char *)&sockaddr_in1, 0, sizeof(sockaddr_in1));
    sockaddr_in1.sin_family = AF_INET;
    sockaddr_in1.sin_port = htons(REMOTE_SERVER_PORT);
    inet_pton(AF_INET, REMOTE_SERVER_NAME, &sockaddr_in1.sin_addr.S_un.S_addr);

    // start communication
    while (1)
    {
        printf("Enter command (d=date, t=time) : ");
        gets_s(cmd_message, sizeof(cmd_message) - 1);

        // send the message
        if (sendto(socket1, cmd_message, strlen(cmd_message), 0, (struct sockaddr *) &sockaddr_in1, sizeof(sockaddr_in1)) == SOCKET_ERROR)
        {
            printf("sendto() failed with error code : %d", WSAGetLastError());
            exit(EXIT_FAILURE);
        }

        // receive a reply and print it
        memset(rcv_buf, '\0', sizeof(rcv_buf)); // clear the buffer by filling null, it might have previously received data
        // try to receive some data, this is a blocking call
        if (recvfrom(socket1, rcv_buf, sizeof(rcv_buf), 0, (struct sockaddr *) &sockaddr_in1, &sockaddr_in1_len) == SOCKET_ERROR)
        {
            printf("recvfrom() failed with error code : %d", WSAGetLastError());
            exit(EXIT_FAILURE);
        }

        puts(rcv_buf);
    }

    closesocket(socket1);
    WSACleanup();

    return 0;
}

LabVIEW has four functions which are important in this context: LabVIEW有四个在这种情况下很重要的功能:

  • UDP Open (gets a port to listen on) UDP Open(获取侦听端口)
  • UDP Read (reads data from the port defined at "UDP Open", provides the remote port from a received package to send data back) UDP读取(从“UDP Open”定义的端口读取数据,从接收的包中提供远程端口以发送数据)
  • UDP Write (gets data to send as well as a remote port) UDP写入(获取要发送的数据以及远程端口)
  • UDP Close UDP关闭

LabVIEW Code LabVIEW代码

If required, you can download my test source from the following destination (same thing with the link as mentioned above): dl.dropboxusercontent.com/u/16833149/Simple%20UDP%20-%20Command%20Receiver.7z 如果需要,您可以从以下目的地下载我的测试源(与上面提到的链接相同):dl.dropboxusercontent.com/u/16833149/Simple%20UDP%20-%20Command%20Receiver.7z

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM