6

以前に書いたものを少し改善しようとしています。ここで、データの受信に問題が発生しました。指定されたポートでリッスンしているプログラムに tcpClient を使用して文字列を送信するために使用するプログラムがあります。正常に動作するので、もう一度データを転送することにしました

public static void receiveThread()
{
    while (true)
    {
        TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
        tcpListener.Start();

        Console.WriteLine("Waiting for connection...");

        TcpClient tcpClient = tcpListener.AcceptTcpClient();

        Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint);

        while (!(tcpClient.Client.Poll(20, SelectMode.SelectRead)))
        {
            NetworkStream networkStream = tcpClient.GetStream();
            StreamReader streamReader = new StreamReader(networkStream);

            data = streamReader.ReadLine();

            if (data != null)
            {
                Console.WriteLine("Received data: {0}", data);
                send(data); // Here Im using send Method
            }
        }
        Console.WriteLine("Dissconnected...\n");
        tcpListener.Stop();
    }
}

/// <summary>
/// Sending data
/// </summary>
/// <param name="data">Data to send</param>
public static void send(string data)
{
    TcpClient tcpClient = new TcpClient();
    try
    {
        tcpClient.Connect(ipAddress, sendPort);
        Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint);
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
    if (tcpClient.Connected)
    {
        NetworkStream networkStream = tcpClient.GetStream();
        StreamWriter streamWriter = new StreamWriter(networkStream);
        Console.WriteLine("Messege {0} to {1}", data, tcpClient.Client.RemoteEndPoint);
        streamWriter.WriteLine(data);
        streamWriter.Flush();
        tcpClient.Close();
    }
}

正常に動作することもありますが、より多くの場合、それをレシーバーと呼び、送信しようとしているものを取得できません。そして、私はそれの何が悪いのか本当にわかりません。send メソッドに問題があるようです。これはレシーバー出力の例です

Waiting for connection...
Connected with 127.0.0.1:52449
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52450
Received data: qweqwe
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52451
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52452
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52453
Received data: zxczx
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52454
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52455
Received data: aasd
Dissconnected...

Waiting for connection...
Connected with 127.0.0.1:52457
Received data: www
Dissconnected...
4

2 に答える 2

6

ここでいくつかの問題:

  1. StreamReader4kBのバッファがあり、への最初の呼び出しで可能な限り多くを読み取ろうとしますReadLine()。その結果、StreamReaderにデータがあり、すでに読み取られているために使用可能なデータがなくなったときにPoll()に入る可能性があります。
  2. Poll()マイクロ秒かかります。を呼び出す前にデータが存在しない限り、着信データを0.02ms待機するとfalseが返される可能性がありますPoll()
  3. 反復ごとに新しいStreamReaderを作成します。これにより、前の反復で既に読み取られたデータが破棄される可能性があります。

行を読み取るだけで、タイムアウトとを必要とするStreamReader場合は、次のようにします。

delegate string ReadLineDelegate ();
...
using (NetworkStream networkStream = tcpClient.GetStream()) {
    StreamReader reader = new StreamReader(networkStream);
    ReadLineDelegate rl = new ReadLineDelegate (reader.ReadLine);
    while (true) {
        IAsyncResult ares = rl.BeginInvoke (null, null);
        if (ares.AsyncWaitHandle.WaitOne (100) == false)
            break; // stop after waiting 100ms
        string str = rl.EndInvoke (ares);
        if (str != null) {
            Console.WriteLine ("Received: {0}", str);
            send (str);
        } 
    }
}
于 2009-12-03T01:00:16.133 に答える
1

ゴーストを追跡する前に、データが実際にストリーム上に存在することを確認してください。ALWAYS データがある場合、問題にアプローチできますが、論理的に見ると、ストリームが無効になっているか、データがまったくないように見えます。

于 2009-12-03T00:12:04.593 に答える