предоставлен байт для BeginReceive - PullRequest
0 голосов
/ 03 июля 2010

то, что делает моя программа, при первом принятии соединения, сервер отправляет данные, которые получает клиент, затем отправляет снова (размер данных не изменяется), сервер получает их, а затем отправляет обратно снова ... этот цикл продолжается ...

когда второй раз сервер получает данные int, возвращаемые endreceive ();0

, хотя я нашел решение, но я не знаю, почему это на самом деле решает проблему

Я где-то читал, что существует нечто, называемое «грязным» буфером: s

так что я сделал.

//added line
data = new byte[DataSize];

//now index works fine :s
int index = socket.endreceive(result);

ранее я повторно использовал byte[] data для отправки и получения без изменения его содержимого, отправка данных - все нули

, и это сработало:)

MSDN не помогает мне там, или я что-то пропустил? MSDN Link

Это обобщенный код

    private void OnSendCallBack(IAsyncResult result)
    {
        int id_client = (int)result.AsyncState;
        try
        {

            int index = clientInfo[id_client].client.EndSend(result);

            clientInfo[id_client].offsetSend += index;
            if (index == 0)
            {
                Console.WriteLine("Index == 0");
                return;
            }
            else if (clientInfo[id_client].offsetSend < DataSize)
            {
                clientInfo[id_client].dataToSend = DataSize - clientInfo[id_client].offsetSend;
                clientInfo[id_client].client.BeginSend(data, clientInfo[id_client].offsetSend, clientInfo[id_client].dataToSend, SocketFlags.None, RecieveCallBack, id_client);
            }
            else 
            {
                clientInfo[id_client].offsetSend = 0;
                clientInfo[id_client].dataToSend = DataSize;
                //*************************************
                data = new byte[DataSize]; // THIS IS THE PROBLEM HERE
                //*************************************
                clientInfo[id_client].client.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallBack, id_client);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Send: " + ex.Message);
        }
    }

private void RecieveCallBack(IAsyncResult result)
    {
        int id_client = (int)result.AsyncState;

        try
        {

            int index = clientInfo[id_client].client.EndReceive(result);

            //byte[] buffer = new byte[DataSize];
            //int received = clientInfo[id_client].client.Receive(buffer);

            clientInfo[id_client].offsetRec += index;
            if (index == 0)
            {
                index = clientInfo[id_client].client.EndReceive(result);
                Console.WriteLine("Index == 0");
                return;
            }
            else if (clientInfo[id_client].offsetRec < DataSize && clientInfo[id_client].offsetRec != 0)
            {
                clientInfo[id_client].dataToReceive = DataSize - clientInfo[id_client].offsetRec;
                clientInfo[id_client].client.BeginReceive(data, clientInfo[id_client].offsetRec, clientInfo[id_client].dataToReceive, SocketFlags.None, RecieveCallBack, id_client);
            }
            else
            {
                clientInfo[id_client].offsetRec = 0;
                clientInfo[id_client].dataToReceive = DataSize;

                if (clientInfo[id_client].RunNumber < RounCount)
                {
                    clientInfo[id_client].RoundTripStat.EndSample();
                    clientInfo[id_client].RoundTripStat.BeginSample(); 
                    clientInfo[id_client].client.BeginSend(data, 0, data.Length, SocketFlags.None, OnSendCallBack, id_client); 
                }

                Close(id_client);
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("Server: " + ex.Message);
        }
    }

Я предоставил код SendCallback и Receive Callback, поскольку вы можете видеть, что одна асинхронная команда ожидает одну навремя

1 Ответ

1 голос
/ 03 июля 2010

EndReceive() возвращает 0, если больше не было данных для приема, и сокет был закрыт (т. Е. Там будет больше не будет данных для приема).

Из документов, на которые вы ссылались:

Если удаленный хост закрывает соединение Socket методом Shutdown, и все доступные данные были получены, метод EndReceive завершится немедленно и вернет ноль байтов.

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

Безопасно «совместно использовать» буфер, только если вы когда-либо выполняете только одну операцию за раз, и вы убедитесь, что при записи у вас есть именно те данные, которые вы хотите, явно заданные там.

...