2010-05-21 137 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 ;-) 
    } 
} 
相關問題