Java Socket 无法使用我的 IP 地址

问题描述 投票:0回答:0

我正在尝试在 Android Studio 中构建一个 P2P 聊天应用程序。为了实现这一目标,我使用两个不同的项目:一个运行服务器本身并充当第一个客户端,另一个项目作为新客户端运行。考虑到这一点,我一直在尝试连接我的手机和 A.S.模拟器在同一台服务器上。问题是,每次我尝试运行我的代码时,我都会收到一条警告:(使用我的 IP 地址 (ipv4)):

java.net.BindException: bind failed: EADDRNOTAVAIL (Cannot assign requested address)

此警告出现在服务器应用程序中:


    public class MainActivity extends AppCompatActivity {
    private static final int SERVER_PORT = 8080;
    private static final String SERVER_IP = "0.0.0.0";

    private List<Socket> clients = new ArrayList<>();
    private ServerSocket serverSocket;

    private TextView messageDisplay;
    private EditText messageInput;
    private Button sendButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        messageDisplay = findViewById(R.id.message_display);
        messageInput = findViewById(R.id.message_input);
        sendButton = findViewById(R.id.send_button);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToAllClients();
                System.out.println(serverSocket.getLocalPort());
                System.out.println(serverSocket.getLocalSocketAddress());
            }
        });

        startServer();
    }

    private void startServer() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket();
                    serverSocket.bind(new InetSocketAddress(SERVER_IP, SERVER_PORT));
                    System.out.println("Servidor criado com sucesso");
                    while (true) {
                        Socket clientSocket = serverSocket.accept();
                        Toast.makeText(MainActivity.this, "Cliente STARTADO",    Toast.LENGTH_SHORT).show();
                        clients.add(clientSocket);

                        listenToClient(clientSocket);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void listenToClient(final Socket clientSocket) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                    String message;
                    Toast.makeText(MainActivity.this, "TÁ OUVINDO", Toast.LENGTH_SHORT).show();
                    while ((message = reader.readLine()) != null) {
                        displayMessage("Client: " + message);
                    }

                } catch (IOException e) {
                    Toast.makeText(MainActivity.this, "NÃO TA OUVINDO", Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void sendMessageToAllClients() {
        final String message = messageInput.getText().toString();
        if (!message.isEmpty()) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (Socket client : clients) {
                        try {
                            PrintWriter writer = new PrintWriter(client.getOutputStream(), true);
                            writer.println(message);
                            Toast.makeText(MainActivity.this, "TÁ MANDANDO", Toast.LENGTH_SHORT).show();
                        } catch (IOException e) {
                            Toast.makeText(MainActivity.this, "NÃO TÁ MANDANDO", Toast.LENGTH_SHORT).show();
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

            messageInput.setText("");
            displayMessage("Me: " + message);
        }
    }

    private void displayMessage(final String message) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //Toast.makeText(MainActivity.this, "TÁ MOSTRANDO", Toast.LENGTH_SHORT).show();
                messageDisplay.append("\n" + message);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (serverSocket != null) {
                serverSocket.close();
            }
            for (Socket client : clients) {
                client.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}```

When I tried to use localhost (127.0.0.1) or 0.0.0.0 (which I don't actually understand what is), I get this warning, now at the client app logcat: 

java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 8080) from /:: (port 48262): connect failed: ECONNREFUSED (Connection refused)

Here's the client-side code: ```

    package com.example.desafio6_client;

    import androidx.appcompat.app.AppCompatActivity;

    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;

    public class MainActivity extends AppCompatActivity {
    private static final int SERVER_PORT = 8080;
    private static final String SERVER_IP = "0.0.0.0";

    private TextView messageDisplay;
    private EditText messageInput;
    private Button sendButton;
    private Socket clientSocket;
    private PrintWriter writer;
    private BufferedReader reader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        messageDisplay = findViewById(R.id.message_display);
        messageInput = findViewById(R.id.message_input);
        sendButton = findViewById(R.id.send_button);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToServer();
            }
        });

        connectToServer();
    }

    private void connectToServer() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    clientSocket = new Socket(SERVER_IP, SERVER_PORT);

                    Toast.makeText(MainActivity.this, "CONNECTED", Toast.LENGTH_SHORT).show();
                    if (clientSocket.isConnected()) {
                        writer = new PrintWriter(clientSocket.getOutputStream(), true);
                        reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                        if(writer == null){
                            Toast.makeText(MainActivity.this, "WRITER IS NULL", Toast.LENGTH_SHORT).show();
                        }
                        if(reader == null){
                            Toast.makeText(MainActivity.this, "READER IS NULL", Toast.LENGTH_SHORT).show();
                        }
                        listenToServer();
                    } else {
                        // Handle the case when the socket connection is not established
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "Connection failed. Please check server status.", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("CRASHO");
                    // Handle any other exceptions that might occur during the socket connection
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "b " + e.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        }).start();
    }

    private void listenToServer() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String message;
                    while ((message = reader.readLine()) != null) {
                        displayMessage("Server: " + message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void sendMessageToServer() {
        final String message = messageInput.getText().toString();
        if (!message.isEmpty()) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (writer != null) {
                        writer.println(message);
                    } else {
                        // Handle the case when the writer is null
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "Connection to server is not established.", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                }
            }).start();

            messageInput.setText("");
            displayMessage("Me: " + message);
        }
    }

    private void displayMessage(final String message) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                messageDisplay.append("\n" + message);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (clientSocket != null) {
                clientSocket.close();
            }
            if (writer != null) {
                writer.close();
            }
            if (reader != null) {
                reader.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} ```
     

I tried disabling my firewall, using an IP finder in my browser (because my cmd-ipconfig ipv4 is different compared to the one the site tells me), tried binding the server socket to a random IP, but nothings seems to work. I thought it was an AndroidManifest,xml missing statement, but it also changed nothing. 

Client-side xml: 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <application
        android:enableOnBackInvokedCallback="true"
        android:networkSecurityConfig="@xml/network_security_config"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Desafio6client"
        tools:targetApi="tiramisu">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Server-side xml: 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <application
        android:networkSecurityConfig="@xml/network_security_config"
        android:enableOnBackInvokedCallback="true"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Desafio6server"
        tools:targetApi="tiramisu">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config xmlns:tools="http://schemas.android.com/tools">
    <base-config cleartextTrafficPermitted="true"
        tools:ignore="InsecureBaseConfiguration">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>


Can someone tell me what I'm doing wrong?
java android tcp serversocket
© www.soinside.com 2019 - 2024. All rights reserved.