Одновременная отправка данных с обоих сторон соединения

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Создатель
Постоялец
Постоялец
 
Сообщения: 422
Зарегистрирован: 21.04.2004 (Ср) 3:32
Откуда: Новосибирск

Одновременная отправка данных с обоих сторон соединения

Сообщение Создатель » 26.02.2006 (Вс) 8:57

Так вот, что будет то при этом? Если одна сторона передает данные, другая их получает и в то же время отправляет свои...

А то у меня тут интересная фигня получается: если только один клиент передает данные, другой только слушает, их общение как-то "подвисает". Как только начинает передавать данные и сервер - все становится в норме, байты летят как надо...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 26.02.2006 (Вс) 19:47

Всё должно быть в порядке и при односторонней, и при двусторонней передаче. Т.ч. глюки где-то в твоём коде.
Не будешь так добр его показать?
Изображение

Создатель
Постоялец
Постоялец
 
Сообщения: 422
Зарегистрирован: 21.04.2004 (Ср) 3:32
Откуда: Новосибирск

Сообщение Создатель » 27.02.2006 (Пн) 15:57

Попробую показать :)

Вот куски кода, отвечающие непосредственно за соединение и обмен данными:
(Опущены различные обработчики ошибок и т.д.)

Сервер:

Код: Выделить всё
'Создаем сокет

(изначально создается конечная точка ipEndPoint)

        Dim SListener As Socket = New Socket(AddressFamily.InterNetwork,
        SocketType.Stream, ProtocolType.Tcp)

        SListener.Bind(ipEndPoint)
        SListener.Listen(20)


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

Код: Выделить всё
Do While True

Dim hSock As Socket = SListener.Accept
AddClient(hSock)

Loop


Процедура AddClient создает новый объект клиента, передавая ему ссылку на полученный сокет hSock

Код: Выделить всё
Public Sub New(ByVal idValue As Integer, ByVal socketValue As Socket)
        mId = idValue
        mSocket = socketValue

(В конструкторе класса создается новый поток, отвечающий за взаимодействие с клиентом)

        mThread = New Thread(AddressOf Run)
        mThread.Start()
End Sub


Public Sub Run()

            mSocketStream = New NetworkStream(mSocket)
            mReader = New BinaryReader(mSocketStream)
            mWriter = New BinaryWriter(mSocketStream)


While True

                mGetString = mReader.ReadString

                If mGetString = Commands.Disconnect Then
                    RaiseEvent DisconnectEvent(Me)
                    Exit Sub
                End If

                RaiseEvent GetStringEvent(Me, mGetString)



End While


End Sub


Public Sub SendString(ByVal stringValue As String)

mWriter.Write(stringValue)
             
End Sub



Так, с сервером вроде все. Теперь клиент:


Код: Выделить всё
Public Sub New(ByVal IpAddrValue As String)
        mIp = IpAddrValue

        'запуск отдельного потока для регистрации клиента
        mRegistrationThread = New Thread(AddressOf Registration)
        mRegistrationThread.Start()

    End Sub


Public Sub Registration()
        'процедура регистрации клиента в системе сервера

            mTcpClient = New TcpClient
            mTcpClient.Connect(mIp, 38093)

            mNetworkStream = mTcpClient.GetStream

            mWriter = New BinaryWriter(mNetworkStream)
            mReader = New BinaryReader(mNetworkStream)

            Run()
End Sub



Public Sub Run()


           Do While True

                message = mReader.ReadString

                If message = Commands.Disconnect Then
                    RaiseEvent ConnectionFalseEvent(Me)
                    Exit Sub
                End If

                RaiseEvent GetStringEvent(message)

            Loop
End Sub



Public Sub SendString(ByVal stringValue As String)

                mWriter.Write(stringValue)

End Sub



ЗЫ: Заторможенность проявляется непосредственно в передаче данных (смотрел в файрволе)

Создатель
Постоялец
Постоялец
 
Сообщения: 422
Зарегистрирован: 21.04.2004 (Ср) 3:32
Откуда: Новосибирск

Сообщение Создатель » 27.02.2006 (Пн) 16:33

Да, может так все станет понятней. Вот пример приложения написанного с помощью этих классов. Если есть желание, можно проверить (только проверять обязательно на двух разных компах, на одном и том же все в норме).
Запустить сервер на одном и клиент на другом и поэкспериментировать с галочкой "отправлять данные". Сначала пусть только клиент отправляет, потом вместе. Если наблюдать за кол-вом принятых сообщений разница заметна.
Вложения
Копия Заторможенность.rar
(45.7 Кб) Скачиваний: 69

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 03.03.2006 (Пт) 14:27

Проверил. Разницы в средней скорости нет: в минуту проходит ~3850 сообщений в обоих случаях.
Если передача идёт только в одну сторону, то задержка между обновлениями -- около четверти секунды.
Если эти четвертьсекундные задержки и составляют всю проблему, то думаю, ничего с этим не сделать: это похоже на фичу TCP (буферизация данных перед отправкой).
Изображение

Создатель
Постоялец
Постоялец
 
Сообщения: 422
Зарегистрирован: 21.04.2004 (Ср) 3:32
Откуда: Новосибирск

Сообщение Создатель » 03.03.2006 (Пт) 18:23

Спасиб за помощь. Вот только одно, выходит при одновременной отправке с обеих сторон, буферизация не происходит?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 03.03.2006 (Пт) 19:13

Ну, ты представляешь себе, как работает TCP? :-)

Каждая сторона шлёт подтверждения о принятых пакетах.
Если в таком пакете-подтверждении данных нет совсем, значит, 64 байта трафика израсходованы впустую.

Поэтому она, очевидно, ждёт, не удастся ли ей наполнить пакет с подтверждением настоящими данными. Как только такой пакет наполняется, он немедленно отсылается; иначе он (через четверть секунды) так и уходит пустым.

Естественно, всё это спекуляция. Фактически всё может быть реализовано совсем и не так. Но такая реализация вполне правдоподобна.
Изображение


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 112

    TopList  
cron