Best way to create a UDP network for Android
I recently asked a question regarding threading on Android (Google Daydream specific) which wasn't performing as expected. I was using a thread for communication to transfer information between an embedded system, and once the communication failed (i.e. the embedded system turned off, or any other 'can't transmit/receive' reason) the thread would abort and would attempt to reconnect to the embedded system until a connection is made again.
This works perfectly running in Unity (5.6) on Windows, but once ported to Android the thread seems to just hang once the network goes down and won't acknowledge that the thread has died. The Update() function continues to loop, but it's not until I leave the scene that the thread dies and the code continues to perform as expected (see my other post here).
I'm trying a new idea now where I'm assuming it's not the threading code which is problematic, or Android's inability to handle threads (as I've had no indication from anyone that what I'm doing can't be done on Android) but perhaps the handling of networks on Android or my UDP code.
I've got my UDP code below and I wanted to see if anyone saw anything which immediately looks wrong:
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets;
public class UDPConn : MonoBehaviour {
Socket sock;
IPEndPoint destEnd;
IPEndPoint endPoint;
EndPoint sender;
// Bool for connection status
public bool socketReady = false;
// Receive timeout (ms).
int rxTimeout = 1000;
byte[] msg;
// Try to initiate connection.
public bool setupSocket(int conPort)
{
try
{
String hostName = "";
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
hostName = ip.ToString();
}
}
System.Net.IPAddress ipaddress = System.Net.IPAddress.Parse(hostName);
endPoint = new IPEndPoint(ipaddress, conPort);
System.Net.IPAddress remoteIP = System.Net.IPAddress.Parse("192.168.20.2");
destEnd = new IPEndPoint(remoteIP, conPort);
sender = (EndPoint)destEnd;
sock = new Socket(endPoint.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
sock.Bind(endPoint);
sock.ReceiveTimeout = rxTimeout;
// Send message to 'wake' other side.
sock.SendTo(System.Text.Encoding.ASCII.GetBytes("Connect"), sender);
// Attempt to read from the socket. This will timeout if the other side isn't active.
string readData = readSocket();
if (readData != null) {
socketReady = true;
return true;
}
else
{
socketReady = false;
return false;
}
}
catch (Exception e)
{
Debug.Log("Socket error: " + e);
return false;
}
}
// Send message to server.
public void writeSocket(string theLine)
{
if (!socketReady)
{
return;
}
sock.SendTo(System.Text.Encoding.ASCII.GetBytes(theLine), sender);
}
// Read message from server.
public string readSocket()
{
try
{
msg = new Byte[256];
sock.ReceiveFrom(msg, ref sender);
String returnData = System.Text.Encoding.ASCII.GetString(msg);
return returnData;
}
catch (Exception e)
{
Debug.Log("Socket error: " + e);
return null;
}
}
// Disconnect from the socket.
public void closeSocket()
{
if (!socketReady)
{
return;
}
Debug.Log("UDPConn:closeSocket");
sock.Close();
socketReady = false;
}
}
Other than my code, I also saved the Logcat (see end of post) at the point of where I disconnected the network from the Android phone (by swiping down from the screen, disabling the WiFi). My other idea outside of the UDP code is that perhaps I need to catch some sort of network error from Android and handle it better. The first item in Logcat is the last Debug.Log message I sent within Unity, and the first cnss-daemon message is the point at which I disconnected the network. Is there anything in there that can help identify my issue?
Thanks very much for any help. Sorry for the long post.
06-30 14:07:56.150 19762 19966 I Unity : **Inside Thread Run()
06-30 14:07:56.150 19762 19966 I Unity : Stacktrace is not supported on this platform.
06-30 14:07:56.150 19762 19966 I Unity : (Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
06-30 14:07:56.150 19762 19966 I Unity :
06-30 14:07:56.149 651 651 W cnss-daemon: type=1400 audit(0.0:153): avc: granted { net_admin } for capability=12 scontext=u:r:cnss-daemon:s0 tcontext=u:r:cnss-daemon:s0 tclass=capability
06-30 14:07:56.149 651 651 W cnss-daemon: type=1400 audit(0.0:154): avc: granted { net_admin } for capability=12 scontext=u:r:cnss-daemon:s0 tcontext=u:r:cnss-daemon:s0 tclass=capability
06-30 14:07:56.149 651 651 W cnss-daemon: type=1400 audit(0.0:155): avc: granted { net_admin } for capability=12 scontext=u:r:cnss-daemon:s0 tcontext=u:r:cnss-daemon:s0 tclass=capability
06-30 14:07:56.149 651 651 W cnss-daemon: type=1400 audit(0.0:156): avc: granted { net_admin } for capability=12 scontext=u:r:cnss-daemon:s0 tcontext=u:r:cnss-daemon:s0 tclass=capability
06-30 14:07:56.149 651 651 W cnss-daemon: type=1400 audit(0.0:157): avc: granted { net_admin } for capability=12 scontext=u:r:cnss-daemon:s0 tcontext=u:r:cnss-daemon:s0 tclass=capability
06-30 14:07:56.149 651 651 W cnss-daemon: type=1400 audit(0.0:158): avc: granted { net_admin } for capability=12 scontext=u:r:cnss-daemon:s0 tcontext=u:r:cnss-daemon:s0 tclass=capability
06-30 14:07:56.153 1487 1487 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid=de:14:5c:9c:33:94 reason=3 locally_generated=1
06-30 14:07:56.154 1487 1487 W wpa_supplicant: nl80211: Was expecting local disconnect but got another disconnect event first
06-30 14:07:56.160 1110 1455 D WifiStateMachine: WifiStateMachine: Leaving Connected state
06-30 14:07:56.164 1110 1456 D DhcpClient: doQuit
06-30 14:07:56.170 1110 1456 D ApfFilter: (wlan0): shutting down
06-30 14:07:56.171 1110 1455 D WifiNative-HAL: stopRssiMonitoring, cmdId 0
06-30 14:07:56.174 1110 19709 D DhcpClient: Receive thread stopped
06-30 14:07:56.177 1110 1459 D ConnectivityService: NetworkAgentInfo [WIFI () - 110] EVENT_NETWORK_INFO_CHANGED, going from CONNECTED to DISCONNECTED
06-30 14:07:56.177 1110 1459 D ConnectivityService: NetworkAgentInfo [WIFI () - 110] got DISCONNECTED, was satisfying 8
06-30 14:07:56.177 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:07:56.189 639 1171 D CommandListener: Setting iface cfg
06-30 14:07:56.200 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:07:56.206 1110 19707 D DhcpClient: onQuitting
06-30 14:07:56.223 1682 1752 W QCNEJ : |CORE| network lost: 110
06-30 14:07:56.224 1682 1752 W QCNEJ : |CORE| onLost: unbind the process to WIFI
06-30 14:07:56.229 1487 1487 I wpa_supplicant: wlan0: CTRL-EVENT-REGDOM-CHANGE init=USER type=COUNTRY alpha2=US
06-30 14:07:56.238 639 1171 D CommandListener: Clearing all IP addresses on wlan0
06-30 14:07:56.244 1110 1455 D WifiCountryCode: Succeeded to set country code to: US
06-30 14:07:56.244 1110 1455 D WifiStateMachine: Start Disconnecting Watchdog 11
06-30 14:07:56.245 1110 1455 D WifiNative-HAL: stopRssiMonitoring, cmdId 0
06-30 14:07:56.256 1110 1455 I WifiConnectivityManager: scheduleWatchdogTimer
06-30 14:07:56.277 2037 2453 W Settings: Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
06-30 14:07:56.282 1110 1455 I WifiConnectivityManager: Set WiFi disabled
06-30 14:07:56.283 1110 1455 D WifiNetworkAgent: NetworkAgent: NetworkAgent channel lost
06-30 14:07:56.297 639 1171 V IdletimerController: runCmd(/system/bin/ip6tables -w -t raw -D idletimer_raw_PREROUTING -i wlan0 -j IDLETIMER --timeout 15 --label 1 --send_nl_msg 1) res_ipv4=0, res_ipv6=0
06-30 14:07:56.310 2037 2453 W Settings: Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
06-30 14:07:56.330 639 1171 V IdletimerController: runCmd(/system/bin/ip6tables -w -t mangle -D idletimer_mangle_POSTROUTING -o wlan0 -j IDLETIMER --timeout 15 --label 1 --send_nl_msg 1) res_ipv4=0, res_ipv6=0
06-30 14:07:56.332 1110 1459 D ConnectivityService: Sending DISCONNECTED broadcast for type 1 NetworkAgentInfo [WIFI () - 110] isDefaultNetwork=true
06-30 14:07:56.344 18824 18824 D MusicLifecycle: com.google.android.music.net.NetworkConnectivityMonitor$NetworkChangedReceiver generated event: Broadcast received with context com.google.android.music.ui.PhoneMusicApplication@e91968c and intent Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) }
06-30 14:07:56.349 2393 18279 W MdnsClient_Cast: Multicast lock held. Releasing. Subtypes:"233637DE"
06-30 14:07:56.359 18824 18824 I NetworkConnectivity: Network state changed: null
06-30 14:07:56.372 2393 18279 W MdnsClient: unicast receiver thread is already dead.
06-30 14:07:56.384 18824 18824 I NetworkPolicyMonitor: Download-ability status changed to (false) unmetered wifi/eth: false mobileOrMetered: false
06-30 14:07:56.389 18824 18824 I NetworkPolicyMonitor: Stream-ability status changed to (false) unmetered wifi/eth: false mobileOrMetered: false
06-30 14:07:56.408 2393 18279 I DeviceScanner: [MDNS] notifyDevicesOffline: []
06-30 14:07:56.422 2393 18279 E Publisher: ProcessDatabaseInternal start
06-30 14:07:56.424 2393 18279 I CastMediaRouteProvider: onDevicesPublished with 0 devices
06-30 14:07:56.438 2393 18279 I CastMediaRouteProvider: Published 0 routes
06-30 14:07:56.447 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:07:56.452 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:07:56.462 639 1171 E Netd : netlink response contains error (No such file or directory)
06-30 14:07:56.464 1110 1459 D NetworkNotificationManager: clearing notification tag=ConnectivityNotification:110 event=NO_INTERNET
06-30 14:07:56.490 2393 14149 W Herrevad: [660] rwh.b: Invalid mccmnc
06-30 14:07:56.495 2393 14149 W Herrevad: [660] rwh.b: Invalid mccmnc
06-30 14:07:56.525 18824 18935 W NetworkBandwidthMonitor: Unsuccessful attempt to get a Network Quality Client prediction (quality==null)
06-30 14:07:56.552 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:07:56.557 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:07:56.673 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:07:56.677 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:07:56.732 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:07:56.737 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:07:59.732 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:07:59.752 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:08:00.872 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:08:00.877 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:08:02.680 2164 2181 W GvrApi : GvrApi.shutdown() should be called to ensure resource cleanup
06-30 14:08:04.847 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:08:04.852 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()
06-30 14:08:21.718 1110 1670 E : E/int izat_xtra::XtraDataRequest::doDownloadXtraData(const string &, string &):177][XTRA2] DNS resolution on xtrapath3.izatcloud.net failed.
06-30 14:08:24.766 2037 19816 W ctxmgr : [NetworkStateProducer]No state change for network connection context
06-30 14:08:26.012 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl()
06-30 14:08:26.017 1930 1930 I WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl()