我正在尝试通过Android手机上的Wifi-Direct连接和传输数据。我在P2PConnectionManager.java文件中基本上完成的是 -
在这两个类中我交换了手机的IP地址和MAC地址(这是为了实现与多部手机的通信)。我已经在各处使用过数据报套接字,因为这正是我现在要做的事情。
在P2PSend.java中,一旦我选择了文件,我也尝试通过DatagramSocket发送它,但是它给了我一个绑定失败:EADDRINUSE(地址已经在使用中)异常。
我为这两个连接使用不同的端口,甚至包括socket.setReuseAddress()
有人可以指出我哪里出错吗?我为代码中的混乱道歉。
P2PConnectionManager.java:
public void onConnectionInfoAvailable(WifiP2pInfo info) {
//here check whether we're the group owner, then create server socket if so
if(info.isGroupOwner){
appendToConsole("CMGR: Setting up server handshake on " + info.groupOwnerAddress.getHostAddress() + ":5555");
//setup the server handshake with the group's IP, port, the device's mac, and the port for the conenction to communicate on
ServerHandshake sh = new ServerHandshake();
sh.setup(myMAC, info.groupOwnerAddress.getHostAddress(),5555,childportstart);
childportstart += 2;
sh.execute();
}else{
//give server a second to setup the server socket
try{
Thread.sleep(1000);
}catch (Exception e){
System.out.println(e.toString());
}
String myIP = "";
try {
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while(en.hasMoreElements()){
NetworkInterface ni = en.nextElement();
Enumeration<InetAddress> en2 = ni.getInetAddresses();
while(en2.hasMoreElements()){
InetAddress inet = en2.nextElement();
if(!inet.isLoopbackAddress() && inet instanceof Inet4Address){
myIP = inet.getHostAddress();
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
appendToConsole("CMGR: Setting up client handshake from " + myIP + ":5555");
//setup the client handshake to connect to the server and trasfer the device's MAC, get port for connection's communication
ClientHandshake ch = new ClientHandshake();
ch.setup(info.groupOwnerAddress.getHostAddress(),5555,myMAC,myIP);
ch.execute();
}
}
ClientHandshake类:
public class ClientHandshake extends AsyncTask<Void, Void, String> {
String peerIP;
String peerMAC;
int peerPort;
int childport;
byte[] buffer;
byte[] buffer2;
DatagramSocket clientSocket;
OutputStream outs;
InputStream ins;
String myMAC;
String myIP;
public void setup(String peerIP, int peerPort, String myMAC, String myIP ) {
this.peerIP = peerIP;
this.peerPort = peerPort;
this.myMAC = myMAC;
this.myIP = myIP;
}
public String doInBackground(Void...params) {
try{
clientSocket = new DatagramSocket(peerPort);
clientSocket.setReuseAddress(true);
System.out.println("Peerport: " + peerPort);
InetAddress IPAddress = InetAddress.getByName(peerIP);
System.out.println("CH: PEERIP ADDRESS - " + IPAddress);
int len = myIP.length();
byte[] sendMyMac = new byte[17];
byte[] sendMyIPlen = new byte[2];
byte[] sendMyIP = new byte[len];
byte[] receivePeerMAC = new byte[17];
byte[] receivePort = new byte[4];
//write our MAC address
sendMyMac = myMAC.getBytes();
System.out.println("myMAC - " + myMAC);
DatagramPacket sendPacket1 = new DatagramPacket(sendMyMac, sendMyMac.length, IPAddress, peerPort);
clientSocket.send(sendPacket1);
System.out.println("sendMyMAC done -");
//write our IP add len
String string = String.valueOf(myIP.length());
sendMyIPlen = string.getBytes();
System.out.println("myIPlen - " + myIP.length());
DatagramPacket sendPacket2 = new DatagramPacket(sendMyIPlen, sendMyIPlen.length, IPAddress, peerPort);
clientSocket.send(sendPacket2);
System.out.println("sendMyIPlen done -");
//write our IP add
sendMyIP = myIP.getBytes();
System.out.println("myIP - " + myIP);
DatagramPacket sendPacket3 = new DatagramPacket(sendMyIP, sendMyIP.length, IPAddress, peerPort);
clientSocket.send(sendPacket3);
System.out.println("SendMyIP done -");
//read peer's MAC address
DatagramPacket receivePeerMac = new DatagramPacket(receivePeerMAC, receivePeerMAC.length);
clientSocket.receive(receivePeerMac);
String peerMAC = new String(receivePeerMac.getData());
System.out.println("FROM SERVER:" + peerMAC);
//read the port
DatagramPacket port = new DatagramPacket(receivePort, receivePort.length);
clientSocket.receive(port);
String cport = new String (port.getData());
int childport = Integer.parseInt(cport);
clientSocket.close();
return peerMAC;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(String peerMAC){
createNewP2PConnection(myMAC,myIP,peerMAC,peerIP,childport,0);
}
}
ServerHandshake类:
public class ServerHandshake extends AsyncTask<Void, Void, String> {
int portno;
int childport;
int peerIPlen;
byte[] buffer;
byte[] buffer2;
Socket s;
DatagramSocket serverSocket;
InputStream ins;
OutputStream outs;
String myMAC;
String myIP;
String ipaddr;
String peerMAC;
String peerIP;
int myPort;
public void setup(String myMAC, String myIP, int myPort, int childport) {
this.myIP = myIP;
this.myMAC = myMAC;
this.myPort = myPort;
this.childport = childport;
}
public String doInBackground(Void...params) {
System.out.println("Checking SH");
System.out.println("CP : "+childport);
try{
serverSocket = new DatagramSocket(5555);
serverSocket.setReuseAddress(true);
//serverSocket.setSoTimeout(5000);
byte[] receivePeerMAC = new byte[17];
byte[] receivePeerIPlen = new byte[2];
byte[] sendMyMac = new byte[17];
byte[] sendMyPort = new byte[4];
try {
Thread.sleep(5000);
}catch(Exception e) {
e.printStackTrace();
}
//read Peer Mac
DatagramPacket PeerMac = new DatagramPacket(receivePeerMAC, receivePeerMAC.length);
serverSocket.receive(PeerMac);
String peerMAC = new String(PeerMac.getData());
System.out.println("RECEIVEDpeerMAC: " + peerMAC);
InetAddress IPAddress = PeerMac.getAddress();
int port = PeerMac.getPort();
//read peer IP's len
DatagramPacket IPlen = new DatagramPacket(receivePeerIPlen, receivePeerIPlen.length);
serverSocket.receive(IPlen);
String PeerIPlen = new String(IPlen.getData());
int peerIPlen = Integer.parseInt(PeerIPlen);
System.out.println("RECEIVEDpeerIPlenstring: " + PeerIPlen + " .... int: " + peerIPlen + "ANY DIFFERENCE??");
//read peer IP
byte [] receivePeerIP = new byte [peerIPlen];
DatagramPacket IP = new DatagramPacket(receivePeerIP, receivePeerIP.length);
serverSocket.receive(IP);
String peerIP = new String(IP.getData());
System.out.println("RECEIVEDpeerIP: " + peerIP);
//Write our local MAC
sendMyMac = myMAC.getBytes();
System.out.println("myMAC - " + myMAC);
DatagramPacket sendPacket1 = new DatagramPacket(sendMyMac, sendMyMac.length, IPAddress, port);
serverSocket.send(sendPacket1);
System.out.println("sendMyMAC done -");
//Write the port to talk on
String string = String.valueOf(childport);
sendMyPort = string.getBytes();
DatagramPacket sendPacket2 = new DatagramPacket(sendMyPort, sendMyPort.length, IPAddress, port);
serverSocket.send(sendPacket2);
System.out.println("Port: " + childport);
serverSocket.close();
return (peerIP);
}catch(Exception e){
e.printStackTrace();
}
return (null);
}
public void onPostExecute(String peerIP){ //changed from (String peerMAC)
createNewP2PConnection(myMAC,myIP,peerMAC,peerIP,childport,1);
}
}
P2PSend.java: 注意:我在这里使用过IntentService,只是为了获取文件路径,目标IP和端口
public class P2PSend extends IntentService {
private static final int SOCKET_TIMEOUT = 15000;
public static final String ACTION_SEND_FILE = "com.p2pwifidirect.connectionmanager.SEND_FILE";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_DESTINATION = "go_host";
public static final String EXTRAS_DESTINATION_PORT = "go_port";
public static final String EXTRAS_MY_IP = "my_ip";
public P2PSend() {
super("P2PSend");
System.out.println("P2PSend.java started IntentService");
}
protected void onHandleIntent(Intent intent) {
System.out.println("P2PSend.java started onHandleIntent");
Context context = getApplicationContext();
System.out.println("Intent: " + intent);
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_DESTINATION); //this is the IP address of the receiver
String myIP = intent.getExtras().getString(EXTRAS_MY_IP); //my IP address
System.out.println("P2PSend:Host Address: " + host);
//int port = intent.getExtras().getInt(EXTRAS_DESTINATION_PORT);
int port = 6000;
System.out.println("P2PSend:Port: " + port);
System.out.println("P2PSend:fileUri: " + fileUri);
try {
DatagramSocket socket = new DatagramSocket(port);
System.out.println("Opening client socket - ");
//socket.bind(new InetSocketAddress(myIP, port));
InetAddress hostAddress = InetAddress.getByName(host);
socket.connect(new InetSocketAddress(hostAddress, port));
//socket.setSoTimeout(SOCKET_TIMEOUT); //is it needed???
System.out.println("Client socket - " + socket.isConnected());
ContentResolver cr = context.getContentResolver();
InputStream is = null;
is = cr.openInputStream(Uri.parse(fileUri));
byte buf[] = new byte[1024];
int len = 0;
while ((len = is.read(buf)) != -1) {
DatagramPacket packet = new DatagramPacket(buf,buf.length, hostAddress, port);
//System.out.println("Client socket - " + socket.isConnected());
socket.send(packet);
System.out.println("Writing data: " + packet);
System.out.println("Writing data now...");
}
is.close();
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (Exception e) {
// Give up
e.printStackTrace();
}
}
}
} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println("Client: Data written");
}
关于我哪里出错的任何建议?
非常感谢你!
答案 0 :(得分:0)
以这种方式创建套接字:
clientSocket = new DatagramSocket();
clientSocket.setReuseAddress(true);
clientSocket.bind(new InetSocketAddress(peerPort));
如果您想发送广播,还可以考虑在绑定之前添加此行:
clientSocket.setBroadcast(true);