сокеты c # читают данные и затем отвечают - PullRequest
0 голосов
/ 21 апреля 2011

Я использую следующий код (построенный на основе ответов на мои предыдущие вопросы о SO):

public void Start()
{
    listener = new TcpListener(IPAddress.Any, 9030);
    listener.Start();
    Console.WriteLine("Listening...");
    StartAccept();
}

private void StartAccept()
{        
    listener.BeginAcceptTcpClient(HandleAsyncConnection, listener);            
}

private void HandleAsyncConnection(IAsyncResult res)
{
    StartAccept();
    TcpClient client = listener.EndAcceptTcpClient(res);

    StringBuilder sb = new StringBuilder();
    var data = new byte[client.ReceiveBufferSize];

    using (NetworkStream ns = client.GetStream())
    {
        int readCount;
        while ((readCount = ns.Read(data, 0, client.ReceiveBufferSize)) != 0)
        {
            sb.Append(Encoding.UTF8.GetString(data, 0, readCount));
        }

        // Do work

        // Test reply
        Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString());
        ns.Write(replyData, 0, replyData.Length);
        ns.Flush();
        ns.Close();
    }

    client.Close();
}

Строка «Выполнить работу» показывает, где я буду выполнять необходимую обработку для своего клиента.

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

Есть идеи, как это исправить?

Ответы [ 3 ]

1 голос
/ 21 апреля 2011

Хорошо, во-первых, вы смешиваете асинхронные вызовы (BeginAcceptTcpClient) и синхронные (Read и Write) вызовы.Это полностью убивает цель асинхронного кода.Во-вторых, может быть, поэтому ваша розетка закрывается?Выполнение операции синхронизации на асинхронном сокете.Я не уверен, но без клиентского кода это невозможно сказать.

В любом случае, это НЕ то, как вы строите асинхронный, многопользовательский сервер.реализация: http://msdn.microsoft.com/en-us/library/fx6588te.aspx

0 голосов
/ 21 апреля 2011

Вы неправильно поняли, как работает Read. Он блокируется, пока что-то не получено от другой конечной точки. Единственный раз, когда он возвращает 0, это когда другая сторона отключилась, поэтому вы продолжите чтение, пока другая сторона не отключится.

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

0 голосов
/ 21 апреля 2011

Я думаю, что вы должны использовать байт длины, чтобы выделить свой буфер. ReceiveBufferSize может вызываться несколько раз, я думаю, нет гарантии, что вы получите все в одном блоке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...