有人可以演示如何通过TCP连接从发送程序发送字节数组到Java中的接收程序。如何通过TCP连接发送字节数组(Java编程)
byte[] myByteArray
(我是新来的Java编程,并且似乎无法找到显示(连接的两端发送者和接收者)。如何做到这一点的例子如果你知道一个现有的例子(不需要重新发明轮子。)PS这是不是作业!:-)
有人可以演示如何通过TCP连接从发送程序发送字节数组到Java中的接收程序。如何通过TCP连接发送字节数组(Java编程)
byte[] myByteArray
(我是新来的Java编程,并且似乎无法找到显示(连接的两端发送者和接收者)。如何做到这一点的例子如果你知道一个现有的例子(不需要重新发明轮子。)PS这是不是作业!:-)
Java中的InputStream
和OutputStream
类本地处理字节数组。您可能想要添加的一件事是消息开头的长度,以便接收者知道需要多少字节。我通常喜欢提供一种方法,允许控制字节数组中的哪些字节发送,非常类似于标准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;
}
The Oracle Socket Communications Tutorial似乎是合适的发射点。
请注意,它将额外的麻烦将字符转换为字节。如果你想在字节级别工作,只需剥离即可。
谢谢,但它不显示如何发送一个字节数组 – 2010-05-21 00:49:24
难道你不能自己找出休息吗? – 2010-05-21 01:07:51
这Sun Sockets tutorial应该给你一个很好的起点
它不显示如何通过 – 2010-05-21 00:48:50
发送字节数组然后您需要了解[基本IO](http://java.sun.com/docs/books/tutorial/essential/io/)或查看凯文布罗克回答:) – BalusC 2010-05-21 01:51:33
只是this example从Really Big Index开始。但请注意,它旨在传输和接收字符,而不是字节。然而,这不是什么大问题 - 您只需处理Socket
类提供的原始InputStream
和OutputStream
对象。有关不同类型的读者,作者和流的更多信息,请参阅API。你会感兴趣的方法是OutputStream.write(byte[])
和InputStream.read(byte[])
。
你需要使用什么是java.io.OutputStream
的write
方法和java.io.InputStream
的read
方法,这两者都可以从你打开Socket
检索。
我猜测,问题是不正确的措辞。当我在搜索一个答案时发现了这个问题,为什么我在使用InputStream和OutputStream时似乎将整个数组设置为0(遇到值为0的字节时)。是否这些假定字节包含有效的ASCII而不是二进制。由于这个问题并没有出现并问这个问题,而且似乎没有其他人把它作为一种可能性,我想我必须在别处满足我的追求。
我想要做的是编写一个TransparentSocket类,它可以实例化TCP(Socket/ServerSocket)或UDP(DatagramSocket)以透明地使用DatagramPacket。它适用于UDP,但不适用于TCP。后续工作:我似乎已经证实,这些流对于二进制传输本身是无用的,但是它们可以传递给更易于编程的实例化,例如,,
new DataOutputStream(socket.getOutputStream())。writeInt(5);
^这么多想法。它以“便携式”方式写入数据,即可能是ASCII,这完全没有帮助,特别是在模拟我无法控制的软件时!
我会问你使用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();
还记得第一次创建输出流,冲洗,然后用输入流继续,因为如果事情流中留出了输入流不会被创建。
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();
}
}
为什么OP要“试试这个”?一个**好的答案**将总是解释做了什么以及为什么这样做,不仅是为了OP,而且是为了将来访问SO的人可能会发现这个问题并且正在阅读你的答案。 – 2016-10-17 06:08:59
这里是一个例子,一次流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 ;-)
}
}
我该如何循环?就像等待输入流 – 2014-06-09 16:40:35
@ChristopherFrancisco Loop?只需从循环中调用方法即可。如果您的意思是等待消息而不停止程序,则可以在单独的线程上执行I/O,或将其修改为使用NIO。 – 2014-06-25 17:46:20
还没有测试过,但是如果len> [TCP数据包大小],我认为readFully()可能不会读取所有内容,只是第一个可用的部分....(https://docs.oracle.com/javase/ 7/docs/api/java/io/DataInput.html#readFully(byte []))因此,在这种情况下,此代码可能无法正常工作,对吧? – ntg 2015-05-06 07:59:31