5

Javaでクライアントを作成しましたが、C#のサーバーにデータを送信したいだけです。

問題は、たとえばhelloなどのクライアントに書き込むと、最初の文字しか表示されないことです。バイト配列には要素が1つだけあります。

私のサーバーではJAVAのサーバーがすべて正常に動作するため、JAVAのクライアントは正常に動作するため、サーバー側に問題があると思います。

誰か問題がありますか?

前もって感謝します。

4

3 に答える 3

3

あなたはTCPについて間違った方法で考えています、あなたは単に一度「受信」して1つの「送信」の結果を得るのではありません。

TCPは「ストリーミング」プロトコルであり、自動的に「パケット」に分離されることはありません。1回の受信で2回の送信のデータを取得することもできます。

一般的なパターンは、1つのメッセージの前にその長さを付けることです。これにより、要求されたバイト数を取得するまで、receiveを呼び出すことができます。バッファにデータがない場合にReceiveをすぐに返すには、ソケットを非ブロッキングに設定します

このトピックに関する別の良い記事があります。

これで、ローカルネットワークに遅延がほとんどないため、提供されたコードはどちらの方法でも機能するはずです。Javaパーツが蒸気をバッファリングするかどうかを確認しましたか/手動でフラッシュできますか?

于 2012-10-28T18:44:11.833 に答える
3

Damon Gantが言ったように、TCPはストリーミングプロトコルです。独自のプロトコルを作成することをお勧めします。文字列は送信しません。些細なことをしているのなら、これが本当に最善の方法です。

通常、プロトコルヘッダーには、マジックナンバー、チェックサム、パケット本体の長さ(バイト単位)、およびプロトコルバージョンを含めます。マジックナンバーを使用すると、ストリーム内のパケットの描写が簡単になります(カスタムプロトコルストリームのデバッグに非常に役立ちます)。チェックサムがあると、正しく解析していることを確認できます。TCPプロトコルにはすでにチェックサムがあるため、チェックサムはTCPを介した整合性にはあまり役立ちません。パケット本体の長さは、パケットのすべてのバイトがあることを検出するのに役立ちます。プロトコルバージョンは、パケット本文のバイトを解釈する方法を知るのに役立ちます。

データを受信したら、すべてのバイトを別のバッファーに配置し、プロトコルヘッダーをスキャンします。ヘッダーを解析できる場合は、パケットのバイトがすべて存在することを確認してください。その場合は、パケットを解析します。不完全なパケットが見つかるか、バッファが空になるまで、このプロセスを繰り返します。

送信するパケットごとに、クラスを作成します。パケットを送信する場合は、適切なクラスを作成してシリアル化し、そのクラスのバイトの前にプロトコルヘッダーを追加します。

Javaのシリアライザーを使用することもできますが、単一のサーバーに多数のクライアントが接続している場合は、サーバーにJavaを使用したくない可能性があります。これにより、Javaシリアライザーを別の言語で実装する必要があるため、事態が困難になります。このため、通常は、パケットを手動でバイトに変換するか(面倒ですが単純です)、リフレクションを使用して独自のシリアライザーを作成する方が適切です。より大きなプロジェクトには後者をお勧めします。

于 2012-10-28T19:04:07.790 に答える
2

リスナーが正常に動作するため、問題はおそらくJava側にあります。テストアプリケーションにリスナーコードをコピーして貼り付けました。別のテストアプリケーションを作成してハローワードを送信し、それを完全に聞いたよりも。

public static  void sender()
{
  TcpClient client = new TcpClient();
  IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.2.236"), 30000);
  client.Connect(serverEndPoint);
  NetworkStream clientStream = client.GetStream();
  ASCIIEncoding encoder = new ASCIIEncoding();
  byte[] buffer = encoder.GetBytes("Hello Server!");

  clientStream.Write(buffer, 0, buffer.Length);
  clientStream.Flush();
}


Connection accepted from 192.168.2.236:22811
Recieved...
Hello Server!

ところで、これはより良いリスナーかもしれません。

public void listener()
    {
  TcpListener tcpListener = new TcpListener(IPAddress.Any, 30000);
  tcpListener.Start();

  TcpClient tcpClient = tcpListener.AcceptTcpClient();
  NetworkStream clientStream = tcpClient.GetStream();

  byte[] message = new byte[4096];
  int bytesRead;

  while (true)
  {
    bytesRead = 0;

    try
    {
      //blocks until a client sends a message
      bytesRead = clientStream.Read(message, 0, 4096);
    }
    catch
    {
      //a socket error has occured
      break;
    }

    if (bytesRead == 0)
    {
      //the client has disconnected from the server
      break;
    }

    //message has successfully been received
    ASCIIEncoding encoder = new ASCIIEncoding();
    Console.Write(encoder.GetString(message, 0, bytesRead));
  }

  tcpClient.Close();
}
于 2012-10-28T18:44:18.680 に答える