2010-05-21 139 views
24

有人可以演示如何通过TCP连接从发送程序发送字节数组到Java中的接收程序。如何通过TCP连接发送字节数组(Java编程)

byte[] myByteArray 

(我是新来的Java编程,并且似乎无法找到显示(连接的两端发送者和接收者)。如何做到这一点的例子如果你知道一个现有的例子(不需要重新发明轮子。)PS这是不是作业!:-)

回答

54

Java中的InputStreamOutputStream类本地处理字节数组。您可能想要添加的一件事是消息开头的长度,以便接收者知道需要多少字节。我通常喜欢提供一种方法,允许控制字节数组中的哪些字节发送,非常类似于标准API。

事情是这样的:

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

编辑:要添加接收方:

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

我该如何循环?就像等待输入流 – 2014-06-09 16:40:35

+0

@ChristopherFrancisco Loop?只需从循环中调用方法即可。如果您的意思是等待消息而不停止程序,则可以在单独的线程上执行I/O,或将其修改为使用NIO。 – 2014-06-25 17:46:20

+0

还没有测试过,但是如果len> [TCP数据包大小],我认为readFully()可能不会读取所有内容,只是第一个可用的部分....(https://docs.oracle.com/javase/ 7/docs/api/java/io/DataInput.html#readFully(byte []))因此,在这种情况下,此代码可能无法正常工作,对吧? – ntg 2015-05-06 07:59:31

2

The Oracle Socket Communications Tutorial似乎是合适的发射点。

请注意,它将额外的麻烦将字符转换为字节。如果你想在字节级别工作,只需剥离即可。

+1

谢谢,但它不显示如何发送一个字节数组 – 2010-05-21 00:49:24

+0

难道你不能自己找出休息吗? – 2010-05-21 01:07:51

1

Sun Sockets tutorial应该给你一个很好的起点

+0

它不显示如何通过 – 2010-05-21 00:48:50

+0

发送字节数组然后您需要了解[基本IO](http://java.sun.com/docs/books/tutorial/essential/io/)或查看凯文布罗克回答:) – BalusC 2010-05-21 01:51:33

4

只是this exampleReally Big Index开始。但请注意,它旨在传输和接收字符,而不是字节。然而,这不是什么大问题 - 您只需处理Socket类提供的原始InputStreamOutputStream对象。有关不同类型的读者,作者和流的更多信息,请参阅API。你会感兴趣的方法是OutputStream.write(byte[])InputStream.read(byte[])

1

你需要使用什么是java.io.OutputStreamwrite方法和java.io.InputStreamread方法,这两者都可以从你打开Socket检索。

0

我猜测,问题是不正确的措辞。当我在搜索一个答案时发现了这个问题,为什么我在使用InputStream和OutputStream时似乎将整个数组设置为0(遇到值为0的字节时)。是否这些假定字节包含有效的ASCII而不是二进制。由于这个问题并没有出现并问这个问题,而且似乎没有其他人把它作为一种可能性,我想我必须在别处满足我的追求。

我想要做的是编写一个TransparentSocket类,它可以实例化TCP(Socket/ServerSocket)或UDP(DatagramSocket)以透明地使用DatagramPacket。它适用于UDP,但不适用于TCP。后续工作:我似乎已经证实,这些流对于二进制传输本身是无用的,但是它们可以传递给更易于编程的实例化,例如,,

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

^这么多想法。它以“便携式”方式写入数据,即可能是ASCII,这完全没有帮助,特别是在模拟我无法控制的软件时!

1

我会问你使用ObjectOutputStream和ObjectInputStream。这些将所有东西都作为一个对象发送并接收。

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

还记得第一次创建输出流,冲洗,然后用输入流继续,因为如果事情流中留出了输入流不会被创建。

0
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

为什么OP要“试试这个”?一个**好的答案**将总是解释做了什么以及为什么这样做,不仅是为了OP,而且是为了将来访问SO的人可能会发现这个问题并且正在阅读你的答案。 – 2016-10-17 06:08:59

0

这里是一个例子,一次流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 ;-) 
    } 
} 
相关问题