- Home /
C# Networking: UDP Packets dont arrive on Android
I try to get UDP Packets from a Server to the UDPClient on my Kindle Fire HDX with Code like this, which is executed in another thread:
//Valid IP and Port
Client = new UdpClient ();
Client.Client.ReceiveTimeout = TimeOut;
remoteIPEndPoint = new IPEndPoint(IPAddress.Parse(Server), Port);
//Sending works
Client.Send (sendPacket, sendPacket.Length, remoteIPEndPoint);
//Throws Exception
byte[] rcvPacket = Client.Receive (ref remoteIPEndPoint);
On Android the Client sends the message and the server receives it. But if the Server sends a message to the device it never arrives. I tested the same Code on another WindowsPC and it works. Sending a ping to the server does also not work, while pinging the device is working.
Using Unity 5 and a Kindle Fire HDX Tablet. Internet Access is set to Require and the Tablet is in a WirelessLAN.
Answer by XinJinXiang · Mar 26, 2015 at 02:34 PM
I think you should implement socket communication by using thread. I developed android-pc socket communication project a year ago by using Unity 4.33f. First time, I implement communication logic in update so I can`t receive any message from server. I prefer you check your communication logic. Here is main communication logic that I have implemented. I wish it helps your work.
//This function send packet according to the request
void SendPacket(byte[] msg,Request cmd){
switch (cmd) {
case Request.LogInRequest:
try{
//If socket exist,destroy it first.
if( GlobalInfo.NetworkActivity.currentSocket != null && GlobalInfo.NetworkActivity.currentSocket.Connected )
{
GlobalInfo.NetworkActivity.currentSocket.Shutdown( SocketShutdown.Both );
System.Threading.Thread.Sleep( 5 );
GlobalInfo.NetworkActivity.currentSocket.Close();
}
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(GlobalInfo.LoginUserInformation.serverIp),GlobalInfo.LoginUserInformation.serverPort);
GlobalInfo.NetworkActivity.currentSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
GlobalInfo.NetworkActivity.currentSocket.Blocking = false;
AsyncCallback onConnect = new AsyncCallback(OnConnect);
GlobalInfo.NetworkActivity.currentSocket.BeginConnect(endPoint,onConnect,GlobalInfo.NetworkActivity.currentSocket);
//Wait until connection established
connectDone.WaitOne();
}catch(SocketException se){
GlobalInfo.NetworkActivity.isConnected = false;
print ("Socket Exception:" + se.ToString());
}
break;
case Request.LogOutRequest:
GlobalInfo.NetworkActivity.isLoggedFlag = false;
GlobalInfo.NetworkActivity.receivedThreadExitFlag = true;
break;
default:
break;
}
if (GlobalInfo.NetworkActivity.isConnected) {
try{
AsyncCallback onSend = new AsyncCallback(OnSend);
GlobalInfo.NetworkActivity.currentSocket.BeginSend(msg,0,msg.Length,SocketFlags.None,onSend,0);
}catch(SocketException se){
print ("Socket Exception. Send Packet Failure." + se.ToString());
}
}else{
print ("Connection Problem. Send Packet Failure. Reconnect Please!");
GlobalInfo.NetworkActivity.currentSocket.Shutdown(SocketShutdown.Both);
GlobalInfo.NetworkActivity.currentSocket.Close();
}
}
//Receive Thread
void ReceiveThread(){
... ... ...
bool bFlag = true;
while(bFlag){
if((GlobalInfo.NetworkActivity.isConnected == false) || GlobalInfo.NetworkActivity.receivedThreadExitFlag){
bFlag = false;
print ("Connection Problem! Receive Thread Exit!");
}else{
print ("Thread Ready!");
try{
AsyncCallback receiveData = new AsyncCallback(OnReceiveData);
GlobalInfo.NetworkActivity.currentSocket.BeginReceive(m_buffer,0,m_buffer.Length,SocketFlags.None,receiveData,GlobalInfo.NetworkActivity.currentSocket);
}catch(SocketException se){
bFlag = false;
print ("Receive Thread Error. Socket Exception:" + se.ToString());
}
}
}
}
//Receive Function
public void OnReceiveData(IAsyncResult ar){
Socket rec_sock = (Socket)ar.AsyncState;
try{
int nBytesReceive = rec_sock.EndReceive(ar);
if(nBytesReceive >0){
byte[] receive = new byte[nBytesReceive];
for(int i = 0; i < nBytesReceive; i ++){
receive[i] = m_buffer[i];
}
//Check Packet Type
DecompilePacket(receive);
// This is important command. Must deep think...ReceiveThread();
}else{
print ("Connection Problem. You have been disconnected.");
GlobalInfo.NetworkActivity.receivedThreadExitFlag = true;
GlobalInfo.NetworkActivity.currentSocket.Shutdown(SocketShutdown.Both);
GlobalInfo.NetworkActivity.currentSocket.Close();
}
}catch(Exception e){
GlobalInfo.NetworkActivity.receivedThreadExitFlag = true;
print ("Receive Thread Exception:" + e.ToString());
}
}
//Send Function
void OnSend(IAsyncResult ar){
Socket rec_socket = (Socket)ar.AsyncState;
try{
rec_socket.EndSend(ar);
print ("Send Packet Successfully");
}catch(Exception se){
print("Send Packet Failure:" + se.ToString());
}
}
void SetPacket(Request cmd){
... .... ...
ModelSerializer mainMsgSerializer = new ModelSerializer ();
MemoryStream mainMsgMemoryStream = new MemoryStream ();
mainMsgSerializer.Serialize (mainMsgMemoryStream, qmdMessage);
//Do action according to the command
SendPacket(mainMsgMemoryStream.ToArray(),cmd);
}
Answer by $$anonymous$$ · Mar 31, 2015 at 12:51 PM
Update: After some hours wasting to this problem i found out that packets above 1472 Bytes are lost. Seems like there was a Problem with Packets, which are bigger than the MTU of the Ethernet Frame (1500 Bytes).
Even by limiting the packet size to 1472 bytes, I can't send UDP packets from an Android; but I can receive packets from a PC..
$$anonymous$$y code to limit package :
public void Send(byte[] buffer, int offset, int size)
{
if ($$anonymous$$axPacketSize > 0)
{
int nSend = size / $$anonymous$$axPacketSize;
int remain = size - nSend * $$anonymous$$axPacketSize;
int tempOff = offset;
// Sends the package, splitted.
for (int i = 0; i < nSend; i++)
{
this._Send(buffer, tempOff, $$anonymous$$axPacketSize);
tempOff += $$anonymous$$axPacketSize;
}
// Sends the remaining
this._Send(buffer, tempOff, remain);
}
else
{
this._Send(buffer, offset, size);
}
}
private void _Send(byte[] buffer, int offset, int size)
{
foreach ($$anonymous$$eyValuePair<string, IPEndPoint> remote in this.Remotes)
{
Debug.Log("send " + size + " bytes to " + remote.$$anonymous$$ey);
this.UDPSocket.SendTo(buffer, offset, size, SocketFlags.Partial, remote.Value);
}
}
Fixed: the "SocketFlags.Partial" must be changed to "SocketFlags.None".
Your answer
Follow this Question
Related Questions
Android build is not receiving UDP broadcasts 4 Answers
Best way to create a UDP network for Android 0 Answers
How to access a PHP script on XAMPP with the use of Android device? 0 Answers
TCP data sending with Android 3 Answers
UDP Packet and EC2 0 Answers