Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[udpclient] doesn't output connection information nor received data when using broadcast address #9

Open
avilleret opened this issue May 30, 2019 · 4 comments

Comments

@avilleret
Copy link

When I'm connecting to an UDP server with it's IP address, it answer with "acknowledge"
when I'm connection with a broadcast IP (i.e. 192.168.0.255) I didn't not receive the answer, but a python script does.

My UDP server run on a Atmega 328P with an Ethernet shield, here the code :

/*
 UDPSendReceiveString:
 This sketch receives UDP message strings, prints them to the serial port
 and sends an "acknowledge" string back to the sender

 A Processing sketch is included at the end of file that can be used to send
 and received messages for testing with a computer.

 created 21 Aug 2010
 by Michael Margolis

 This code is in the public domain.
 */


#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0x98, 0x76, 0xB6, 0x11, 0x18, 0x30
};

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged";        // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
  
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // start the Ethernet connection:
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    } else if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    // no point in carrying on, so do nothing forevermore:
    while (true) {
      delay(1);
    }
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  
  // start UDP
  Udp.begin(localPort);
}

unsigned long count = 0;

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i=0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  delay(10);
}

.
You will find the client.py and client.pd script that demonstrate the issue.
But you'll need an arduino and an ethernet shield to reproduce it.
client-issue.tar.gz
Unfortunately I could not reproduce exactly the same behavior with a Python script as UDP server

@avilleret
Copy link
Author

wireshark shows that the server is replying well with the same message as if broadcast is disabled
but client says that Destination unreachable (Port unreachable)

so I tried to add an UDP receive on that port, but Pd says that the port is already in use.

@avilleret
Copy link
Author

finally I got a very simple but working udpclient / udpserver pair in plain C that demonstrate the issue.

I found the code here : http://www.cs.ubbcluj.ro/~dadi/compnet/labs/lab3/udp-example1-c.html
I tuned it to work with broadcast.
iemnet-issue9.tar.gz

You'll find the modified udpclient.c and udpserver.c as well as a client.pd patcher.
I ran the server with ./udpserver 8888
When running udpclient with ./udpclient 192.168.0.5 8888 I got an acknowledgement after sending some string.
I got the same acknowledgement when starting with 192.168.0.255 broadcast IP.

But with client.pd, I got the acknowledgement only when I connect with unicast IP but not with broadcast.

@avilleret
Copy link
Author

hum... injecting the following code before the connect call works, but not after

  post("snd some data...");
  char buffer[256];
  sprintf(buffer, "c'est la fête!\n");

  int length=sizeof(struct sockaddr_in);

  int n=sendto(sockfd,buffer,strlen(buffer),0,&server,length);

  if (n < 0) error("Sendto");

  struct sockaddr_in from;

  n = recvfrom(sockfd,buffer,256,0,&from, &length);

  if (n < 0) error("recvfrom");

  post("Got an ack: %s",buffer);
  post("done");

commenting the connect() block make it work again but in that case, the answer is never fired in the left outlet.

@umlaeute
Copy link
Owner

umlaeute commented Jun 3, 2019

confirmed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants