Android- UDP connection between phones
I am in a networking course and was assigned a project that we can complete in any language or environment. Being the Android lover that I am I naturally wanted to do this on my phone. The part I am having an issue with should be simple and I am starting to think I can not establish a connection using UDP between the phones. What I am trying to do is use one phone as a server and one as a client. The client sends a message to the server and the server changes the string to upper case. (this is not the project, but a good step to see if it is working.) Does anyone know why the server and client would not be connecting or if it is even possible?
This is the server, below is the client, main launch screen, and main.xml
package com.csc.networking;
import java.net.*;
import android.util.Log;
public class UDPServer
{
public void main() throws Exception
{
Log.d("s","1");
DatagramSocket serverSocket = new DatagramSocket(6699);//create a datagram socket at the specified port number
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
Log.d("s","2");
while(true)
{
Log.d("s","3");
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
//To Do: construct a DatagramPacket object called receivePacket. Use the constructor of the class DatagramPacket
//that takes two parameters: 1. the array of bytes (receiveData) and 2. the length of that array.
Log.d("s","3.5");
//To Do: use the method receive on the DatagramSocket object to receive the packet sent from the client.
//the method receive takes one parameter (the DatagramPacket object constructed in the above step).
serverSocket.receive(receivePacket);
Log.d("s","again");
Log.d("s","3.75");
String sentence = new String(receivePacket.getData());//extract the String from the array of bytes.
Log.d("s",sentence);
Log.d("s","4");
InetAddress IPAddress = receivePacket.getAddress();//extract the IP address of the client
int port = receivePacket.getPort();//extract the port number from the packet
String capitalizedSentence = sentence.toUpperCase();//change the sentence received by the server
sendData = capitalizedSentence.getBytes();//convert it to an array of bytes
Log.d("s","5");
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
//To Do: construct a DatagramPacket object called sendPacket. Use the constructor of the class DatagramPacket
//that takes 4 parameters: 1. the array of bytes to be sent. 2. the length of that array of bytes.
//3. the IP address of the client (use the object IPAddress) and 4. the port number of the process running in
//the client.
//To Do: send the packet to the client using the method send on the DatagramSocket object. The metho send
//takes one parameter which is the packet constructed in the above step.
Log.d("s","5.5");
serverSocket.send(sendPacket );
Log.d("s","6");
}
}
}
package com.csc.networking;
import java.io.*;
import java.net.*;
import android.util.Log;
import android.widget.*;
public class UDPClient {
public void main(String string) throws Exception
{
Log.d("help", "1");
//EditText connectAddress = (EditText)findViewById(R.id.connectAddress);
Log.d("help", "2");
String hostIP = "10.60.5.79"; //connectAddress.getText().toString();
Log.d("help", "3");
String coded = string;
Log.d("help", "4");
DatagramSocket clientSocket = new DatagramSocket();//this line creates a datagram socket, this does not
//create a TCP connection with the server, note how we do not have server and process info as parameters to
//the constructor
Log.d("help", "5");
InetAddress IPAddress = InetAddress.getByName(hostIP); //this line invokes DNS to lookup the IP address
//of the hostname. If IP address is provided, it stores it in the object IPAddress.
Log.d("help", "6");
byte[] sendData = new byte[1024]; //array of bytes to be sent to server
Log.d("help", "7");
byte[] receiveData = new byte[1024]; //array of bytes that client will receive from server
Log.d("help", "8");
sendData = coded.getBytes(); //this converts sentence to an array of bytes and stores it in sendData.
Log.d("help", "9");
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,6699);
//To DO: construct a DatagramPacket object called sendPacket. The constructor of the DatagramPacket class
//takes the following parameters: 1. the array of bytes to be sent. 2. the length of the array of bytes.
//3. the IPAddress of the destination (use the object IPAddress) and 4. the port number of the process running
//at the destination.
Log.d("help", "10");
clientSocket.send(sendPacket);
//To DO: call the method send on the DatagramSocket object to send the datagram packet. The method send takes
//the DatagramPacket object as a prameter and sends it through the socket.
Log.d("help", "11");
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
//To Do: construct a new DatagramPacket object called recievePacket. This is the packet that the client will
//receive from the destination. Use the constructor that takes two parameters: 1. an array of bytes (receiveData) and
//2. the length of that array.
Log.d("help", "12");
clientSocket.receive(receivePacket);
//To Do: use the method receive on the DatagramSocket object to receive the datagram packet from the server.
//The method receive takes a parameter which is the DatagramPacket constructed in the above step.
Log.d("help", "13");
String modifiedSentence = new String(receivePacket.getData());//this converts an array of bytes to a string.
Log.d("help", "14");
TextView decoded = (TextView)findViewById(R.id.decoded);
Log.d("help", "15");
decoded.setText(modifiedSentence);
Log.d("help", "16");
clientSocket.close();//this closes the connection.
Log.d("help", "17");
}
private EditText findViewById(int connectaddress) {
// TODO Auto-generated method stub
return null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:baselineAligned="true" android:orientation="vertical"
android:layout_width="wrap_content" android:layout_height="fill_parent">
<TextView android:text="@string/Title" android:id="@+id/Title"
android:layout_width="fill_parent" android:gravity="center"
android:textSize="24px" android:layout_height="wrap_content" />
<EditText android:id="@+id/editText1" android:layout_below="@+id/Title"
android:layout_alignLeft="@+id/Title" android:layout_alignRight="@+id/Title"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:scrollbarAlwaysDrawVerticalTrack="true" android:scrollbars="vertical" android:singleLine="true" androi开发者_如何学运维d:hint="@string/Hint"/>
<RelativeLayout android:layout_width="wrap_content"
android:layout_below="@+id/editText1" android:id="@+id/relativeLayout1"
android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText1"
android:layout_alignRight="@+id/editText1">
<Button android:layout_width="wrap_content"
android:layout_below="@+id/startServer" android:layout_height="wrap_content"
android:layout_alignLeft="@+id/startServer"
android:layout_alignRight="@+id/startServer" android:id="@+id/Send"
android:text="@string/Send" />
<EditText android:layout_width="wrap_content" android:layout_below="@+id/Send" android:layout_height="wrap_content" android:layout_alignLeft="@+id/Send" android:layout_alignRight="@+id/Send" android:id="@+id/connectAddress" android:hint="Enter Ip Address Here"></EditText>
<TextView android:text="Decoded" android:layout_width="wrap_content" android:layout_below="@+id/connectAddress" android:id="@+id/decoded" android:layout_height="wrap_content" android:layout_alignLeft="@+id/connectAddress" android:layout_alignRight="@+id/connectAddress"></TextView>
<Button android:layout_width="fill_parent" android:id="@+id/startServer" android:text="@string/Start " android:layout_height="wrap_content" android:layout_alignParentRight="true"></Button>
</RelativeLayout>
</RelativeLayout>
package com.csc.networking;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class launchScreen extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button SendButton = (Button)findViewById(R.id.Send);
SendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
Log.d("click", "1");
EditText codedMessage = (EditText)findViewById(R.id.editText1);
UDPClient client = new UDPClient();
String msg = codedMessage.getText().toString();
Log.d("click", msg);
Log.d("click", "2");
client.main(msg);
Log.d("click", "3");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Button ServerButton = (Button)findViewById(R.id.startServer);
ServerButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
UDPServer server = new UDPServer();
server.main();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
http://systembash.com/content/a-simple-java-udp-server-and-udp-client/
this should be what you are looking for! Best regards
First thing is that you are trying to do network stuff on UI thread. In newer Android it will cause Exceptions, and user experience is very bad. When server or client waits in method:
socket.receive()
Better idea is to put those things in threads or AsyncTasks. This might be helpful networking networking in android
According to your issue, I can suggest sending this packet several times. UDP does not guarantee packet delivery, and sending one and only one packet is pretty risky.
Put your socket.send()
method in loop and send lets say 10 times the same packet.
You can also try sending it to your computer IP address, and check with software like Wireshark if it is received.
Last but not least, in your case the better option would be TCP client and server, where packet delivery is guaranteed. UDP is best in streaming media etc. where retransmissions are not useful at all.
If you're using 3G connectivity it is possible that inbound firewall is blocking your (incoming) connections. See this
My suggestion is to start from a wireless local network, so that IPs will be static/wellknown and then move to internet connections.
精彩评论