2014-10-04 29 views
1

我正在開發一個android應用程序,它必須在兩部手機之間進行實時通信。有一個客戶端和服務器在兩個電話上運行,我有一箇中央服務器,每個服務器的公共IP和端口都被交換。兩個電話都在監聽中央服務器的通知。連接拒絕錯誤,同時在android中通過使用打孔的TCP套接字進行通信

假設兩部手機都通過中央服務器接收對方的公共IP和端口,然後在每部手機上啓動客戶端,然後再啓動服務器(這是因爲它以其他順序失敗,因爲我在做打孔我使用相同的端口進行收聽和發送)。

以下是我如何啓動服務器和客戶端

socket=new Socket(); 
try { 
    socket.setReuseAddress(true); 
} catch (SocketException e) { 
    e.printStackTrace(); 
} 
try { 
    socket.bind(new InetSocketAddress(<Port of this phone>)); 
} catch (IOException e) { 
e.printStackTrace(); 
} 
ClientThread clientThread=new ClientThread(<IP of the other phone>,<Port of the other phone>,socket); 
clientThread.execute(); 

Thread serverThread = new Thread(new ServerThread(<IP of this phone>,<Port of this phone>)); 
serverThread.start(); 

這是我的服務器

public class ServerThread implements Runnable { 

private String serverIP; 
private int serverPort; 
private ServerSocket serverSocket; 

public ServerThread(String serverIP,int serverPort){ 
    this.serverIP=serverIP; 
    this.serverPort=serverPort; 
} 


public void run() { 
    try { 
      serverSocket = new ServerSocket(); 
      serverSocket.setReuseAddress(true); 
      serverSocket.bind(new InetSocketAddress(serverPort)); 
      while (true) { 
       // listen for incoming clients 
       Socket client = serverSocket.accept(); 
       Log.d("serverstatus","Connected :)"); 
       if(connected) 
       //then pass messages 
       } 
     } 
     catch (Exception e) { 
     Log.d("serverstatus","Error"); 
     e.printStackTrace(); 
     } 
    } 

}

代碼這是我的客戶端代碼

public class ClientThread extends AsyncTask<String,String,String>{ 
private String serverIP; 
private int serverPort; 
private Socket socket; 

public ClientThread(String serverip,int serverport,Socket mySocket) 
{ 
    serverIP=serverip; 
    serverPort=serverport; 
    socket=mySocket; 
} 

@Override 
protected String doInBackground(String... arg0) { 
    try { 
     while(true) 
     { 
      socket.connect(new InetSocketAddress(serverIP, serverPort)); 
      if(socket.isConnected()) 
      { 
      //pass messages 
      } 
     } 
     } 
     catch (Exception e) { 
     Log.d("clientstatus","Error"); 
     e.printStackTrace(); 
     //try again 
     ClientThread clientThread=new ClientThread(serverIP,serverPort,socket); 
     clientThread.execute(); 
     } 
    } 
}  

預期的是,phone1到phone2的第一次連接嘗試失敗後(因爲phone2的端口尚未打開),phone1的端口變爲開放(因爲對phone2的請求),然後當電話2嘗試與phone1通信時成功是因爲phone1的端口現在是開放的,phone2也是如此(因爲phone2對phone1的請求)。

它仍然顯示連接拒絕每次我嘗試連接,然後'套接字關閉'異常被拋出。

我在做什麼錯,有人可以幫助我這個。

+0

'拒絕連接'通常不表示防火牆問題,'套接字關閉'僅表示您自己關閉套接字,然後繼續使用它:您的部分出現編程錯誤。 – EJP 2014-10-04 10:30:26

+0

@ejp在連接完成之前,我還沒有關閉代碼中的任何地方的套接字,並且套接字關閉錯誤將在下一次嘗試中建立連接。 (第一次嘗試顯示連接被拒絕) – 2014-10-04 10:38:56

回答

0

我試過類似的OSx和iOS。我在服務器端有一個非常簡單的C代碼來監聽傳入的連接,這是捕獲手機的IP和端口號172.39.33.23:44392(基本上,即使你的手機連接到無線路由器,我能夠從另一個設備發送數據到此端口)。但不是tcp,你應該嘗試使用UDP將數據發送到捕獲的帶有數據報(Java)的IP和端口。

public void sendUdpData() 
    { 

     String phone1Ip = "172.39.33.23"; 
     int phone1Port = 44392; 

     try 
     { 
      String commandString = "Send this data"; 
      byte[] commnadByte = commandString.getBytes(); 
      DatagramPacket datagramPacket = new DatagramPacket(commnadByte, commnadByte.length,InetAddress.getByName(phone1Ip),phone1Port); 
      DatagramSocket datagramSocket= new DatagramSocket(phone1Port); 
      datagramSocket.send(datagramPacket); 
      datagramSocket.close(); 
     } 
     catch (UnknownHostException e1) 
     { 

     } 
     catch (SocketException e1) 
     { 

     } 
     catch (IOException e1) 
     { 

     } 
    } 
+0

感謝您的答覆,但使用UDP發送,並不能保證數據包到達另一端的權利?爲什麼使用TCP不可能?我懷疑即使我使用了打孔,防火牆在服務器端受到限制。 – 2014-10-04 10:23:56

+0

我知道UDP並不保證數據包會被髮送,但重要的是,這就是爲什麼它被稱爲UDP打孔。與TCP相比,UDP更快,所以訣竅是您可能想使用不同的通信來保證傳輸。 (類似郵件獲取)。 UDP用於遊戲,而Skype則使用UDP。我想你的基本結構應該像電話1連接到你的服務器獲取IP和端口,然後電話2連接和服務器獲取它是IP和端口,然後你傳遞這些信息後發送,然後電話2可以發送數據到手機1與udp。 – KeranMarinov 2014-10-04 11:28:20

相關問題