Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Программа UDP

44K
13 января 2011 года
mgelimgeli
8 / / 21.02.2009
Привет всем ,ест 1 вапрос па поводу размера буфераа

Код:
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
    Dim broadcast As IPAddress = IPAddress.Parse("217.11.160.16")
    Dim ep As New IPEndPoint(broadcast, 27015)

Try
            Do While True
                If s.Connected Then
                    Dim sendbuf(255) As Byte
                    s.Receive(sendbuf)
                      send_server(sendbuf)
                Else
                    s.Connect(ep)
                End If
               
            Loop
        Catch ex As Exception
            Console.WriteLine(ex.ToString)
            c1.Abort()
            z1.Abort()
        End Try


вот когда я создаю сенбаф размером 255 бывает что оно больше чем нада. мне надо знат заранеее какой число байтов пришло.
на тсп сокете ето делает

 
Код:
Dim sendbuf(s.Available) As Byte

прошу подскозат что писать место s.Available ?

ошибку выдает такой
System.Net.Sockets.SocketException: Сообщение, отправленное на сокет датаграмм,
было больше, чем буфер внутренних сообщений или был превышен иной сетевой параме
тр. Также возможно, что буфер для принятия сообщения был меньше, чем размер сооб
щения
44K
14 января 2011 года
mgelimgeli
8 / / 21.02.2009
добрый времени суток всем , мне надо делать программу который создает север на локальном ип и соединяется с удаленным сервером .то что принимает сервер с локальки передает на удаленный сервер и обратно .что-то вроде транспорта или как назвать хз _)))
сам написал но ест проблема знающие люди прошу помочь
Код:
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading

Module Module1
    Dim z As New ThreadStart(AddressOf receive_server)
    Dim z1 As New Thread(z)
    Dim c As New ThreadStart(AddressOf receive_Client)
    Dim c1 As New Thread(c)
    'Client
    Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
    Dim broadcast As IPAddress = IPAddress.Parse("217.11.160.16")
    Dim ep As New IPEndPoint(broadcast, 27015)
    'Server
    Private Const listenPort As Integer = 27015
    Dim listener As New UdpClient(listenPort)
    Dim serip As IPAddress = IPAddress.Parse("192.168.1.10")
    Dim groupEP As New IPEndPoint(serip, listenPort)
    Public Function Send_client(ByVal sendbuf() As Byte) As Integer
        s.SendTo(sendbuf, ep)
    End Function
    Sub receive_Client()
        Try
            Do While True
                If s.Connected Then
                    Dim sendbuf(255) As Byte
                    s.Receive(sendbuf)
                    send_server(sendbuf)
                Else
                    s.Connect(ep)
                End If
            Loop
        Catch ex As Exception
            Console.WriteLine("ошибка Client > > > " & ex.ToString)
            c1.Abort()
            z1.Abort()
        End Try
    End Sub
    Sub receive_server()
        Try
            Do While True
                Dim bytes As Byte() = listener.Receive(groupEP)
                Send_client(bytes)
            Loop
        Catch e As Exception
            Console.WriteLine("ошибка Server > > > " & e.ToString())
            c1.Abort()
            z1.Abort()
        Finally
            listener.Close()
        End Try
    End Sub
    Sub send_server(ByVal sendbuf() As Byte)
        listener.Send(sendbuf, sendbuf.Length, groupEP)
    End Sub
    Sub Main()
        Console.WriteLine("server zapushen")
        z1.Start()
        Console.WriteLine("client zapushen")
        c1.Start()
    End Sub
End Module


ошибку выдает такой

Цитата:
ошибка Client > > > System.Net.Sockets.SocketException: Сообщение, отправленное
на сокет датаграмм, было больше, чем буфер внутренних сообщений или был превышен
иной сетевой параметр. Также возможно, что буфер для принятия сообщения был мен
ьше, чем размер сообщения
в System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size,
SocketFlags socketFlags)
в System.Net.Sockets.Socket.Receive(Byte[] buffer)
в udp_mintext.Module1.receive_Client() в D:\Documents and Settings\admin\Loca
l Settings\Application Data\Temporary Projects\udp_mintext\Module1.vb:строка 29



проблема тут

 
Код:
Dim sendbuf(255) As Byte
s.Receive(sendbuf)


массив sendbuf больше чем надо .вот и вопрос что делать ? .как заранее узнать какой размер пакета пришло ?


заранее всех благодарю
278
14 января 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: mgelimgeli

 
Код:
Do While True
    ' ...
    Dim sendbuf(255) As Byte
    ' ...
 Loop




Вы выделяете буфер в каждой итерации цикла Do While True, там оперативной памяти не плохо еще? :) Для начала - выделите его один раз до входа в цикл.

Цитата: mgelimgeli

как заранее узнать какой размер пакета пришло ?



Только анализировать TCP-фреймы. Но с помощью тех средств, которыми вы пользуетесь, это сделать невозможно (да и не нужно для вашей задачи), поэтому ответ - никак. Создайте просто асинхронный сокет и ждите, пока в буфере что-то не появится. Как вариант - можно читать по одному байту.

7
14 января 2011 года
@pixo $oft
3.4K / / 20.09.2006
Вообще-то,НЯЗ,буфер живёт только в своей области,т.е. куда там до цикла–он вообще в If'е выделяется.Хотя могу и ошибаться,тогда действительно надо до цикла
(почему-то локальные переменные вспомнились)
278
14 января 2011 года
Alexander92
1.1K / / 04.08.2008
@pixo $oft, If ведь тоже внутри цикла. И потом, даже если вы правы и это локальная переменная - она ж не статическая и выделяется каждый раз заново (пусть даже в своей области). К сожалению, я не очень хорошо помню синтаксис VB, но на C++, например, в цикле такую переменную можно объявить только как static, иначе рано или поздно будет переполнение.
297
14 января 2011 года
koodeer
1.2K / / 02.05.2009
Alexander92, это ж .NET, здесь сборщик мусора сам утилизирует уже неиспользуемую память. Так что проблем нехватки памяти в данном случае не будет.


mgelimgeli, а если в Receive указать количество принимаемых байт? Не более 256. Что-нибудь изменится?

И ещё, с такими названиями переменных - z, z1, c, c1, etc - нет никакого желания смотреть ваш код. Дайте названия, сразу говорящие о том, что это.
241
15 января 2011 года
Sanila_san
1.6K / / 07.06.2005
А почему бы не создать два асинхронных сокета - один на приём, другой на передачу, и просто направлять поток от приёмника к передатчику? Не надо будет с буферами париться, только следить за тем, чтобы соединение поддерживалось, поскольку может отваливаться по таймауту. Но, как я понял, делается это уже на прикладном уровне.

UPD: Для отладки такого софта очень советую Wireshark, реально облегчает жизнь. Кстати, попробуйте поснифить им: наверняка найдёте ещё ошибки в работе, да и отладка действительно очень упростится.
44K
15 января 2011 года
mgelimgeli
8 / / 21.02.2009
привет . всем спасибо сам разобрался . сделал вот так

Код:
Sub receive_Client()
        If s.Connected = False Then
            s.Connect(ep)
        End If
        Try
            Do While True
                Dim sendbuf(8192) As Byte
                Dim n As Integer
                n = s.Receive(sendbuf)
                ReDim Preserve sendbuf(n - 1)
                 send_server(sendbuf)
            Loop
        Catch ex As Exception
            Console.WriteLine("ошибка Client > > > " & ex.ToString)
            c1.Abort()
            z1.Abort()
        End Try

    End Sub
7
15 января 2011 года
@pixo $oft
3.4K / / 20.09.2006
Таки не прислушались ко всем замечаниям.Сделайте хотя бы так
Код:
Sub receive_Client()
    If s.Connected = False Then
        s.Connect(ep)
    End If
    Try
        Dim sendbuf(8192) As Byte,n As Integer
        Do While True
            n = s.Receive(sendbuf)
            ReDim Preserve sendbuf(n - 1)
            send_server(sendbuf)
        Loop
    Catch ex As Exception
        Console.WriteLine("ошибка Client > > > " & ex.ToString)
        c1.Abort()
        z1.Abort()
    End Try
End Sub
44K
15 января 2011 года
mgelimgeli
8 / / 21.02.2009
Цитата: @pixo $oft
Таки не прислушались ко всем замечаниям.Сделайте хотя бы так
Код:
Sub receive_Client()
    If s.Connected = False Then
        s.Connect(ep)
    End If
    Try
        Dim sendbuf(8192) As Byte,n As Integer
        Do While True
            n = s.Receive(sendbuf)
            ReDim Preserve sendbuf(n - 1)
            send_server(sendbuf)
        Loop
    Catch ex As Exception
        Console.WriteLine("ошибка Client > > > " & ex.ToString)
        c1.Abort()
        z1.Abort()
    End Try
End Sub



@pixo $oft какая разница до или после цикла ? . я не спорю но вроде оно не мешать мне _)) все равно сделаю как вы сказали _)

7
15 января 2011 года
@pixo $oft
3.4K / / 20.09.2006
Во-первых,не «до и после»,а «до и в»;).Во-вторых,разницу вам уже описали выше
5
15 января 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: @pixo $oft
Таки не прислушались ко всем замечаниям.


Угу, только зачем каждый раз копировать буфер? Вот этим: ReDim Preserve.
Нужно нормально называть и объявить переменные:

 
Код:
Dim buffer(8192) As Byte
        Dim bytesReceived As Integer
        Do While True
            bytesReceived = s.Receive(buffer)
            send_server(buffer, bytesReceived)
        Loop

И соответствующим образом изменить send_server
 
Код:
Sub send_server(ByVal buffer() As Byte, ByVal bufferSize As Integer)
        listener.Send(buffer, bufferSize, groupEP)
    End Sub
44K
15 января 2011 года
mgelimgeli
8 / / 21.02.2009
Цитата: @pixo $oft
Во-первых,не «до и после»,а «до и в»;).Во-вторых,разницу вам уже описали выше



я сделал как ты сказал и прог не работает ))) так как после записи в сендбаф надо сначала создать массив битов для последующего записи а если оно не внутри то после ReDim Preserve массив становится не 8192 а становится таким как был предыдущий пакет так что по другому никак )) но все-равно сппп всеммм

44K
15 января 2011 года
mgelimgeli
8 / / 21.02.2009
Цитата: hardcase
Угу, только зачем каждый раз копировать буфер? Вот этим: ReDim Preserve.
Нужно нормально называть и объявить переменные:
 
Код:
Dim buffer(8192) As Byte
        Dim bytesReceived As Integer
        Do While True
            bytesReceived = s.Receive(buffer)
            send_server(buffer, bytesReceived)
        Loop

И соответствующим образом изменить send_server
 
Код:
Sub send_server(ByVal buffer() As Byte, ByVal bufferSize As Integer)
        listener.Send(buffer, bufferSize, groupEP)
    End Sub


если я знал какой пакет идет с удаленного хоста то у меня небыли не каких проблем _) так что надо задать максимальный и после переделать

5
15 января 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: mgelimgeli
если я знал какой пакет идет с удаленного хоста то у меня небыли не каких проблем _) так что надо задать максимальный и после переделать


Значит нужно задать максимальный и знать размер фактических данных которые в нем лежат (что я продемонстрировал).

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог