|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
[JAVA] Passaggio oggetti tramite DatagramPacket
come ricostruisco l'oggetto che ho passato tramite una datagrampacket al server?
mi spiego. sul server creo il mio labirinto 3d, che dfevo inviare a tutti i client in modo che loro possano "giocarlo". facendo una comunicazione a più cliente e il più veloce possibile, sto usando datagrampacket. ora, quando ricevo il datagrampacket faccio così: Codice:
byte[] buf = new byte[1024]; packet = new DatagramPacket(buf, buf.length); socket.receive(packet); inoltre, come faccio a sapere la dimensione del buffer per evitare troppi "sopacchettamenti"?
__________________
My gaming placement |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
uppetino?
__________________
My gaming placement |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Penso che tu abbia implementato degli I/O stream in grado di interfacciarsi sulla rete attraverso UDP. Prova a postarne il codice, cosi vediamo.
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
classe client
Codice:
package online;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import labirinti.Labirinto;
public class Client {
public static void main(String[] args) throws IOException {
MulticastSocket socket = new MulticastSocket(4446);
InetAddress address = InetAddress.getByName("224.0.0.1");
socket.joinGroup(address);
DatagramPacket packet;
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
buf=packet.getData();
boolean flag = true;
while (flag) {
String received = new String(packet.getData(), 0, packet
.getLength());
System.out.println("Quote of the Moment: " + received);
}
socket.leaveGroup(address);
socket.close();
}
}
Codice:
package online;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Date;
public class QuoteServerThread extends Thread {
protected DatagramSocket socket = null;
protected BufferedReader in = null;
protected boolean altroTesto = true;
public QuoteServerThread() throws IOException {
this("QuoteServerThread");
}
public QuoteServerThread(String name) throws IOException {
super(name);
socket = new DatagramSocket(4444);
try {
in = new BufferedReader(new FileReader("one-liners.txt"));
} catch (FileNotFoundException e) {
System.err.println("Could not open quote file. Serving time instead.");
}
}
public void run() {
while (altroTesto) {
try {
byte[] buf = new byte[1024];
// receive request
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// figure out response
String dString = null;
if (in == null)
dString = new Date().toString();
else
dString = getNextQuote();
buf = dString.getBytes();
// send the response to the client at "address" and "port"
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
altroTesto = false;
}
}
socket.close();
}
protected String getNextQuote() {
String returnValue = null;
try {
if ((returnValue = in.readLine()) == null) {
in.close();
altroTesto = false;
returnValue = "No more quotes. Goodbye.";
}
} catch (IOException e) {
returnValue = "IOException occurred in server.";
}
return returnValue;
}
}
Codice:
package online;
public class Server {
public static void main(String[] args) throws java.io.IOException {
new ServerThread(new ServerMakerLabirinto()).start();
}
}
classe servermakerlabirinto Codice:
package online;
import labirinti.Labirinto;
import labirinti.LabirintoSemplice;
public class ServerMakerLabirinto {
private Labirinto labirinto;
public ServerMakerLabirinto(){
this.labirinto=new LabirintoSemplice();
}
}
Codice:
package online;
import java.io.*;
import java.net.*;
import java.util.*;
public class ServerThread extends QuoteServerThread {
private long tempo = 5000;
private ServerMakerLabirinto serverMakerLabirinto;
public ServerThread(ServerMakerLabirinto serverMakerLabirinto) throws IOException {
super("ServerThread");
this.serverMakerLabirinto=serverMakerLabirinto;
}
public void run() {
while (altroTesto) {
try {
byte[] buf = new byte[256];
// construct quote
String dString = null;
if (in == null)
dString = new Date().toString();
else
dString = getNextQuote();
buf = dString.getBytes();
// send it
InetAddress group = InetAddress.getByName("224.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length,
group, 4446);
socket.send(packet);
// sleep for a while
try {
sleep((long) (Math.random() * tempo));
} catch (InterruptedException e) {
}
} catch (IOException e) {
e.printStackTrace();
altroTesto = false;
}
}
socket.close();
}
}
il servermaker costruisce il labirinto e lo passa al server. quando al server arrivano le richieste di 32 player (è un 1v1 il gioco) manda ad entrambi lo stesso labirinto, alchè i client costruiscono il proprio mondo 3d e mandano info continuamente al server che aggiorna il labirinto con le posizioni dei due pg e le rimanda ad entrambi. credo che la strutura sia corretta, ma non sò come ricostruire il labirinto una volta arrivati sui client
__________________
My gaming placement |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
up???
stavo pensando, mi dovrei creare un costruttore di labirinto che ricevi un []byte, ma come "cacchio" faccio? se pensate ad una soluzione diversa sparatemela pls, non ho molto tempo.
__________________
My gaming placement |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Costruisciti un tuo Input/Output stream, che recupera i byte da UDP, e lo agganci ad un Object stream.
|
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Quote:
mai fatto sinceramente
__________________
My gaming placement |
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Estendendo le classi astratte InputStream e OutputStream. Considera anche, di aggiungere al tuo protocollo su UDP qualche controllo supplementare, in modo da forzare la ri-spedizione di qualche segmento perso.
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Quote:
reputi sia più semplice? o meglio fe come suggerisci tu?
__________________
My gaming placement |
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Dipende molto da come intendi strutturare l' applicazione. Con RMI utilizzi gli oggetti remoti come se fossero in locale, quindi ti viene celata tutta la logica di rete che ci sta dietro. Nell' altro caso devi gestire da te il recupero degli oggetti e anche l' aventuale sincronizzazioni tra i "dati" prodotti localmente dai client e il server. Ovviamente cambia anche la distribuzione dei carichi di lavoro.
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Quote:
il gioco è nato come "in solo". ora lo sto estendendo in ulty, 1v1, chi trova l'uscita prima vince. praticamente il server crea il labirinto e lo comunica ai player, che creano il mondo 3d e lo navigano, comunicando al server la loro posizione continuamente, quindi inviano solo posizione(e non tutto come avevo pensato io prima), ma all'inizio ricevono tutto il labirinto. il server quando riceve i dati li ricomunica a tutti. cosa mi consigli di usare? rmi forse è eccessivo in questa ottiva, vero? e se usassi OBJECTOUTPUTSTREAM??? ho trovato un pdf che ne parla, me lo sto studiando.
__________________
My gaming placement Ultima modifica di franksisca : 10-06-2010 alle 16:23. |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Un' architettura ibrida? Nel senso che il gioco lo gestisci (una volta acquisito su ogni client il necessario) in locale su ogni client, come è giusto che sia, mentre la sincronizzazione tra i vari partecipanti, la fai in RMI in modo da gestirla, abbastanza agevolmente, come un' applicazione multi-thread sul server.
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
|
|
|
|
|
|
|
#14 | ||
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Quote:
Quote:
per info metto qui la dispensa, magari serve ad altri: http://issuu.com/franksisca/docs/invio_oggetti_udp_java
__________________
My gaming placement |
||
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
RMI è abbastanza potente, ma nel complesso non è affatto difficile implementare una buona struttura, anche perchè come ti dicevo ti concentreresti più sulla logica che sui dettagli del protocollo.
In alternativa, pur non conoscendo la mole di dati che transiterebbe sulla rete, mi viene in mente un sistema basato su UDP con Nack temporizzati(e magari gestione della mancanza temporanea di dati). In questo modo sarebbe il server a richiedere i dati in caso di mancata consegna. In tal modo aumenta la complessità e il carico computazionale del server, ma produci meno overhead di rete. |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
alora, ho fatto così:
client Codice:
package online;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import labirinti.LabirintoSemplice;
public class Client {
private InetAddress indirizzoIP;
private MulticastSocket datagramSocket;
private DatagramPacket datagramPacket;
private ByteArrayInputStream byteData;
private ByteArrayOutputStream byteOutput;
private ObjectInputStream objectInput;
private ObjectOutputStream objectOutput;
public void start() {
try {
int port = 1300;
// invio informazione al server della connessione avvenuta
byte buffer[] = new byte[256];
this.indirizzoIP = InetAddress.getByName("LocalHost");
this.datagramSocket = new MulticastSocket(port);
this.datagramSocket.joinGroup(this.indirizzoIP);
this.byteOutput = new ByteArrayOutputStream();
this.datagramPacket = new DatagramPacket(buffer, buffer.length,
this.indirizzoIP, port);
this.objectOutput = new ObjectOutputStream(this.byteOutput);
this.objectOutput.writeObject("sono connesso");
// ricevo dal server il labirinto in cui muovermi
this.datagramPacket = new DatagramPacket(buffer, buffer.length);
this.datagramSocket.receive(this.datagramPacket);
this.byteData = new ByteArrayInputStream(this.datagramPacket
.getData());
this.objectInput = new ObjectInputStream(this.byteData);
LabirintoSemplice labirinto = (LabirintoSemplice) this.objectInput
.readObject();// ricevo il labirinto e costruisco l'ambiente
// grafico
AmbienteOnlineClient ambienteClient = new AmbienteOnlineClient(
labirinto);
while (true) {// fino a quando qualcuno non vince
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Codice:
package online;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class ServerThread extends QuoteServerThread {
private ServerMakerLabirinto serverMakerLabirinto;
private MulticastSocket multicastSocket;
private ByteArrayOutputStream byteOutput;
private DatagramPacket pacchetto;
private ByteArrayInputStream byteData;
private ObjectOutputStream objectOutput;
private ObjectInputStream objectInput;
private InetAddress indirizzoIP;
public ServerThread(ServerMakerLabirinto serverMakerLabirinto)
throws IOException {
super("ServerThread");
this.serverMakerLabirinto = serverMakerLabirinto;
}
public void run() {
try {
this.indirizzoIP = InetAddress.getByName("LocalHost");
int port = 1300;
this.multicastSocket = new MulticastSocket();
byte[] data = new byte[1024];
int cnt = 0;
while (cnt < 2) {// aspetto i 2 client connessi
this.pacchetto = new DatagramPacket(data, data.length);
this.multicastSocket.receive(this.pacchetto);
this.byteData = new ByteArrayInputStream(this.pacchetto
.getData());
this.objectInput = new ObjectInputStream(this.byteData);
this.objectInput.readObject();
cnt++;
}
// i 2 client sono connessi, quindi invio ad entrambi il labiritno
// costruito senza mostri
this.byteOutput = new ByteArrayOutputStream();
this.pacchetto = new DatagramPacket(data, data.length,
this.indirizzoIP, port);
this.objectOutput = new ObjectOutputStream(this.byteOutput);
this.objectOutput.writeObject(this.serverMakerLabirinto
.getLabirinto()); // invio il labirinto ai client
this.objectOutput.flush();
data = this.byteOutput.toByteArray();
this.pacchetto.setData(data);
this.pacchetto.setLength(data.length);
this.multicastSocket.send(this.pacchetto);
this.byteOutput.reset();
while (true) {// ricevo i labirinti dai client e li reinvio
}
} catch (Exception e) {
}
}
}
credete che sia valida come soluzione?
__________________
My gaming placement |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:42.




















