Получение и отправка данных в C # - PullRequest
6 голосов
/ 03 декабря 2009

Я все еще пытаюсь немного улучшить то, что написал раньше. Теперь я столкнулся с проблемой получения данных. У меня есть программа, которую я использую для отправки строки с помощью 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();
    }
}

Иногда это работает нормально, но чаще, давайте назовем это получателем, не могу получить то, что я пытаюсь отправить. И я действительно не знаю, что с ним не так. Похоже, может быть проблема с методом отправки. Вот пример вывода приемников

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...

Ответы [ 2 ]

6 голосов
/ 03 декабря 2009

Несколько проблем здесь:

  1. StreamReader имеет буфер 4 КБ и будет пытаться читать как можно больше при первом вызове ReadLine(). В результате вы можете получить данные в StreamReader и перейти к опросу (), если больше нет доступных данных, поскольку они уже прочитаны.
  2. Poll() занимает микросекунды. Ожидание 0,02 мс входящих данных, скорее всего, вернет ложь, если только данные не находятся перед вызовом 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);
        } 
    }
}
1 голос
/ 03 декабря 2009

Убедитесь, что данные действительно существуют в потоке, прежде чем гоняться за призраками. Если есть ВСЕГДА данные, мы можем подойти к проблеме, однако, глядя на это логически, кажется, что поток либо обнуляется, либо на нем просто нет данных.

...