Как отправить массив байтов по TCP-соединению (java-программирование)
Может кто-нибудь продемонстрировать, как отправить массив байтов через TCP-соединение из программы-отправителя в программу-приемник в Java.
byte[] myByteArray
(Я новичок в программировании на Java и не могу найти пример того, как это сделать, что показывает оба конца соединения (отправитель и получатель). Если вы знаете существующий пример, возможно, вы могли бы (Нет необходимости изобретать колесо). PS Это НЕ домашнее задание!: -)
Ответы
Ответ 1
Классы InputStream
и OutputStream
в Java обрабатывают массивы байтов. Единственное, что вы можете добавить, это длина в начале сообщения, чтобы получатель знал, сколько байтов ожидать. Обычно мне нравится предлагать метод, который позволяет контролировать, какие байты в массиве байтов отправлять, как и стандартный 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);
}
}
EDIT. Чтобы добавить принимающую сторону:
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;
}
Ответ 2
Просто начните с этот пример из Really Big Index. Обратите внимание, что он предназначен для передачи и приема символов, а не байтов. Однако это не имеет большого значения - вы можете иметь дело с необработанными объектами InputStream
и OutputStream
, которые предоставляет класс Socket
. См. API для получения дополнительной информации о различных типах читателей, писателей и потоков. Вам будут интересны методы OutputStream.write(byte[])
и InputStream.read(byte[])
.
Ответ 3
Учебное пособие Oracle Socket Communications, похоже, будет подходящей точкой запуска.
Обратите внимание, что это приведет к дополнительной неприятности для превращения символов в байты. Если вы хотите работать на уровне байта, просто очистите его.
Ответ 4
Этот учебник Sun Sockets должен дать вам хорошую отправную точку
Ответ 5
То, что вам нужно использовать, - это метод write
метода java.io.OutputStream
и read
для java.io.InputStream
, оба из которых вы можете извлечь из открываемого Socket
.
Ответ 6
Я бы попросил вас использовать 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();
Также помните, что сначала создайте выходной поток, очистите его, а затем продолжите с входным потоком, потому что если что-то не указано в потоке, поток ввода не будет создан.
Ответ 7
Я предполагаю, что вопрос сформулирован неправильно. Я нашел это при поиске ответа на вопрос, почему мое использование InputStream и OutputStream показало, что весь массив равен 0 при встрече с байтом значения 0. Предположим ли они, что байты содержат действительный ASCII, а не двоичный. Поскольку вопрос не возникает и спрашивает об этом, и никто другой, похоже, не поймал его как возможность, я думаю, мне придется удовлетворить мои поиски в другом месте.
То, что я пытался сделать, это написать класс TransparentSocket, который может создавать прозрачность через TCP (Socket/ServerSocket) или UDP (DatagramSocket) для использования DatagramPacket. Он работает для UDP, но не для TCP.
Последующие действия: я, похоже, подтвердил, что эти потоки сами по себе бесполезны для двоичных передач, но что они могут быть переданы в более удобное для программиста создание экземпляра, например,
новый DataOutputStream (socket.getOutputStream()). writeInt (5);
^ Так много для этой идеи. Он записывает данные "переносимым" способом, то есть, вероятно, ASCII, который вообще не помогает, особенно при эмуляции программного обеспечения, над которым я не контролирую!
Ответ 8
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();
}
}
Ответ 9
Ниже приведен пример, который передает по 100 байт файлов фреймов за один раз.
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 ;-)
}
}