Java 客户端中的DatagramSocket未绑定到服务器中的端口。端口已在使用中

Java 客户端中的DatagramSocket未绑定到服务器中的端口。端口已在使用中,java,sockets,networking,network-programming,bind,Java,Sockets,Networking,Network Programming,Bind,我有一个服务器,它正在等待客户端通过DatagramSocket发送数据包。但是,在客户端,我使用与服务器相同的端口,以便它们可以通信,我在客户端遇到一个异常: Exception in thread "main" java.net.BindException: Address already in use: Cannot bind at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method) at java.net

我有一个服务器,它正在等待客户端通过DatagramSocket发送数据包。但是,在客户端,我使用与服务器相同的端口,以便它们可以通信,我在客户端遇到一个异常:

Exception in thread "main" java.net.BindException: Address already in use: Cannot bind
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:80)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:93)
at java.net.DatagramSocket.bind(DatagramSocket.java:372)
at java.net.DatagramSocket.<init>(DatagramSocket.java:222)
at java.net.DatagramSocket.<init>(DatagramSocket.java:279)
at tp.Repositorio.main(Cliente.java:146)
在客户端,我有这样的东西:

addr = InetAddress.getByName("localhost");
DatagramSocket socket = new DatagramSocket(5008, addr);
DatagramPacket packet = new DatagramPacket(buff, buff.length);
 while(true)
    {
      s.receive(packet);
// and then it throws another thread to treat the packet...
    }
 InetAddress inet;
 inet = InetAddress.getByName("localhost");
 s_data = new DatagramSocket(5008, inet);
我试图改变两边的端口,但它也给了我这个例外。如果我将服务器中的端口更改为5003,客户端中的端口更改为5004,当然不会给我任何异常,但它们无法相互连接

你们有办法解决这个问题吗

谢谢

编辑:

以下是名为repositorio的客户端代码:

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package tp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Diogo
 */
public class Repositorio {
    static int nr_ligacoes;
    static int porto;
    static String endereco;


    Repositorio(int pt, String end)
    {
        this.porto = pt;
        this.endereco = end;
    }

    public static void setNr_ligacoes(int nr_ligacoes) {
        Repositorio.nr_ligacoes = nr_ligacoes;
    }

    public static void setPorto(int porto) {
        Repositorio.porto = porto;
    }

    public static void setEndereco(String endereco) {
        Repositorio.endereco = endereco;
    }



    public File[] getFicheiros()
    {
        File folder = new File("C:\\temp2");

        File[] ficheiros = folder.listFiles();


        for (int i = 0; i < ficheiros.length; i++) {
            if (ficheiros[i].isFile()) {
                System.out.println("File " + ficheiros[i].getName());
            } else if (ficheiros[i].isDirectory()) {
                System.out.println("Directory " + ficheiros[i].getName());
            }
        }

        return ficheiros;
    }

    public int getNr_ligacoes() {
        return nr_ligacoes;
    }


    public int getPorto() {
        return porto;
    }

    public String getEndereco() {
        return endereco;
    }

    public ArrayList<String> getListadeFicheiros()
    {
        ArrayList<String> fich_nome = new ArrayList<>();
        File[] fich = getFicheiros();

        for(int i = 0; i <fich.length ; i++)
            fich_nome.add(fich[i].getName());

        return fich_nome;
    }

    public boolean VerFicheiro(String nome)
    {
        File[] fich = getFicheiros();


        for(int i = 0; i<fich.length;i++)
            if(nome.compareTo(fich[i].getName()) == 0)
                return true;
        return false;
    }




    public static void main(String[] args) throws IOException
    {
        ServerSocket socket_r;
        File localDirectory;
        DatagramSocket s_data;
        DatagramPacket p;


        /* if(args.length != 4){
        System.out.println("Sintaxe: java Repositorio serverTcpPort serverAddress localDirectory");
        return;
        }  */

        localDirectory = new File("C:\\temp2");

        if(!localDirectory.exists()){
            System.out.println("A directoria " + localDirectory + " nao existe!");
            return;
        }

        if(!localDirectory.isDirectory()){
            System.out.println("O caminho " + localDirectory + " nao se refere a uma directoria!");
            return;
        }

        if(!localDirectory.canWrite()){
            System.out.println("Sem permissoes de escrita na directoria " + localDirectory);
            return;
        }

        //Repositorio r = new Repositorio(5002,"localhost");
        InetAddress inet;
        inet = InetAddress.getByName("localhost");
        socket_r = new ServerSocket(5003);

        new lancaRepositorioCliente(socket_r, localDirectory).start();

        s_data = new DatagramSocket(5008, inet);

        new lancarepositorioServidor(s_data, localDirectory).start();


    }




    static class lancarepositorioServidor extends Thread{

        DatagramSocket s;
        File localDirectory;
        ListadeRepositorios listaRep;

        lancarepositorioServidor(DatagramSocket s_data, File local)
        {
            this.localDirectory = local;
            this.s = s_data;
        }

        @Override
        public void run() {
            System.out.println("Estou no lanca to servidor");
            byte[] buf = new byte[10000];
            DatagramPacket pack = new DatagramPacket(buf, 128);

            new repositorioToServidor(pack,s).start();

        }

    }
    static class repositorioToServidor extends Thread{
        DatagramPacket pack;
        DatagramSocket s;

        public repositorioToServidor(DatagramPacket packet, DatagramSocket s) {
            this.pack = packet;
            this.s = s;

        }

        @Override
        public void run() {

            while(true)
            {
                try {
                    sleep(10000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Repositorio.class.getName()).log(Level.SEVERE, null, ex);
                }
                ByteArrayOutputStream bos = new ByteArrayOutputStream(2048);
                ObjectOutputStream oos;
                try {
                    oos = new ObjectOutputStream(bos);
                    oos.writeObject(new Notificacao(nr_ligacoes));

                    DatagramPacket packet = new DatagramPacket(bos.toByteArray(), bos.size());
                    s.send(packet);

                } catch (IOException ex) {
                    Logger.getLogger(Repositorio.class.getName()).log(Level.SEVERE, null, ex);
                }


            }


        }


    }


    static class repositorioToCliente extends Thread{
        Socket s;
        File localDirectory;

        public repositorioToCliente(Socket s, File local) {
            this.s = s;
            this.localDirectory = local;
        }

        public Socket getS() {
            return s;
        }

        @Override
        public void run() {

            System.out.println("Estou no lanca to cliente");


        }


    }


    static class lancaRepositorioCliente extends Thread{
        ServerSocket s;
        File localDirectory;

        public lancaRepositorioCliente(ServerSocket s, File local) {
            this.s = s;
            this.localDirectory = local;
        }

        public ServerSocket getS() {
            return s;
        }

        @Override
        public void run() {
            Socket sClient;

            while(true)
            {
                try {
                    sClient = s.accept();

                    new repositorioToCliente(sClient,localDirectory).start();
                    // vamos aqui receber o ficheiro que é para eliminar/depositar

                } catch (IOException ex) {
                    Logger.getLogger(Repositorio.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        }


    }

}
服务器代码:

    package tp;

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 *
 * @author Diogo
 */
public class Servidor{

    protected File localDirectory;
    static String LoginfileName;
    //List <Repositorio> rep = null;
    static ListadeRepositorios listaRep;
    static ArrayList <String> ficheiros = null;

    public Servidor()
    {
        this.ficheiros = new ArrayList<>();
    }

    public void setFicheiros(List <String> a)
    {
        a.stream().forEach((a1) -> {
            ficheiros.add(a1);
        });
    }

    public static void main(String[] args) throws IOException
    {
        Servidor s = new Servidor();
        ListadeRepositorios lista_rep = new ListadeRepositorios();
        int listeningPort1;
        int listeningPort2;
        ServerSocket serverSocket;
        InetAddress addr;
        DatagramSocket socket;

        try {

            //listeningPort = Integer.parseInt(args[0]);
            listeningPort1 = 5001;
            listeningPort2 = 5008;

            if(listeningPort1 <= 0) throw new NumberFormatException("Porto TCP de escuta indicado <= 0 (" + listeningPort1 + ")");


            LoginfileName = "c:/temp/users.txt";

            serverSocket = new ServerSocket(listeningPort1);

            serverSocket.setSoTimeout(1000000000);

            new lancaCliente(serverSocket, LoginfileName).start();

            addr = InetAddress.getByName("localhost");
            socket = new DatagramSocket(listeningPort2, addr);


            new lancaRepositorio(socket).start();


        }catch(NumberFormatException e){
            System.out.println("O porto de escuta deve ser um inteiro positivo.");
        }
    }


    static class lancaCliente extends Thread{

        ServerSocket s;
        String Login;

        public lancaCliente(ServerSocket s, String Login) {

            this.s = s;
            this.Login = Login;
        }

        @Override
        public void run() {
            Socket accept;

            while(true)
            {
                try {

                    System.out.println("Servidor à espera de clientes: ");


                    accept = s.accept();
                    System.out.println("Servidor aceitou Cliente");

                    new atendeCliente(accept, this.Login).start();


                } catch (IOException ex) {
                    Logger.getLogger(lancaCliente.class.getName()).log(Level.SEVERE, null, ex);
                }


            }

        }

    }

    static class atendeCliente extends Thread{

        int porto;
        //List<Repositorio> repositorios;
        List<String> clienteLogado;
        //List<Socket> socketsAbertos;
        List<String> infoFicheiros;
        Socket Scliente;
        List<String> lines;
        String arg0 = null,arg1 = null, arg2=null;
        String[] comando;
        String filename;
        ListadeRepositorios listaRep2;


        public static final int TIMEOUT = 5; //segundos

        atendeCliente(Socket s, String nome)
        {
            this.Scliente = s;
            this.filename = nome;
        }



        protected int processaLogin(String user, String pass) throws IOException
        {
            String separaUser = null, separaPass=null;
            String[] separa;

            Path caminho = Paths.get("C:/temp/users.txt");

            Charset charset = Charset.forName("ISO-8859-1");

            try {
                lines = Files.readAllLines(caminho, charset);

                lines.stream().forEach((line) -> {
                    System.out.println(line);
                });
            } catch (IOException e) {
                System.out.println(e);
            }

            for(int i = 0; i<lines.size();i++)
            {
                separa = lines.get(i).split("\\s+");
                separaUser = separa[0];
                separaPass = separa[1];

                if(user.compareTo(separaUser) == 0 && pass.compareTo(separaPass)==0)
                    return 1;
            }
            return 0;

        }


        @Override
        public void run()
        {
            BufferedReader buf = null;
            PrintWriter escreve = null;
            int estaLogado;
            String mensagem = "";

            try {
                buf = new BufferedReader(new InputStreamReader(Scliente.getInputStream()));
            } catch (IOException ex) {
                Logger.getLogger(atendeCliente.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                escreve = new PrintWriter(Scliente.getOutputStream());
            } catch (IOException ex) {
                Logger.getLogger(atendeCliente.class.getName()).log(Level.SEVERE, null, ex);
            }

            try {
                while(true)
                {
                    try {
                        buf = new BufferedReader(new InputStreamReader(Scliente.getInputStream()));
                    } catch (IOException ex) {
                        Logger.getLogger(atendeCliente.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    System.out.println("Estou a espera de uma mensagem do cliente");
                    mensagem = buf.readLine();

                    System.out.println("Recebi: " + mensagem);
                    comando = mensagem.split("\\s+");
                    arg0  = comando[0];
                    arg1  = comando[1];
                    arg2  = comando[2];
                    System.out.println(comando[0] + comando[1] + comando[2]);
                    System.out.println(arg0 + arg1 + arg2);
                    if("login".compareTo(arg0)==0)
                    {
                        estaLogado = processaLogin(arg1, arg2);
                        if (estaLogado == 0)
                        {
                            escreve.println("Nao existe!");
                            escreve.flush();
                        }
                        else
                        {
                            escreve.println("LoginFeito");
                            escreve.flush();
                        }
                    }

                    else if("deposita".compareTo(arg0)==0 || "apaga".compareTo(arg0) == 0)
                    {
                        Repositorio rep;
                        rep = listaRep2.MenosCongest();
                        int porto_rep = rep.getPorto();
                        String end_rep = rep.getEndereco();
                        String porto_s = Integer.toString(porto_rep);
                        String comandoToCliente = end_rep + " " + porto_s;

                        escreve.println(comandoToCliente);
                        escreve.flush();
                    }

                    else if("listaficheiros".compareTo(arg0) == 0)
                    {
                        ObjectOutputStream outB = new ObjectOutputStream(Scliente.getOutputStream());
                        ficheiros.add("f1.txt");
                        ficheiros.add("f2.txt");
                        ficheiros.add("f3.txt");
                        ficheiros.add("f4.txt");

                        //ficheiros_disponiveis = listaRep.getFicheiros();

                        outB.writeObject(ficheiros);
                        outB.flush();
                    }

                    mensagem = "";
                }



            } catch (IOException ex) {
                Logger.getLogger(atendeCliente.class.getName()).log(Level.SEVERE, null, ex);
            }catch (Exception e){
            }

        }

    }


    static class lancaRepositorio extends Thread{

        DatagramSocket ser;
        ListadeRepositorios listaRep;

        public lancaRepositorio(DatagramSocket s)
        {
            this.ser = s;
        }


        @Override
        public void run() {

            byte[] buff = new byte[1024];

            DatagramSocket s = this.ser;
            DatagramPacket packet = new DatagramPacket(buff, buff.length);
            Repositorio r;

            while(true)
            {
                try {
                    System.out.println("Sevidor à espera de repositorios:");
                    s.receive(packet);
                    System.out.println("Sevidor recepbeu repositorios");
                    r = new Repositorio(packet.getPort(),packet.getAddress().getHostAddress());

                    listaRep.addRepositorio(r);
                    new atendeRepositorio(s,r).start();



                } catch (IOException ex) {
                    Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        }

    }



    static class atendeRepositorio extends Thread{

        DatagramSocket so;
        Repositorio r;

        public atendeRepositorio(DatagramSocket s, Repositorio r)
        {
            this.so = s;
            this.r = r;
        }

        @Override
        public void run() {
            while(true)
            {
                try {
                    byte[] incomingData = new byte[1024];
                    DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);

                    so.receive(incomingPacket);

                    byte[] data = incomingPacket.getData();

                    ByteArrayInputStream in;
                    in = new ByteArrayInputStream(data);

                    try (ObjectInputStream iStream = new ObjectInputStream(new ByteArrayInputStream(data))) {
                        Notificacao n1 = (Notificacao) iStream.readObject();

                        for(int i = 0;i<listaRep.getListaRepositorios().size();i++)
                        {
                            if(r == listaRep.getListaRepositorios().get(i))
                            {
                                r.setNr_ligacoes(n1.getN_op());
                            }

                        }

                    }


                } catch (IOException ex) {
                    Logger.getLogger(atendeRepositorio.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(atendeRepositorio.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }



    }



}
在浏览过程中,我发现有关DatagramSocket的以下内容:-

所有数据报套接字都绑定到一个本地端口,它们在该端口上侦听 传入数据和它们放在传出数据头中的数据 数据报。如果你在给客户写信,你不在乎当地人怎么说 端口是,因此您可以调用一个构造函数,让系统分配 未使用的端口是匿名端口。此端口号放置在任意位置 传出数据报,服务器将使用它来解决任何 响应数据报

如果要编写服务器,客户端需要知道 服务器正在哪个端口上侦听传入的数据报; 因此,当服务器构造DatagramSocket时,它会指定 它将侦听的本地端口。但是,所使用的套接字 客户端和服务器在其他方面是相同的:它们只在以下方面不同 无论他们使用的是匿名系统还是已知端口。 客户端套接字和服务器套接字之间没有区别,如下所示 TCP有很多缺点。没有DatagramServerSocket这样的东西

解决方案:-

您可能混淆了这两个端口。客户端的DatagramSocket应该使用匿名端口,而发送到服务器的数据包应该使用服务器端口发送到服务器。两者都是不同的东西。这可能根本不会生成BindException

只需在Cliente.java中使用以下构造函数调用即可创建客户端套接字:-

DatagramSocket socket = new DatagramSocket();
发送到服务器的DatagramPacket应使用与服务器相同的端口号:-

DatagramPacket packet = new DatagramPacket(buf, buf.length, 
                            address, 5008);    // server's port number is 5008
socket.send(packet);
我希望这能帮助并解决您的问题…

在浏览过程中,我发现了有关DatagramSocket的以下内容:-

所有数据报套接字都绑定到一个本地端口,它们在该端口上侦听 传入数据和它们放在传出数据头中的数据 数据报。如果你在给客户写信,你不在乎当地人怎么说 端口是,因此您可以调用一个构造函数,让系统分配 未使用的端口是匿名端口。此端口号放置在任意位置 传出数据报,服务器将使用它来解决任何 响应数据报

如果要编写服务器,客户端需要知道 服务器正在哪个端口上侦听传入的数据报; 因此,当服务器构造DatagramSocket时,它会指定 它将侦听的本地端口。但是,所使用的套接字 客户端和服务器在其他方面是相同的:它们只在以下方面不同 无论他们使用的是匿名系统还是已知端口。 客户端套接字和服务器套接字之间没有区别,如下所示 TCP有很多缺点。没有DatagramServerSocket这样的东西

解决方案:-

您可能混淆了这两个端口。客户端的DatagramSocket应该使用匿名端口,而发送到服务器的数据包应该使用服务器端口发送到服务器。两者都是不同的东西。这可能根本不会生成BindException

只需在Cliente.java中使用以下构造函数调用即可创建客户端套接字:-

DatagramSocket socket = new DatagramSocket();
发送到服务器的DatagramPacket应使用与服务器相同的端口号:-

DatagramPacket packet = new DatagramPacket(buf, buf.length, 
                            address, 5008);    // server's port number is 5008
socket.send(packet);

我希望这有助于解决您的问题……

是的,我是。在同一台机器上。给他们相同的端口是行不通的。通常,您不必为客户端套接字指定端口号,所有操作系统都会分配一些未使用的内容。但是,在建立连接或发送UDP数据报时,需要指定其他对等方的地址。在这里,您应该提供相同的端口号和服务器地址。你如何在客户端连接/发送邮件?我更新了帖子以包含客户端和服务器代码。是的。在同一台机器上。给他们相同的端口是行不通的。通常,您不必为客户端套接字指定端口号,所有操作系统都会分配一些未使用的内容。但是,在建立连接或发送UDP数据报时,需要指定其他对等方的地址。在这里,您应该提供相同的端口号和服务器地址。如何在客户端连接/发送邮件?我更新了帖子,添加了客户端和服务器代码。你说得对,我的朋友!!非常感谢!!:D@
从哪里获得地址有帮助吗?@YLS-这就是为什么参数地址出现在DatagramPacket的构造函数中。它是要发送请求的服务器的InetAddress!在启动套接字连接之前,您通常会提前知道服务器地址。您完全正确,我的朋友!!非常感谢!!:D@AM_I_Helpful从哪里获得地址?@YLS-这就是为什么参数地址出现在DatagramPacket的构造函数中。它是要发送请求的服务器的InetAddress!在启动套接字连接之前,您通常会提前知道服务器地址。