2014-10-04 54 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

相关问题