簡體   English   中英

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

[英]java.net.BindException: EADDRINUSE (Address already in use)

我正在嘗試通過Android手機上的Wifi-Direct連接和傳輸數據。 我在P2PConnectionManager.java文件中所做的基本上是-

  1. 通過P2pManager建立到對等方的連接
  2. 如果我是組所有者,則稱為ServerHandshake類
  3. 如果我不是GroupOwner,則將其稱為ClientHandshake類

在這兩類中,我交換了電話的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");

    } 

關於我要去哪里的任何建議?

非常感謝!

通過以下方式創建套接字:

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

如果要發送廣播,請在綁定它之前考慮添加此行:

clientSocket.setBroadcast(true);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM