How to do UDP broadcast transmission by Wi-Fi communication on iOS14 beta6?

UDP broadcast communication ("255.255.255.255") is not possible in iOS14 beta6 and Xcode beta6 development environment. The broadcast communication between the product device and UDP is the first communication start trigger, so if this broadcast is not possible, it will be impossible to communicate. How can I get it done?
Without this communication solution, it will be necessary to deal with complaints from users who are having trouble after releasing the application.






Accepted Reply


Thank you for your reply.

I was able to support UDP with the content of the professor.

best regards

Replies

iOS 14 beta added a feature called local network privacy. For more on this, see:
Note that while the latter has a focus on the new NWConnectionGroup API, local network privacy applies equally to the legacy BSD Sockets API.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Eskimo,Thank you for your reply.

Multicast permission request was added to Provision Profile of App.

Looking at the specified URL,
inside the project
Added "Local network permissions" to info.plist,
and it looks like Swift's iOS 14 specific code.

With the legacy source,
the broadcast transmission will result in an error “sendto: No route to host”,
and the situation will be the same as before adding authority.
What should i do? ?

Please point out the mistake in the source code.

#import <Foundation/Foundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
  • (int) MSDPsendRequestPrnE {

   
  int fdsend;
  struct sockaddr
in addrsend;
   
  int yes = 1;
   
  if((fd
send = socket(AFINET, SOCKDGRAM, 0)) < 0) {
//    NSLog(@"%@", @"sendRequestE:socketerror");
    perror("socket");
    return -1;
  }
   
  memset(&addrsend, 0, sizeof(addrsend));
  addrsend.sinfamily   = AFINET;
  addr
send.sinport    = htons(kPrinterSearchTaskREQPORT ); //kPrinterSearchTaskREQPORT is Define Number 49111
addr
send.sinaddr.saddr = inetaddr("255.255.255.255");
  
  setsockopt(fd
send, SOLSOCKET, SOBROADCAST, (char *)&yes, sizeof(yes));

  if(sendto(fdsend, "DAT rE", 6, 0,
       (struct sockaddr *)&addr
send, sizeof(addrsend)) < 0) {
    perror("sendto");//<----This is Error occurs!!!
  }
//  NSLog(@"%@", @"sendRequest
E:socketclose");
  close(fd
send);
   
   
  return 0;
}
I don’t see any code to bind your socket to a specific interface. My experience is that this is critical when dealing with multicast and broadcast in BSD Sockets.

The weapon of choice here is the IP_BOUND_IF socket option. In a not-at-all-curious coincidence, I’ve been working on code to test this. The code pasted in below works for me on iOS 14.0b7.

ps Please use a code block to post code. It’s very hard to read without that. To format text in a code block, use the <> button.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"



Code Block
// In this context:
//
// * `inputs.localAddress` is a `sockaddr_in` with `sin_port` set to
// the source port and `sin_addr` set to `INADDR_ANY`.
//
// * `inputs.interfaceIndex` is the interface index that I want to
// broadcast on, as returned by `if_nametoindex`.
let sock = try FileDescriptor.socket(Int32(inputs.localAddress.saFamily), SOCK_DGRAM, 0)
try sock.setSocketOption(SOL_SOCKET, SO_REUSEPORT, 1 as Int32)
try sock.setSocketOption(IPPROTO_IP, IP_BOUND_IF, inputs.interfaceIndex)
try sock.setSocketOption(SOL_SOCKET, SO_BROADCAST, 1 as Int32)
try sock.bind(inputs.localAddress)


Note This code is using my own custom extensions to the new Swift System framework, but there’s a direct mapping between those extensions and the traditional BSD Sockets API.
Thank you for your reply

Is the information source the UDP Server side? I'm a little confused by this proposal, so I'll confirm it.

I think the problem is the socket transmission on the client side.

UDP Client logic is Socket → Sendto->Close
Is this okay?

There is a bind in your source.
Is bind required on the Client side?

Please tell me the solution.

UDP Client logic is Socket → Sendto -\> Close

Is this okay?

Probably not )-: At a minimum you need to set the SO_BROADCAST option.

There is a bind in your source. Is bind required on the Client side?

Depends on what you mean by “bind” (-:
  • The bind system call is only required if you want to set the source port (which I do in my example).

  • The IP_BOUND_IF is important in most situations. This specifies the interface that’s used for the broadcast. Without this the system picks an interface on your behalf and that’s often not the interface you want.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
It seems that the whole thing is confusing. To organize the story again. .. ..

My app sends data with a UDP limited broadcast address.
I will put the source code with your suggestion below.

Code Block
#import <Foundation/Foundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
//Send Data UDP
(int) MSDPsendRequestPrnE {
   
  int fdsend;
  struct sockaddrin addrsend;
   
  int yes = 1;
   unsigned int wifiInterface;
   
  wifiInterface = if_nametoindex("en0");
   
   //socket
  if((fdsend = socket(AFINET, SOCKDGRAM, 0)) < 0) {
//    NSLog(@"%@", @"sendRequestE:socketerror");
    perror("socket");
    return -1;
  }
   
  memset(&addrsend, 0, sizeof(addrsend));
  addrsend.sinfamily   = AFINET;
  addrsend.sinport    = htons(kPrinterSearchTaskREQPORT ); //kPrinterSearchTaskREQPORT is Define Number 49111
addrsend.sinaddr.saddr = inetaddr("255.255.255.255");
//setsockopt
if (setsockopt(fd_send, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes))){
    NSLog(@"%@", @"sendRequest_E:socket_opt_error0");
    perror("setsocketpt");
  }
  if ( setsockopt(fd_send, IPPROTO_IP, IP_BOUND_IF, (char *)&wifiInterface, sizeof(wifiInterface))){
    NSLog(@"%@", @"sendRequest_E:socket_opt_error1");
    perror("setsocketpt");
  }
//sendto
  if(sendto(fdsend, "DAT rE", 6, 0,
       (struct sockaddr *)&addrsend, sizeof(addrsend)) < 0) {
    perror("sendto");//<----This is Error occurs!!!
  }
//  NSLog(@"%@", @"sendRequestE:socketclose");
  close(fdsend);
   
   
  return 0;
}

Xcode Log:
sendto: No route to host
sendto: No route to host
sendto: No route to host
sendto: No route to host

In iOS14, to support this process
I saw the URL of How to use multicast networking in your app.

Add multicast to ProvisionProfile and
Added "com.apple.developer.networking.multicast" entitlement in Xcode. It has been confirmed in the terminal.

I expected it to be normal. UDP Limited Broadcast Address Data Transmission by adding entitlement to Project with Provison Profile request and "com.apple.developer.networking.multicast"
motion

Is this correspondence wrong?

Please let me know if you still need it.
Well, that’s annoying. It turns out that the bind is significant. Adding the following to your test code gets it working:

Code Block
struct sockaddr_in local_addr;
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(12345);
local_addr.sin_addr.s_addr = INADDR_ANY;
bind(fd_send, (const struct sockaddr *)&local_addr, sizeof(local_addr));


I’m testing on iOS 14.0b7 (haven’t yet had a chance to install b8).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for your reply.

I was able to support UDP with the content of the professor.

best regards