java.net.BindException:EADDRINUSE(地址已在使用中)

时间:2014-07-22 03:49:56

标签: java android sockets

我正在尝试通过Android手机上的Wifi-Direct连接和传输数据。我在P2PConnectionManager.java文件中基本上完成的是 -

  1. 通过P2pManager
  2. 创建与对等方的连接
  3. 如果我是群组所有者,则称为ServerHandshake类
  4. 如果我不是GroupOwner,则称为ClientHandshake类
  5. 在这两个类中我交换了手机的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");
    
        } 
    

    关于我哪里出错的任何建议?

    非常感谢你!

1 个答案:

答案 0 :(得分:0)

以这种方式创建套接字:

clientSocket = new DatagramSocket();
clientSocket.setReuseAddress(true);
clientSocket.bind(new InetSocketAddress(peerPort));

如果您想发送广播,还可以考虑在绑定之前添加此行:

clientSocket.setBroadcast(true);