简体   繁体   English

如何通过TCP连接发送字节数组(java编程)

[英]how to send an array of bytes over a TCP connection (java programming)

Can somebody demonstrate how to send an array of bytes over a TCP connection from a sender program to a receiver program in Java. 有人可以演示如何通过TCP连接从发送器程序向Java中的接收器程序发送字节数组。

byte[] myByteArray

(I'm new to Java programming, and can't seem to find an example of how to do this that shows both ends of the connection (sender and receiver.) If you know of an existing example, maybe you could post the link. (No need to reinvent the wheel.) PS This is NOT homework! :-) (我是Java编程的新手,似乎无法找到如何执行此操作的示例,显示连接的两端(发送方和接收方)。如果您知道现有示例,也许您可​​以发布链接(不需要重新发明轮子。)PS这不是功课!:-)

The InputStream and OutputStream classes in Java natively handle byte arrays. Java中的InputStreamOutputStream类本身处理字节数组。 The one thing you may want to add is the length at the beginning of the message so that the receiver knows how many bytes to expect. 您可能想要添加的一件事是消息开头的长度,以便接收器知道预期的字节数。 I typically like to offer a method that allows controlling which bytes in the byte array to send, much like the standard API. 我通常喜欢提供一种方法,允许控制字节数组中的哪些字节发送,就像标准API一样。

Something like this: 像这样的东西:

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 : To add the receiving side: 编辑 :添加接收方:

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;
}

Just start with this example from the Really Big Index . 真正的大指数开始这个例子 Notice though, that it's designed to transmit and receive characters, not bytes. 但请注意,它旨在传输和接收字符,而不是字节。 This isn't a big deal, though - you can just deal with the raw InputStream and OutputStream objects that the Socket class provides. 但这不是什么大问题 - 你可以只处理Socket类提供的原始InputStreamOutputStream对象。 See the API for more info about the different types of readers, writers and streams. 有关不同类型的读者,编写者和流的更多信息,请参阅API。 Methods you'll be interested in are OutputStream.write(byte[]) and InputStream.read(byte[]) . 您感兴趣的方法是OutputStream.write(byte[])InputStream.read(byte[])

The Oracle Socket Communications Tutorial would seem to be the appropriate launch point. Oracle套接字通信教程似乎是合适的发布点。

Note that it's going to extra trouble to turn characters into bytes. 请注意,将字符转换为字节会更加麻烦 If you want to work at the byte level, just peel that off. 如果你想在字节级工作,只需将其剥离。

这个Sun Sockets教程应该为您提供一个很好的起点

你需要用什么write的方法java.io.OutputStream ,和read的方法java.io.InputStream ,这两者都可以从检索Socket打开。

I would ask you to use ObjectOutputStream and ObjectInputStream. 我会请你使用ObjectOutputStream和ObjectInputStream。 These send everything as an object and receive as the same. 它们将所有内容作为对象发送并以相同方式接收。

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();

Also remember first create the output stream, flush it and then go ahead with the input stream because if something left out in the stream the input stream wont be created. 还要记住首先创建输出流,刷新它然后继续输入流,因为如果流中遗漏了某些内容,则不会创建输入流。

I'm guessing that the question is worded incorrectly. 我猜这个问题措辞错误。 I found this when searching for an answer to why my use of InputStream and OutputStream seemed to be setting the entire array to 0 upon encountering a byte of value 0. Do these assume that the bytes contain valid ASCII and not binary. 我在寻找一个答案时找到了这个,为什么我在使用InputStream和OutputStream时遇到一个值为0的字节时将整个数组设置为0.这些假设这些字节包含有效的ASCII而不是二进制。 Since the question doesn't come right out and ask this, and nobody else seems to have caught it as a possibility, I guess I'll have to satisfy my quest elsewhere. 既然这个问题没有出来问这个问题,而且其他人似乎没有把它作为一种可能性,我想我必须满足我在其他地方的任务。

What I was trying to do was write a TransparentSocket class that can instantiate either a TCP (Socket/ServerSocket) or a UDP (DatagramSocket) to use the DatagramPacket transparently. 我试图做的是编写一个TransparentSocket类,它可以实例化TCP(Socket / ServerSocket)或UDP(DatagramSocket)以透明地使用DatagramPacket。 It works for UDP, but not (yet) for TCP. 它适用于UDP,但不适用于TCP。

Follow-up: I seem to have verified that these streams are themselves useless for binary transfers, but that they can be passed to a more programmer-friendly instantiation, eg, 后续:我似乎已经证实这些流本身对二进制传输无用,但它们可以传递给程序员更友好的实例化,例如,

new DataOutputStream(socket.getOutputStream()).writeInt(5); new DataOutputStream(socket.getOutputStream())。writeInt(5);

^ So much for that idea. 这个想法太多了。 It writes data in a "portable" way, ie, probably ASCII, which is no help at all, especially when emulating software over which I have no control! 它以“可移植”的方式写入数据,即可能是ASCII,这根本没有帮助,尤其是在模拟我无法控制的软件时!

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();
    }

}

Here is an example that streams 100 byte wav file frames at a time. 这是一个流式传输100字节wav文件帧的示例。

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 ;-)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM