2017-02-08 45 views
1

LabVIEWとC++コードを統合する必要があり、最終的にはFRCロボットのオフボードプロセッサを使用します。UDP LabVIEWを使用してUDP C++ソケットと通信する

私は数ヶ月前にC++でプログラミングを始めただけなので、C++で複雑すぎることはほとんど経験していません。

私は、LabVIEWとC++をUDP通信で統合することに決めました(私はTCPを試したのでUDPを選択しました。私は自分のプログラムC++クライアントUDPプログラムを書いていましたが、LabVIEWで私のUDPプログラムをプログラミングするときは混乱しました。

C++では、クライアントとサーバーのUDPプログラムが明確に区別されているようです。 C++では、クライアントがサーバーに接続しようとしていて、サーバーが応答しているようです。しかし、LabVIEWでは、サーバーは誰が最初に送信するかによって決定されるようです。

私のC++コードは、動作しなかったLabVIEWプログラムでの私の試みの写真と一緒です。私が何か良い助けを見つけることができなかったので、非常に役立つだろう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

+0

あなたはTCPがあまりにも遅れを与えたと言います。 TCP_NODELAYを設定しましたか? –

+0

SOCK_STREAMはTCPを指定するので、あなたが投稿したC++プログラムはUDPではなくTCPで通信していることに注意してください。 UDPをしたいのであれば、SOCK_DGRAMを指定する必要があります(connect()コマンドを取り除き、send()/ recv(); send()/ recvfrom ()はUDP通信にはあまり役に立ちません) –

+0

-John Zwinch、TCP_NODELAYを試しました(私はあなたがLabVIEW VIについて話していると仮定しています) –

答えて

0

一般的にUDPプロトコルがない "接続" を持っていない、それはコネクションレスです。 パケットはIPアドレスとポートに送信され、そのパケットが受信されるかどうか監視されません。

両側はUDPポートでリッスンできるだけでなく、ネットワーク内の別のUDPポート/ IPアドレスにデータを送信できます。 片方のサーバ(コマンドに応答しているため)またはクライアント(コマンドを送信しているため、そのサーバへの応答を待っている)を呼び出すと、アプリケーションによって定義されます。

UDP packetには、「送信元ポート番号」と「送信元ポート番号」が含まれています。 受信側は、特定のポート(送信側の「宛先ポート」)をリッスンし、送信側はこのポートにデータを送信します。 受信者は、送信元から「送信元ポート番号」を取得し、相手側が何かを返信したい場合にリスンしている情報を取得します。

私はテストプログラムのために使った "UDPソケットプログラミングのwinsock"に関する有益な情報を見つけました(私の評判の状態で今すぐリンクを追加することはできませんので、http://を自分で追加してくださいそれ): www.binarytides。

  • UDPオープン(リッスンするようにポートを取得します)
  • UDP読む: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は、この文脈において重要である4つの機能を持っています(「UDP Open」で定義されたポートからデータを読み取り、受信したパッケージからリモートポートを提供してデータを返す)

  • UDP書き込み(送信するデータとリモートポートを取得)
  • UDP閉じる

LabVIEW Code

必要な場合は、次の目的地(前述したように、リンクと同じもの)からの私のテストソースダウンロードすることができます。 dl.dropboxusercontent.com/u/16833149/Simple%20UDP%を20%20Command%20Receiver.7z

+0

おかげさまで助けてくれてありがとう –