java.net.BindException:EADDRINUSE(地址已在使用) [英] java.net.BindException: EADDRINUSE (Address already in use)
问题描述
我试图通过WIFI,直接在Android手机连接和传输数据。我已经基本上在我的P2PConnectionManager.java文件做的是 -
I'm trying to connect and transfer data through Wifi-Direct on Android phones. What I've basically done in my P2PConnectionManager.java file is -
- 创建通过P2pManager 来同行的连接
- 称为类ServerHandshake如果我集团所有者
- 称为类ClientHandshake如果我不是GroupOwner
- Created a connection to the peer through the P2pManager
- Called the class ServerHandshake if I am the Group Owner
- Called the class ClientHandshake if I am not the GroupOwner
在这两类我已经交换的IP地址和电话的MAC地址(这个我已经做了,使与多个手机通讯)。我已经使用数据报套接字无处不在,因为这是需要什么,现在的我所试图做的。
in these two classes I have exchanged the IP addresses and MAC addresses of the phones (this I've done to enable communication with multiple phones). I have used Datagram Sockets everywhere as that is what is required right now for what I am trying to do.
在P2PSend.java,一旦我选择文件,我试图超过一个DatagramSocket把它作为很好,但它给了我一个绑定失败:EADDRINUSE(地址已在使用)异常
In P2PSend.java, once I select the file, I have tried to send it over a DatagramSocket as well, but it is giving me a bind failed: EADDRINUSE (Address already in use) exception.
我使用两个连接不同的端口,甚至包括socket.setReuseAddress()
I am using different ports for both the connections, and even included socket.setReuseAddress()
可有人请指出我要去的地方错了吗?我在code中的混乱表示歉意。
Can someone please point out where I am going wrong? I apologize for the mess in the code.
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和端口
P2PSend.java: Note: I have used IntentService here, just to get the filepath, destination IP and port
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");
}
任何建议,我要去哪里错了吗?
Any suggestions as to where I'm going wrong?
感谢你了!
推荐答案
创建插座是这样的:
clientSocket = new DatagramSocket();
clientSocket.setReuseAddress(true);
clientSocket.bind(new InetSocketAddress(peerPort));
如果您想发送广播,也可以考虑结合之前加入这一行:
If you want to send Broadcast, also consider adding this line before binding it:
clientSocket.setBroadcast(true);
这篇关于java.net.BindException:EADDRINUSE(地址已在使用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!