java.net.ConnectException: Połączenie odrzucone


186

Próbuję zaimplementować połączenie TCP, wszystko działa dobrze po stronie serwera, ale po uruchomieniu programu klienckiego (z komputera klienckiego) pojawia się następujący błąd:

java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
        at java.net.Socket.connect(Socket.java:529)
        at java.net.Socket.connect(Socket.java:478)
        at java.net.Socket.<init>(Socket.java:375)
        at java.net.Socket.<init>(Socket.java:189)
        at TCPClient.main(TCPClient.java:13)

Próbowałem zmienić numer gniazda na wypadek, gdyby był używany, ale bezskutecznie, czy ktoś wie, co powoduje ten błąd i jak go naprawić.

Kod serwera:

//TCPServer.java

import java.io.*;
import java.net.*;

class TCPServer {
    public static void main(String argv[]) throws Exception {
        String fromclient;
        String toclient;

        ServerSocket Server = new ServerSocket(5000);

        System.out.println("TCPServer Waiting for client on port 5000");

        while (true) {
            Socket connected = Server.accept();
            System.out.println(" THE CLIENT" + " " + connected.getInetAddress()
                    + ":" + connected.getPort() + " IS CONNECTED ");

            BufferedReader inFromUser = new BufferedReader(
                    new InputStreamReader(System.in));

            BufferedReader inFromClient = new BufferedReader(
                    new InputStreamReader(connected.getInputStream()));

            PrintWriter outToClient = new PrintWriter(
                    connected.getOutputStream(), true);

            while (true) {

                System.out.println("SEND(Type Q or q to Quit):");
                toclient = inFromUser.readLine();

                if (toclient.equals("q") || toclient.equals("Q")) {
                    outToClient.println(toclient);
                    connected.close();
                    break;
                } else {
                    outToClient.println(toclient);
                }

                fromclient = inFromClient.readLine();

                if (fromclient.equals("q") || fromclient.equals("Q")) {
                    connected.close();
                    break;
                } else {
                    System.out.println("RECIEVED:" + fromclient);
                }

            }

        }
    }
}

Kod klienta:

//TCPClient.java

import java.io.*;
import java.net.*;

class TCPClient {
    public static void main(String argv[]) throws Exception {
        String FromServer;
        String ToServer;

        Socket clientSocket = new Socket("localhost", 5000);

        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
                System.in));

        PrintWriter outToServer = new PrintWriter(
                clientSocket.getOutputStream(), true);

        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
                clientSocket.getInputStream()));

        while (true) {

            FromServer = inFromServer.readLine();

            if (FromServer.equals("q") || FromServer.equals("Q")) {
                clientSocket.close();
                break;
            } else {
                System.out.println("RECIEVED:" + FromServer);
                System.out.println("SEND(Type Q or q to Quit):");

                ToServer = inFromUser.readLine();

                if (ToServer.equals("Q") || ToServer.equals("q")) {
                    outToServer.println(ToServer);
                    clientSocket.close();
                    break;
                } else {
                    outToServer.println(ToServer);
                }
            }
        }
    }
}

Czy możesz napisać kod klienta? Jeśli jest to klient zdalny, upewnij się, że nie masz żadnych problemów z zaporą!
home

Wyłączyłem zapory ogniowe zarówno na kliencie, jak i serwerze i wciąż ten sam problem
Samantha Catania

2
Na jakim interfejsie nasłuchuje serwer. Jeśli słuchasz tylko na localhost, nie możesz połączyć się zdalnie.
Thorbjørn Ravn Andersen

Próbowałem połączyć się zdalnie podczas używania localhost, twarz do dłoni. To jest moja pierwsza wersja próbna z TCP>. <Jak sprawić, by działała zdalnie?
Samantha Catania

Pamiętaj, że możesz mieć między nimi również zapory sprzętowe typu „bare metal” ... czy to działa, jeśli klient i serwer są na tym samym urządzeniu?
home

Odpowiedzi:


323

Ten wyjątek oznacza, że ​​nie ma usługi nasłuchującej na adresie IP / porcie, z którym próbujesz się połączyć:

  • Próbujesz połączyć się z niewłaściwym adresem IP / hostem lub portem.
  • Nie uruchomiłeś swojego serwera.
  • Twój serwer nie oczekuje połączeń.
  • Na serwerach Windows kolejka zaległości nasłuchiwania jest pełna.

52
Czuję się głupio, że przeoczyłem to You have not started your server, ale to rzeczywiście był dla mnie problem!
Alexis Leclerc

Żeby było jasne - „rdzeń Javy jest w porządku”. Jedynym problemem jest to, że pomijamy problemy .. (stan serwera, adres ipada, port, łączność z Internetem - bycie na tym samym routerze jest konieczne dla lokalnych adresów IP i więcej)
Vinay Bhargav

1
Collin, co dokładnie rozumiesz przez „serwer nie czeka na akceptację połączeń”? Ludzie papugują to wokół, jakby to coś znaczyło.
Markiz Lorne

Napisałem to jakiś czas temu, ale myślę, że miałem na myśli to inny sposób na powiedzenie, że nie uruchomiłeś swojego serwera.
Collin Price

w moim przypadku miałem uruchomione cztery symulatory Gennymotion i próbowałem załadować aplikację na kartę Galaxy i otrzymywałem ten błąd. po przeczytaniu dużo z kumpla WEB, następnie zamknąłem wszystkie symulatory i zaćmienie, zabiłem ADP w menedżerze zadań, a następnie ponownie uruchomiłem Eclipse i wszystko zaczęło działać poprawnie. Myślę, że kiedy masz uruchomionych wiele symulatorów, a następnie próbujesz podłączyć urządzenie, ADB oszalało z mojego doświadczenia. to są moje dwa centy ... :)
Vincy

40

Sprawdziłbym:

  • Nazwa hosta i port, z którym próbujesz się połączyć
  • Po stronie serwera udało się poprawnie rozpocząć nasłuchiwanie
  • Brak zapory blokującej połączenie

Najprostszym punktem wyjścia jest prawdopodobnie próba ręcznego połączenia z komputera klienckiego za pomocą telnet lub Putty. Jeśli to się powiedzie, problem tkwi w kodzie klienta. Jeśli nie, musisz dowiedzieć się, dlaczego tak się nie stało. Wireshark może ci w tym pomóc.


Czasem dostaję ten wyjątek. Dzieje się tak przez określony czas. Natychmiast zgłasza ten wyjątek. A potem wszystko staje się w porządku. Mam zaporę na serwerze. Ale dodałem regułę ruchu przychodzącego, aby umożliwić połączenia przychodzące na porcie 8080. Czy reguła jest czasami ignorowana?
Ashwin

@Ashwin: Naprawdę nie można powiedzieć - trzeba dokładnie ustalić, jak daleko idą dane. Spójrz na dzienniki zapory sieciowej itp.
Jon Skeet

@JonSkeet jak skonfigurować naszą zaporę, jeśli mamy ten błąd?
Nikhil Pareek

1
@Nikhil: Nie mam kwalifikacji, aby odpowiedzieć na to pytanie, ale podejrzewam, że każdy, kto jest wykwalifikowany, potrzebuje znacznie więcej informacji, aby ci pomóc. (Po pierwsze, nie wiemy, jaką masz zaporę ogniową ...)
Jon Skeet

7

Musisz podłączyć gniazdo klienta do zdalnego serwera ServerSocket. Zamiast

Socket clientSocket = new Socket("localhost", 5000);

robić

Socket clientSocket = new Socket(serverName, 5000);

Klient musi połączyć się z nazwą serwera, która powinna pasować do nazwy lub adresu IP skrzynki, na której ServerSocketutworzono instancję (nazwa musi być dostępna z komputera klienta). BTW: To nie nazwa jest ważna, chodzi tylko o adresy IP ...


Zakładam, że używa ich obu na tej samej maszynie do celów testowych, dlatego właśnie localhost byłby w porządku
SE

@Aaron: Powiedziała, że ​​to działa, jeśli klient i serwer działają na tym samym komputerze (odpowiedź można znaleźć w innym komentarzu).
domu

„Powyższy wiersz wiąże gniazdo z hostem lokalnym” Nie, nie łączy, wiąże je z INADDR_ANY. To pozwala mu akceptować połączenia za pośrednictwem dowolnej karty sieciowej. To, co robi OP, jest już poprawne. Odpowiedź jest całkowicie niepoprawna. Downvoting.
Markiz Lorne

@EJP: Masz rację ServerSocket, zmodyfikowałem odpowiedź. Niemniej jednak clientSocketnadal próbuje się połączyć localhost.
home

@ home Musisz usunąć frazę dotyczącą adresu powiązania.
Markiz Lorne

7

Miałem ten sam problem, ale naprawiłem serwer przed uruchomieniem klienta.


4
Oczywiście musisz uruchomić serwer przed klientem. Uruchomienie klienta w pierwszej kolejności i próba połączenia się z serwerem oznacza, że ​​nie można nawiązać połączenia z serwerem po uruchomieniu.
user3308043

5
@ user3308043 Tak, to było oczywiste, ale nie było zbyt oczywiste dla niektórych nowych programistów (takich jak ja 3 lata temu), więc chciałem po prostu podzielić się tym z innymi, którzy byli tak bladymi jak ja.
Dao Lam

Dzięki, pomogło mi to również, połączenie testowe zakończyło się powodzeniem, ale nie udało się wyświetlić żadnych danych tabel.
Damien Christophe

6

Chciałbym dodać do powyższych odpowiedzi jedno z moich doświadczeń -

„Hostowałem na moim serwerze na localhost i próbowałem połączyć się z nim za pomocą emulatora Androida , podając właściwy adres URL, taki jak http://localhost/my_api/login.php. Dostałem błąd odmowy połączenia

Zwróć uwagę - kiedy właśnie przeszedłem do przeglądarki na PC i użyłem tego samego adresu URL ( http://localhost/my_api/login.php) , otrzymałem poprawną odpowiedź

Problemem w moim przypadku był termin, localhostktóry zastąpiłem adresem IP mojego serwera (ponieważ Twój serwer jest hostowany na twoim komputerze), co sprawiło, że jest on dostępny z mojego emulatora na tym samym komputerze.


Aby uzyskać adres IP dla twojego komputera lokalnego, możesz użyć ipconfigpolecenia na cmd, otrzymasz IPv4 coś w rodzaju 192.68.xx.yy Voila .. to adres IP twojego komputera, na którym hostujesz serwer. użyj go zamiast localhost

http://192.168.72.66/my_api/login.php


Uwaga - nie będzie można uzyskać dostępu do tego prywatnego adresu IP z dowolnego węzła poza tym komputerem. (W razie potrzeby możesz użyć do tego Ngnix)


4

Miałem ten sam problem z brokerem Mqtt o nazwie vernemq. Ale rozwiązałem go, dodając następujące elementy.

  1. $ sudo vmq-admin listener show

aby wyświetlić listę dozwolonych adresów IP i portów dla vernemq

  1. $ sudo vmq-admin listener start port=1885 -a 0.0.0.0 --mountpoint /appname --nr_of_acceptors=10 --max_connections=20000

aby dodać dowolny adres IP i nowy port. teraz powinieneś być w stanie połączyć się bez problemu.

Mam nadzieję, że to rozwiąże twój problem. wprowadź opis zdjęcia tutaj


1
To uratowało mi dzień, ale ponieważ vernemq nie instaluje się z apt-get, niektórzy ludzie będą potrzebować tego linku: vernemq.com/docs/installation/debian_and_ubuntu.html
Damir Olejar

2

Mam nadzieję, że moje doświadczenie może być dla kogoś przydatne. Napotkałem problem z tym samym śledzeniem stosu wyjątków i nie mogłem zrozumieć, o co chodzi. Serwer bazy danych, z którym próbowałem się połączyć, działał, a port był otwarty i akceptował połączenia.

Problem dotyczył połączenia z Internetem. Połączenie internetowe, którego używałem, nie mogło połączyć się z odpowiednim serwerem. Kiedy zmieniłem szczegóły połączenia, problem został rozwiązany.


1

W moim przypadku nadałem gniazdu nazwę serwera (w moim przypadku „raspberrypi”), a zamiast tego zrobił to adres IPv4 lub, aby określić, IPv6 został uszkodzony (nazwa została rozstrzygnięta na IPv6)


1

W moim przypadku musiałem umieścić znacznik wyboru Expose daemon on tcp://localhost:2375 without TLSw pobliżu dockerustawienia (po prawej stronie paska zadań kliknij prawym przyciskiem myszy docker, wybierz setting)


1

dostałem ten błąd, ponieważ zamknąłem ServerSocket wewnątrz pętli for, która próbuje zaakceptować liczbę znajdujących się w niej klientów (nie skończyłem akceptować wszystkich wskazówek)

więc uważaj, gdzie zamknąć Socket


0

Miałem ten sam problem, ale problem polegał na tym, że nie zamykałem obiektu gniazda. Po użyciu socket.close (); problem rozwiązany. Ten kod działa dla mnie.

ClientDemo.java

public class ClientDemo {
    public static void main(String[] args) throws UnknownHostException,
            IOException {
        Socket socket = new Socket("127.0.0.1", 55286);
        OutputStreamWriter os = new OutputStreamWriter(socket.getOutputStream());
        os.write("Santosh Karna");
        os.flush();
        socket.close();
    }
}

i ServerDemo.java

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        System.out.println("server is started");
        ServerSocket serverSocket= new ServerSocket(55286);
        System.out.println("server is waiting");
        Socket socket=serverSocket.accept();
        System.out.println("Client connected");
        BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String str=reader.readLine();
        System.out.println("Client data: "+str);
        socket.close();
        serverSocket.close();

    }
}

1
Niezamknięcie gniazda klienta nie powoduje odmowy połączenia. Nie byłoby być gniazdo klienta do końca, czy połączenie zostało odrzucone.
Markiz Lorne


-2

Miałem ten sam problem i okazało się, że było to spowodowane catalina.outniepoprawnym zezwoleniem pliku. Nie był zapisywalny przez użytkownika tomcat. Po naprawieniu uprawnień problem został rozwiązany. Dowiedziałem się, że jest to problem z uprawnieniami z dzienników w tomcat8-initd.logpliku:

/usr/sbin/tomcat8: line 40: /usr/share/tomcat8/logs/catalina.out: Permission denied


1
„Odmowa zezwolenia” nie jest tym samym, co „odmowa połączenia”.
Markiz Lorne

Błąd odmowy uprawnień był w tomcat8-initd.logpliku, podczas gdy dzienniki wyjściowe serwera zawierały dokładnie błąd wymieniony w pytaniu.
kbsbng

-3

Możliwe, że poprzednia instancja klienta nadal działa i nasłuchuje na porcie 5000.


6
Klienci nie słuchają. Oni rozmawiają.
Raedwald

Poprzednie wystąpienie spowodowałoby błąd BindExceptionna serwerze, a nie ConnectExceptionna kliencie.
Markiz Lorne
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.