2011-12-30 19 views
1

私はJavaに実験的なゲームサーバーを構築しています。UDPソケットデータグラム受信パケット2倍で完全なメッセージを取得

クライアントが送信:メッセージを受信する

length: 22\r\n 
playerId: 0\r\n 
\r\n\r\n 
this is a test message 

Javaコード:これは、クライアントによって送信されたメッセージの40のバイトを受信しない

String message = ""; 

byte[] buf = new byte[20]; 
DatagramPacket packet = new DatagramPacket(buf, buf.length); 
socketServer.receive(packet); 
message += new String(buf, "UTF8"); 

buf = new byte[20]; 
packet = new DatagramPacket(buf, buf.length); 
socketServer.receive(packet); 
message += new String(buf, "UTF8"); 

、それは20のバイトを受信し、第二にはsocketServer.receive(packet)新しいメッセージのためにハングアップします。 DEFによって

理由:データグラムが受信されるまで

この方法ブロック。 の長さフィールドには、受信した メッセージの長さが含まれています。メッセージがパケットの長さより長い場合、 メッセージは切り捨てられます。

私は20バイトのメッセージともう1つの20バイトのメッセージを読むことができる必要があります。これはどのように達成できますか?

私はメッセージがどれくらい長く続くかわからないので、これが必要です。

String message = ""; 
while (!message.contains("\r\n\r\n")) { //"\r\n\r\n" marks end of message 
    byte[] buf = new byte[20]; 
    DatagramPacket packet = new DatagramPacket(buf, buf.length); 
    socketServer.receive(packet); 
    message += new String(buf, "UTF8"); 
} 

これは、メッセージが\r\n\r\nで終わると仮定すると、完全なメッセージを取得します。私はこのような何かをしたいです。

UDPプロトコルで処理する必要があります。私はJavaのソケットに新しいですが、私はそこに何かがあると仮定して、それを見つけることができません。前もって感謝します。

答えて

2

UDPは可変長の読み取り用に設計されておらず、それぞれread() [またはrecv()]はサーバー上の単一のwrite() [またはsend()]に対応します。

40バイトのパケットの20バイトのみを読み取る場合、残りのバイトは破棄されます。

パケット全体を受信するのに十分な大きさのバッファ(ネットワークが断片化を適切に処理する場合は最大65536バイト)を作成し、パケット全体を一度に読み取る必要があります。

APIは実際に受信したバイト数を示します。にコード化された値と照合して、パケット全体を受信したことを確認することを検討してください。

+0

これがパフォーマンスに影響しますか?バッファーを本当に高く設定することは悪い可能性があるようですが、わかりません。 –

+1

@PatrickLorioには64kバッファがありますか?わずかなことではなく、ちょっとしたRAMです。 – Alnitak

+1

UDPデータグラムの最大サイズは65535-28バイトです。 – EJP

2

40バイトを書き込む場合、40バイトを受け取る必要があります。 40バイトを書き、バッファが20だけの場合、20バイトを失います。

Q:バッファを256バイト(たとえば)にしないでください。

Q:「メッセージ」が2つの部分に届くようにする必要がある場合は、2つのメッセージを送信するだけではどうですか?

+0

バッファは256バイト、メッセージは1024+と言うことができるので、バッファを本当に大きくするのはちょっとスマートなのでしょうか? –

+0

"なぜ2つのメッセージを送信しないのですか?" - 20バイトメッセージのパケットごとのオーバーヘッドは約300%なので、なぜですか? – Alnitak

+0

Q2:UDPが100%ではないため、パケットが失われるため、メッセージが2つの完全なメッセージに分割されても、受信が保証されません。 –

関連する問題