Java 客户端中的DatagramSocket未绑定到服务器中的端口。端口已在使用中
我有一个服务器,它正在等待客户端通过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
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!在启动套接字连接之前,您通常会提前知道服务器地址。