comment envoyer un tableau d'octets sur une connexion TCP (programmation java)

Quelqu'un peut-il montrer comment envoyer un tableau d'octets sur une connexion TCP d'un programme expéditeur à un programme récepteur en Java.

byte[] myByteArray

(je suis nouveau à la programmation Java, et n'arrive pas à trouver un exemple de comment faire cela qui montre les deux extrémités de la connexion (expéditeur et récepteur.) Si vous connaissez un exemple existant, peut-être que vous pourriez poster le lien. (Pas besoin de réinventer la roue.) P.S. C'est Pas devoirs! :-)

24
demandé sur Mark Roberts 2010-05-21 04:40:27

9 réponses

Les classes InputStream et OutputStream en Java gèrent nativement les tableaux d'octets. La seule chose que vous pouvez ajouter est la longueur au début du message afin que le récepteur sache combien d'octets attendre. J'aime généralement offrir une méthode qui permet de contrôler les octets du tableau d'octets à envoyer, tout comme l'API standard.

Quelque Chose comme ceci:

private Socket socket;

public void sendBytes(byte[] myByteArray) throws IOException {
    sendBytes(myByteArray, 0, myByteArray.length);
}

public void sendBytes(byte[] myByteArray, int start, int len) throws IOException {
    if (len < 0)
        throw new IllegalArgumentException("Negative length not allowed");
    if (start < 0 || start >= myByteArray.length)
        throw new IndexOutOfBoundsException("Out of bounds: " + start);
    // Other checks if needed.

    // May be better to save the streams in the support class;
    // just like the socket variable.
    OutputStream out = socket.getOutputStream(); 
    DataOutputStream dos = new DataOutputStream(out);

    dos.writeInt(len);
    if (len > 0) {
        dos.write(myByteArray, start, len);
    }
}

EDIT: Pour ajouter le côté réception:

public byte[] readBytes() throws IOException {
    // Again, probably better to store these objects references in the support class
    InputStream in = socket.getInputStream();
    DataInputStream dis = new DataInputStream(in);

    int len = dis.readInt();
    byte[] data = new byte[len];
    if (len > 0) {
        dis.readFully(data);
    }
    return data;
}
56
répondu Kevin Brock 2011-06-01 19:12:25

Il suffit de commencer par cet exemple du vraiment grand Index. Notez cependant qu'il est conçu pour transmettre et recevoir des caractères, pas d'octets. Ce n'est pas une grosse affaire, cependant - vous pouvez simplement traiter les objets InputStream et OutputStream bruts que la classe Socket fournit. Voir L'API pour plus d'informations sur les différents types de lecteurs, écrivains et flux. Les méthodes qui vous intéresseront sont OutputStream.write(byte[]) et InputStream.read(byte[]).

4
répondu Catchwa 2010-05-21 01:50:15

Le tutoriel de communication Oracle socket semble être le point de lancement approprié.

Notez qu'il va problème supplémentaire pour transformer les caractères en octets. Si vous voulez travailler au niveau des octets, Décollez-le.

2
répondu bmargulies 2014-05-26 16:21:18

Ce Soleil Sockets tutoriel devrait vous donner un bon point de départ

1
répondu Alexander Pogrebnyak 2010-05-21 00:46:09

Ce que vous devez utiliser est le write méthode de java.io.OutputStream et le read méthode de java.io.InputStream, à la fois de laquelle vous pouvez récupérer à partir de la Socket vous ouvrez.

1
répondu Yann Ramin 2010-05-21 01:07:47

Je vous demande D'utiliser ObjectOutputStream et ObjectInputStream. Ceux-ci envoient tout comme un objet et reçoivent comme le même.

ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
os.flush();
ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
os.writeObject(byte_array_that_you_want_to_send);
byte[] temp = (byte[]) is.readObject();

Rappelez-vous également de créer d'abord le flux de sortie, de le vider, puis d'aller de l'avant avec le flux d'entrée, car si quelque chose est laissé dans le flux, le flux d'entrée ne sera pas créé.

1
répondu Revanth Kumar 2015-03-09 01:48:27

Je suppose que la question est mal formulée. J'ai trouvé cela lors de la recherche d'une réponse à la raison pour laquelle mon utilisation de InputStream et OutputStream semblait définir le tableau entier à 0 en rencontrant un octet de valeur 0. Est-ce que ceux-ci supposent que les octets contiennent ASCII valide et non binaire. Puisque la question ne vient pas tout de suite et pose ceci, et personne d'autre ne semble l'avoir pris comme une possibilité, je suppose que je vais devoir satisfaire ma quête ailleurs.

Ce que j'essayais de faire était d'écrire une classe TransparentSocket qui peut instancier soit un TCP (Socket / ServerSocket) ou un UDP (DatagramSocket) pour utiliser le DatagramPacket de manière transparente. Cela fonctionne pour UDP, mais pas (encore) pour TCP.

Suivi: il me semble avoir vérifié que ces flux sont eux-mêmes inutiles pour les transferts binaires, mais qu'ils peuvent être passés à une instanciation plus conviviale pour le programmeur, par exemple,

Nouveau DataOutputStream(socket.getOutputStream ()).writeInt(5);

^ tellement pour cette idée. Il écrit des données de manière "portable", c'est-à-dire, probablement ASCII, ce qui n'est d'aucune aide, surtout lors de l'émulation de logiciels sur lesquels je n'ai aucun contrôle!

0
répondu Jerry Miller 2012-12-07 18:12:10
import java.io.*;
import java.net.*;

public class ByteSocketClient 
{
    public static void main(String[] args) throws UnknownHostException, IOException 
    {
        Socket s=new Socket("",6000);

        DataOutputStream dout=new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));

        byte[] a = {(byte)0xC0,(byte)0xA8,(byte)0x01,(byte)0x02,(byte)0x53,(byte)0x4D,(byte)0x41,(byte)0x52,(byte)0x54};
        dout.write(a);
        dout.close();
        s.close();
    }

}
0
répondu Utpal Goswami 2016-10-17 05:47:29

Voici un exemple qui diffuse des trames de fichiers WAV de 100 octets à la fois.

private Socket socket;

public void streamWav(byte[] myByteArray, int start, int len) throws IOException {

    Path path = Paths.get("path/to/file.wav");

    byte[] data = Files.readAllBytes(path);

    OutputStream out = socket.getOutputStream();
    DataOutputStream os = new DataOutputStream(out);

    os.writeInt(len);
    if (len > 0) {
        os.write(data, start, len);
    }
}

public void readWav() throws IOException {

    InputStream in = socket.getInputStream();

    int frameLength = 100; // use useful number of bytes

    int input;
    boolean active = true;

    while(active) {
        byte[] frame = new byte[frameLength];
        for(int i=0; i<frameLength; i++) {

            input = in.read();

            if(input < 0) {
                active = false;
                break;
            } else frame[i] = (byte) input;
        }

        // playWavPiece(frame);
        // streamed frame byte array is full
        // use it here ;-)
    }
}
0
répondu Lightbeard 2016-11-24 16:39:46