我正在开发一个 android 应用程序,它必须在两部手机之间进行实时通信。两部手机上都运行着一个客户端和服务器,我有一个中央服务器,每个服务器的公共(public) IP 和端口都与之交换。两部手机都在监听中央服务器以获取通知。
假设两部手机都通过中央服务器接收彼此的公共(public) ip 和端口,然后在每部手机上我启动客户端,然后启动服务器(这是因为,它以其他顺序失败,因为我正在打洞punching 我使用相同的端口进行监听和发送)。
下面是我启动服务端和客户端的方式
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 的请求)然后当 phone 2 尝试与 phone1 通信时,它成功了,因为 phone1 的端口现在打开了,phone2 的端口也打开了(因为 phone2 对 phone1 的请求)。
每次我尝试连接时它仍然显示连接被拒绝,然后抛出“套接字关闭”异常。
我做错了什么,谁能帮我解决这个问题。
最佳答案
我在 OSx 和 iOS 上尝试过类似的方法。我在服务器端有一个非常简单的 C 代码监听传入连接,它捕获手机的 ip 和端口号,比如 172.39.33.23:44392(基本上即使你的手机连接到 wifi 路由器,我也能够从另一台设备向此端口发送数据)。但是,您应该尝试使用 UDP 将数据发送到使用数据报 (Java) 捕获的 ip 和端口,而不是 tcp。
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)
{
}
}
关于java - 使用打洞通过 TCP 套接字在 android 中通信时出现连接拒绝错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26191346/