2017-11-24 3 views
0

Ich kämpfe mit UDP-Sockets. Ich möchte die Zeit für den Austausch von Daten zwischen zwei Rechnern vergleichen.Wie einfach senden UDP-Daten in C?

Ich schrieb schnell dieses Projekt https://github.com/nowox/udp-test in C, wo ich einen einfachen Client habe:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <fcntl.h> 
#include <netdb.h> 
#include <sys/time.h> 
#include <arpa/inet.h> 
#include <time.h> 
#include <errno.h> 

#define PORT (3000) 

#define SUBIMAGES (1000) 
#define FRAMES_PER_SUBIMAGES (23) 
#define UDP_FRAME (1442) 

#define SERVERADDRESS "127.0.0.1" // 138.131.156.36" 

#define BUFFER_SIZE (SUBIMAGES * FRAMES_PER_SUBIMAGES * UDP_FRAME) 


char buffer[BUFFER_SIZE]; 

/** 
* Populate the buffer with random data. 
*/ 
void build(uint8_t* buffer, size_t length) 
{ 
    for (size_t i = 0; i < length; i++) 
    { 
     buffer[i] = (rand() % 255) + 1; 
    } 
} 

int main(int argc, char **argv) 
{ 
    struct timespec start, end; 
    int sockfd; 
    struct sockaddr_in server; 

    printf("Build Data...\n"); 
    build(buffer, sizeof(buffer)); 

    printf("Configure socket...\n"); 
    sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if (sockfd < 0) 
    { 
     fprintf(stderr, "Error opening socket"); 
     return EXIT_FAILURE; 
    } 

    bzero((char*)&server, sizeof(server)); 
    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = inet_addr(SERVERADDRESS); 
    server.sin_port = htons(PORT); 

    printf("Send UDP data...\n"); 
    clock_gettime(CLOCK_MONOTONIC_RAW, &start); 
    for (size_t i = 0; i < BUFFER_SIZE; i += UDP_FRAME) 
    { 
     if (sendto(sockfd, &buffer[i], UDP_FRAME, 0, 
        (const struct sockaddr*)&server, sizeof(server)) < 0) 
     { 
      fprintf(stderr, "Error in sendto()\n"); 
      return EXIT_FAILURE; 
     } 
    } 
    clock_gettime(CLOCK_MONOTONIC_RAW, &end); 
    uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + 
         (end.tv_nsec - start.tv_nsec)/1000; 

    printf("Time to send %d subimages: %f[s]\n", SUBIMAGES, delta_us/1e6f); 
    printf("Finished...\n"); 

    return EXIT_SUCCESS; 
} 

Ich erwarte den UDP-Datenrahmen in Wireshark zu sehen, aber es scheint, dass ich nichts zu sehen.

Erste Frage: Warum sendet meine Steckdose nichts?

Ich fand heraus, dass es wegen WSL (Windows Subsystem für Linux) war. Also zog ich nach Ubuntu

Zweite Frage: Warum erhält mein Server nichts?

+0

Ich sehe Ihre Pakete mit tcpdump (sudo tcpdump -i lo -p udp -v). Hörst du die richtige Netzwerkschnittstelle? – dbrank0

+0

Richtig sieht es ok mit tcpdump ... Also habe ich ein anderes Problem mit meinem Server dann, die meine Pakete nicht erhalten :( – nowox

+0

Ich verbrachte einen ganzen Tag versucht, ein UDP-Problem so zu diagnostizieren, nur um herauszufinden, dass IT konfiguriert Netzwerk, um UDP Verkehr zwischen den zwei Computern zu blockieren, die ich auf prüfte. Müssen Sie möglicherweise firewall configurations justieren? – lockcmpxchg8b

Antwort

1

Sie binden Ihren Client an denselben Port wie Ihren Server. Dies ist nicht gültig. Sie müssen Ihren Client nicht binden.

Kommentieren Sie Ihren Bindungsaufruf im Client, und die Pakete werden vom zufällig ausgewählten Port an den Server gesendet. Ihr Server wird sie erhalten, aber Sie haben einen anderen Fehler in der Exit-Bedingung auf Ihrem Server. Fügen Sie also einen Ausdruck hinzu, wenn Sie einen Rahmen erhalten, um zu sehen, dass es tatsächlich passiert.

+0

Ich entfernte die Bindung vom Client. Ich erkannte, dass es ein Fehler war, aber immer noch. Der Server erhält nichts. – nowox

+0

Fügen Sie einen Ausdruck vor oder nach recv in Ihrem Server hinzu Ich, es empfängt Pakete (aber Ihre Version druckt nichts aus, da Schleife nie endet). – dbrank0