У меня есть сервер, который на клиентах посылает для отправки пакета через DatagramSocket. Но когда в клиенте я использовать те же порты, как сервер (так что они могут общаются) я получаю исключение в стороне клиента: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)
Так на стороне сервера у меня есть поток, который Wating на пакеты. Что-то вроде этого:
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 в Клиенте, это не дает мне никаких исключений (конечно), но они не могут соединяться между собой.
У вас есть идеи, чтобы решить эту проблему?
Спасибо.
Edit:
Вот следующий код клиента (он называется 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);
}
}
}
}
}
Да, я. В той же машине. –
Предоставление им того же порта не будет работать. Обычно вам не обязательно указывать номер порта для клиентского сокета (ОС назначит что-то неиспользуемое). Однако при установлении соединения или отправке дейтаграммы UDP вам необходимо указать адрес другого однорангового узла. Здесь вы должны указать тот же номер порта (вместе с адресом сервера). Как вы связываете/отправляете свои сообщения на клиента? – Inspired
Я обновил сообщение, чтобы включить клиент и код сервера. –