2012-01-06 20 views
1

私はこのTCPサーバーを稼動しています。UDPサーバーは大きなパケットを受け入れることができましたが、ISPはパブリックIPと静的サービスを持っていても私のUDPパケットをブロックします。しかし、今はTCPに変更することに決めましたが、私は大きなスタックを使用してUDPをTCPに置き換えました。TCP Javaでリアルタイムの大きなパケットを送受信する方法は?

ここでは実行中のサーバがありますが、大きなパケットをすぐに受信することはできません。どのようにして無制限または最大サイズなどに増やすことができますか?

1)これには何らかの方法がありますか?

public void run() 
{ 
    while(true) 
    { 
     byte[] buf=new byte[5024]; <<< not helping!! 
     int bytes_read = 0; 
     try {         
      bytes_read = sockInput.read(buf, 0, buf.length);     
      String data = null; 
      data = new String(buf, 0, bytes_read);     
      System.out.println("[TCP]: incomeing data: " + bytes_read + " bytes, data=" +data); 
    } 
} 

2)これには何らかの方法がありますか?

public TCPHandler(Socket sock) throws IOException 
{ 
    sock.setReceiveBufferSize(10*1024 +1024); //<<<<< not helping !!! 
    sock.setSendBufferSize(10*1024+1024); 
    this.sock = sock; 
    sockInput = sock.getInputStream(); 
    sockOutput = sock.getOutputStream(); 
    this.myThread = new Thread(this); 
} 

私はUDPからTCPに切り替えることができないように、大きな処理ができません。何か案は!!

+0

に続く、あなたはいくつかの特定のエラーを取得していますか? – cdeszaq

+0

あなたがメッセージ指向のプロトコルを望むなら、それはあなたのためにメッセージ境界を扱うでしょう、多分あなたはSCTPを探す必要があります... – lvella

答えて

1

あなたが抱えている問題は、InputStreamsの仕組みです。 read(buf、offset、length)を呼び出すと、毎回lengthバイトが読み込まれるとは限りません。単にInputStreamのavailable()を読み込み、読み込んだバイト数を返します。したがって、実際に長さのバイトを読み取るまで、引き続きreadを呼び出す必要があります。

int len = 0; 
int expectedLength = sockInput.readInt(); 
byte[] buf = new byte[ expectedLength ]; 
while(len != buf.length) { 
    len += sockInput.read(buf, len, buf.length); 
} 

// now you have a buffer with expectedLength data in it. 

また、あなたの

DataInputStream ds = new DataInputStream(sock.getInputStream()); 
ds.readFully(buf, 0, buf.length); 

http://docs.oracle.com/javase/6/docs/api/java/io/DataInputStream.html

をラップすることによってDataInputStream.readFullyを()を使用して見ることができますしかし、あなたは単なる文字列の後に本当にしている場合は、この作業を行う必要があります。

Reader reader = new InputStreamReader(sockInput.getInputStream(), "UTF-8"); 

read(byte []、offset、len)と同じread(char []、offset、length) gth)

+0

長さを使用せずに、私は "END"信号を送るプロトコルを書いた。 – YumYumYum

2

TCPとUDPが異なります。 TCPはパケットベースのプロトコルではなく、ストリームベースのプロトコルです。あなたのデータは、順番に到着し、壊れていないが、必ずしもすべてが一度に到着するとは限らない。

あなたがすべきことは、各セット 'パケット'に接頭辞を付けることです。データを受け取ったら、まず長さの値を読み取り、必要な量のデータが得られるまでソケットからチャンクの読み取りを続けます。

+0

私はデータを取得するためにこれを使用していますhttps://gist.github.com/1571076、しかし私はすべてが恋しい。 – YumYumYum

1

TCPがメッセージをパケットに分割する方法や、完全なメッセージを取得するために何回読む必要があるか気にする必要はありません。メッセージの終わりに達するまで読んでから、メッセージのすべてのバイトを返します。

メッセージが完全に読み取られた時点を知ることは、プロトコルによって異なります。接続ごとに1つのメッセージのみを送信するか、メッセージの前にメッセージの長さを送信するか、マーカーバイトを使用できます。

両方のマシンが異なるデフォルトのエンコーディングを持っている可能性があるので、あなたは、あなたがマシンから別のマシンに転送する場合は特に、エンコーディングを指定せずにnew String(byte[])を使用(およびString.getBytes()を呼び出すときに同じを使用)すべきではありません。

1

TCPは、一部を取得できるバイトストリームです.1つ以上のメッセージは、1回の読み取りです。 UDPパケットが532バイトを超えると、パケットが分割される可能性があります。

メッセージを簡単にエンコードするには、まず長さを送信します。

final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); 
final DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 

public void writeMessage(String text) { 
    out.writeUTF(text); 
} 

public String readMessage() { 
    return in.readUTF(); 
} 

読み取り/書き込みUTFは、第1の長さを送信し、コンテンツ

関連する問題