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

时间:2017-02-08 04:09:27

标签: c++ sockets udp labview

我必须集成LabVIEW和C ++代码,这些代码最终将用于FRC Robot上的板外处理器。

几个月前我才开始用C ++编程,所以我在C ++中做任何过于复杂的事情都没什么经验。

我决定通过UDP通信集成LabVIEW和C ++(我选择了UDP over TCP,因为我尝试过TCP,它为我的目的产生了太多的延迟)。我编写了程序C ++客户端UDP程序,但是当我在LabVIEW中编写UDP程序时,我感到很困惑。

在C ++中,客户端和服务器UDP程序之间似乎有明显的区别。在C ++中,似乎客户端尝试连接到服务器并且服务器响应。但是,在LabVIEW中,服务器似乎取决于谁先发送。

我的C ++代码如下,以及我尝试LabVIEW程序无效的图片。感谢您提供的任何帮助(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

1 个答案:

答案 0 :(得分:0)

UDP协议一般没有“连接”,它是无连接的。 数据包会被发送到IP地址和端口,如果收到该数据包,则无法监控。

双方都可以监听UDP端口,也可以将数据发送到网络中的其他UDP端口/ IP地址。 如果你调用一方服务器(因为它正在响应一个命令)或客户端(因为它正在发送命令,它正在等待对它的回复)只是由你的应用程序定义。

UDP packet包含“目标端口号”以及“源端口号”。 接收方侦听特定端口(发送方为“目标端口”),发送方将数据发送到此端口。 接收方使用发送方的“源端口号”获取另一方正在侦听的信息,以便发送回去的情况。

我发现有一些关于“winsock中的UDP套接字编程”的有用信息,我用于我的测试程序(我现在无法使用我的声誉状态发布更多链接,所以请自行添加http:// ): www.binarytides.com/udp-socket-programming-in-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有四个在这方面很重要的功能:

  • UDP Open(获取侦听端口)
  • UDP Read(从“UDP Open”定义的端口读取数据,从收到的包中提供远程端口以发回数据)
  • UDP Write(获取要发送的数据以及远程端口)
  • UDP关闭

LabVIEW Code

如果需要,您可以从以下目的地下载我的测试源(与上述链接相同): dl.dropboxusercontent.com/u/16833149/Simple%20UDP%20-%20Command%20Receiver.7z