有人可以演示如何通過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