несколько send и один буффер
От: vf  
Дата: 12.01.11 19:06
Оценка:
Вопрос теоретический, можно ли использовать один буффер в нескольких send выполняющихся паралельно?
По логике, для функции send буффер константа и внутри стэк будет буффер только читать, и ничего вроде криминального нет если несколько паралельно-выполняющихся send будут отправлять один и тот же буфер. На практике, c# никаких проблем не испытывает в моем тестовом приложении. Но я не встречал примера или авторитетного источника что так делать можно или нельзя. Возможны ли здесь какие нить грабли?!

using System;
using System.Net;
using System.Net.Sockets;

namespace ReuseSocketBuffer
{
    class Program
    {
        static byte[] reciveBuffer = new byte[1024];
        static byte[] senderBuffer = new byte[1024];

        static void Main(string[] args)
        {
            var sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            listener.Bind(new IPEndPoint(IPAddress.Any, 0));
            listener.Listen(1);
            var ar1 = listener.BeginAccept(null, null);

            sender.Connect(new IPEndPoint(IPAddress.Loopback, (listener.LocalEndPoint as IPEndPoint).Port));

            var receiver = listener.EndAccept(ar1);

            receiver.BeginReceive(reciveBuffer, 0, reciveBuffer.Length, SocketFlags.None, ReceiveCallback, receiver);

            var ee = new SocketAsyncEventArgs[1024];

            senderBuffer[0] = 1;
            senderBuffer[1023] = 2;

            for (; ; )
            {
                for (int i = 0; i < ee.Length; i++)
                {
                    ee[i] = new SocketAsyncEventArgs();
                    ee[i].SetBuffer(senderBuffer, 0, senderBuffer.Length);
                }

                for (int i = 0; i < ee.Length; i++)
                    sender.SendAsync(ee[i]);
            }
        }

        static int count = 0;

        static void ReceiveCallback(IAsyncResult ar)
        {
            var receiver = ar.AsyncState as Socket;

            int received = receiver.EndReceive(ar);
            if (received == 1024)
            {
                Console.Write("\r{0}", count++);

                if (reciveBuffer[0] != 1 || reciveBuffer[1023] != 2)
                    throw new Exception();

                receiver.BeginReceive(reciveBuffer, 0, reciveBuffer.Length, SocketFlags.None, ReceiveCallback, receiver);
            }
        }
    }
}
Re: несколько send и один буффер
От: Аноним  
Дата: 13.01.11 06:43
Оценка:
Во первых, твой код никак не параллельно посылает, а вполне себе последовательно. Ну, допустим, ты будешь из разных потоков слать. В принципе, все будет ок — никаких исключений не будет, один и тот же буфер можно в разные операции ВВ засунуть, главное, чтобы его не удалили до завершения всех операций. Но СМЫСЛ всего этого???
Re[2]: несколько send и один буффер
От: Michael Chelnokov Украина  
Дата: 13.01.11 10:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но СМЫСЛ всего этого???


Например, в буфере смикшированный звук от нескольких участников конференции, который надо отослать им всем.
Re[2]: несколько send и один буффер
От: vf  
Дата: 13.01.11 11:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Во первых, твой код никак не параллельно посылает, а вполне себе последовательно. Ну, допустим, ты будешь из разных потоков слать.


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

А>В принципе, все будет ок — никаких исключений не будет, один и тот же буфер можно в разные операции ВВ засунуть, главное, чтобы его не удалили до завершения всех операций. Но СМЫСЛ всего этого???


В моем случае, для udp очень удобно (tcp я с горяча проверил)
Re[3]: несколько send и один буффер
От: Аноним  
Дата: 14.01.11 06:40
Оценка:
А>>Во первых, твой код никак не параллельно посылает, а вполне себе последовательно. Ну, допустим, ты будешь из разных потоков слать.
vf>Я использую SendAsync, вероятность того что запаралелится очень высока.

Примерно 0.0

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

Другими словами: данные уйдут в сеть именно в том порядке, в каком ты вызвал свои SendAsync. В этом смысле, нет никакой разницы вызывать в цикле SendAsync или блокирующий Send.
Re[3]: несколько send и один буффер
От: Аноним  
Дата: 14.01.11 06:50
Оценка:
А>>Но СМЫСЛ всего этого???
MC>Например, в буфере смикшированный звук от нескольких участников конференции, который надо отослать им всем.
Я хотел узнать СМЫСЛ приведенного кода. Очевидно, это просто какая то мусорилка ( для стресс тестов? ). Но какая то очень уж изощреная ))
Re[4]: несколько send и один буффер
От: vf  
Дата: 14.01.11 21:41
Оценка:
А>В твоем случае единственное, что может произойти этакого асинхронного — это приход нотификаций о завершении операций ВВ не в том порядке, в каком эти операции были иницированый.
А>Другими словами: данные уйдут в сеть именно в том порядке, в каком ты вызвал свои SendAsync.

Согласен, и сомнений это не вызывает, причем здесь это?! Я хотел проверить как tcp/ip стек относиться к тому что используется один и тот же буфер для нескольких одновременно выполняющихся Send, к примеру SocketAsyncEventArgs нельзя использовать подобным образом. В моем примере SendAsync может завершиться до того как данные SocketAsyncEventArgs будут обработаны, и будет вызван еще один SendAsync таким образом возникнет та ситуация которую я проверял — один и тот же буфер в стеке.

А>В этом смысле, нет никакой разницы вызывать в цикле SendAsync или блокирующий Send.


Заменив на Send ничего подобного я получить не смогу.
Re[4]: несколько send и один буффер
От: vf  
Дата: 14.01.11 21:47
Оценка:
А>>>Но СМЫСЛ всего этого???
MC>>Например, в буфере смикшированный звук от нескольких участников конференции, который надо отослать им всем.
А>Я хотел узнать СМЫСЛ приведенного кода. Очевидно, это просто какая то мусорилка ( для стресс тестов? ). Но какая то очень уж изощреная ))

Из первого поста>На практике, c# никаких проблем не испытывает в моем тестовом приложении.

Я имел ввиду что это приложения создано для проверки того о чем я спрашивал.
Re[5]: несколько send и один буффер
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.01.11 08:57
Оценка:
Здравствуйте, vf, Вы писали:

vf>Согласен, и сомнений это не вызывает, причем здесь это?! Я хотел проверить как tcp/ip стек относиться к тому что используется один и тот же буфер для нескольких одновременно выполняющихся Send,


В общем случае плохо относится — данные перемешаются.
The God is real, unless declared integer.
Re[6]: несколько send и один буффер
От: vf  
Дата: 15.01.11 09:46
Оценка:
Здравствуйте, netch80, Вы писали:

vf>>Согласен, и сомнений это не вызывает, причем здесь это?! Я хотел проверить как tcp/ip стек относиться к тому что используется один и тот же буфер для нескольких одновременно выполняющихся Send,


N>В общем случае плохо относится — данные перемешаются.


Как перемешаются, можно пример? Что подразумевается под общим случаем, под .нет, виндой проблем не видно, в других осях с чем-то сталкивался?
Re[7]: несколько send и один буффер
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.01.11 07:47
Оценка:
Здравствуйте, vf, Вы писали:

vf>>>Согласен, и сомнений это не вызывает, причем здесь это?! Я хотел проверить как tcp/ip стек относиться к тому что используется один и тот же буфер для нескольких одновременно выполняющихся Send,

N>>В общем случае плохо относится — данные перемешаются.
vf>Как перемешаются, можно пример?

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

vf> Что подразумевается под общим случаем, под .нет, виндой проблем не видно, в других осях с чем-то сталкивался?


Видимо, в дотнете копируется содержимое пользовательского буфера. Иначе я это объяснить не могу.
Практически везде в остальных местах этот фокус не пройдёт.
The God is real, unless declared integer.
Re: несколько send и один буффер
От: ononim  
Дата: 17.01.11 16:38
Оценка: +1
vf>Вопрос теоретический, можно ли использовать один буффер в нескольких send выполняющихся паралельно?
vf>По логике, для функции send буффер константа и внутри стэк будет буффер только читать, и ничего вроде криминального нет если несколько паралельно-выполняющихся send будут отправлять один и тот же буфер.
Ну если в то время пока они будут отправлять буфер никто данные в нем не будет модифицировать — все будет хорошо.
Как много веселых ребят, и все делают велосипед...
Re[2]: несколько send и один буффер
От: Pavel Dvorkin Россия  
Дата: 17.01.11 16:47
Оценка:
Здравствуйте, ononim, Вы писали:

vf>>Вопрос теоретический, можно ли использовать один буффер в нескольких send выполняющихся паралельно?

vf>>По логике, для функции send буффер константа и внутри стэк будет буффер только читать, и ничего вроде криминального нет если несколько паралельно-выполняющихся send будут отправлять один и тот же буфер.
O>Ну если в то время пока они будут отправлять буфер никто данные в нем не будет модифицировать — все будет хорошо.

Хорошо-то хорошо, да вот такой вопрос. Какой там тип в/в при работе с сокетом в ядре используется : прямой или буферизованый ? Если буферизованный, то точно ничего интересного не будет, так как под каждый send будет делаться копия буфера в АП ядра. А вот если прямой — гм... Ядро при этом фиксирует буфер в физической памяти. А если он уже зафиксирован ? Что будет — возьмут зафиксированный уже буфер или будут ждать, пока его расфиксируют ?
With best regards
Pavel Dvorkin
Re[3]: несколько send и один буффер
От: ononim  
Дата: 17.01.11 18:25
Оценка: 20 (1)
vf>>>Вопрос теоретический, можно ли использовать один буффер в нескольких send выполняющихся паралельно?
vf>>>По логике, для функции send буффер константа и внутри стэк будет буффер только читать, и ничего вроде криминального нет если несколько паралельно-выполняющихся send будут отправлять один и тот же буфер.
O>>Ну если в то время пока они будут отправлять буфер никто данные в нем не будет модифицировать — все будет хорошо.
PD>Хорошо-то хорошо, да вот такой вопрос. Какой там тип в/в при работе с сокетом в ядре используется : прямой или буферизованый ? Если буферизованный, то точно ничего интересного не будет, так как под каждый send будет делаться копия буфера в АП ядра. А вот если прямой — гм... Ядро при этом фиксирует буфер в физической памяти. А если он уже зафиксирован ? Что будет — возьмут зафиксированный уже буфер или будут ждать, пока его расфиксируют ?

MmProbeAndLockPages can be called multiple times for the same page. Each successful call to MmProbeAndLockPages for an MDL must be matched by a call to MmUnlockPages for the same MDL.

Как много веселых ребят, и все делают велосипед...
Re[3]: несколько send и один буффер
От: Аноним  
Дата: 17.01.11 20:33
Оценка: -1
PD>Хорошо-то хорошо, да вот такой вопрос. Какой там тип в/в при работе с сокетом в ядре используется : прямой или буферизованый ?

Какгрицца, слышал звон...
Re[8]: несколько send и один буффер
От: vf  
Дата: 18.01.11 08:31
Оценка:
Здравствуйте, netch80, Вы писали:

N>Вместо одних данных будут прочтены другие, записанные для другого send().

N>Реальное чтение этих данных из буфера в оптимально написанном коде происходит не в момент входа в send(), а когда потребуется следующая порция для передачи уже в сокетные буфера.

Нет, данные в буффере я не планирую менять пока все send'ы не завершаться. Тем более планируется SendAsync...

vf>> Что подразумевается под общим случаем, под .нет, виндой проблем не видно, в других осях с чем-то сталкивался?

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

Нет, не настолько там все не оптимально
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.