Создаю сокет программно и не получается

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
XairOn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 19.07.2004 (Пн) 20:20
Откуда: Irkutsk region

Создаю сокет программно и не получается

Сообщение XairOn » 22.09.2005 (Чт) 18:05

Здравствуйте господа, понимаю что вопрос задан не совсем корректно, но думаю вы поймёте в чем моя проблема. Пытаюсь реализовать некоторые функции WinSock'а без использования контрола, т.е. из wsock32.dll и почему-то когда дело доходит до приёма данных прога моя рушится, вернее сначала начинает жутко гнать, а потом рушится. Мне нужно по протоколу UDP (следовательно без установки соединения). Вобщем вот мой код, поглядите пожалуйста, что там не так... почему глючит:
Код: Выделить всё

'Module

Public Const MIN_SOCKETS_REQD As Long = 1
Public Const WS_VERSION_REQD As Long = &H101
Public Const WS_VERSION_MAJOR As Long = WS_VERSION_REQD \ &H100 And &HFF&
Public Const WS_VERSION_MINOR As Long = WS_VERSION_REQD And &HFF&
Public Const MAX_WSADescription = 256
Public Const MAX_WSASYSStatus = 128
Public Const AF_INET = 2
Public Const SOCK_DGRAM As Long = 2
Public Const INVALID_SOCKET = -1
Public Const SOCKET_ERROR = -1
Public Const INADDR_ANY As Long = &H0
Public Const MSG_PEEK  As Long = &H2
Public Const GWL_WNDPROC = (-4)
Public Const WINSOCKMSG = 1025
Public Const WM_USER As Long = &H400
Public Const WSA_NETEVENT = WM_USER + 10
Public Const FD_READ As Long = &H1&
Public Const WM_APP As Long = 32768
Public Const RESOLVE_MESSAGE As Long = WM_APP
Public Const SOCKET_MESSAGE  As Long = WM_APP + 1

Public Type WSAData
    wVersion As Integer
    wHighVersion As Integer
    szDescription(0 To MAX_WSADescription) As Byte
    szSystemStatus(0 To MAX_WSASYSStatus) As Byte
    wMaxSockets As Integer
    wMaxUDPDG As Integer
    dwVendorInfo As Long
End Type

Public Type sockaddr
    sin_family As Integer
    sin_port As Integer
    sin_addr As Long
    sin_zero As String * 8
End Type

Public Declare Function WSAStartup Lib "wsock32" (ByVal wVersionRequired As Long, lpWSADATA As WSAData) As Long
Public Declare Function WSACleanup Lib "wsock32" () As Long
Public Declare Function socket Lib "wsock32.dll" (ByVal af As Long, ByVal s_type As Long, ByVal protocol As Long) As Long
Public Declare Function htons Lib "wsock32.dll" (ByVal hostshort As Long) As Integer
Public Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) As Long
Public Declare Function bind Lib "wsock32" (ByVal socket As Long, addr As sockaddr, ByVal namelen As Long) As Long
Public Declare Function closesocket Lib "wsock32.dll" (ByVal s As Long) As Long
Public Declare Function Connect Lib "wsock32.dll" Alias "connect" (ByVal s As Long, addr As sockaddr, ByVal namelen As Long) As Long
Public Declare Function sendto Lib "ws2_32.dll" (ByVal s As Long, ByVal buf As String, ByVal lLen As Long, ByVal flags As Long, ByRef toa As sockaddr, ByVal tolen As Long) As Long
Public Declare Function recvfrom Lib "ws2_32.dll" (ByVal s As Long, ByVal buf As String, ByVal lLen As Long, ByVal flags As Long, ByRef from As sockaddr, ByRef fromlen As Long) As Long
Public Declare Function WSAAsyncSelect Lib "wsock32.dll" (ByVal s As Long, ByVal hwnd As Long, ByVal wMsg As Long, ByVal lEvent As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Dim PrevProc As Long

Public Sub HookForm(F As Form)
    PrevProc = SetWindowLong(F.hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub UnHookForm(F As Form)
    If PrevProc <> 0 Then
        SetWindowLong F.hwnd, GWL_WNDPROC, PrevProc
        PrevProc = 0
    End If
End Sub

Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If uMsg = SOCKET_MESSAGE Then
        Debug.Print "Сработало 1"
        Sleep 500
        Form1.rcv
        Debug.Print "Сработало 2"
        Sleep 500
    Else
        WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
    End If
End Function

А вот код формы (на форме 1 текстбокс и одна кнопка):
Код: Выделить всё

Dim sc As Long, dt As WSAData, ws As sockaddr, bufer As String, bufer2 As String
Dim p As Long

Private Sub Command1_Click()
    If WSAStartup(WS_VERSION_REQD, dt) <> 0 Then MsgBox "Ошибка инициализации сокета"
    sc = socket(AF_INET, SOCK_DGRAM, 0)
    If sc = INVALID_SOCKET Then MsgBox "Ошибка создания сокета"
    ws.sin_family = AF_INET
    ws.sin_port = 0
    ws.sin_addr = INADDR_ANY
    If bind(sc, ws, Len(ws)) = SOCKET_ERROR Then
        closesocket sc
        MsgBox "Ошибка в бинде :("
    End If
    WSAAsyncSelect sc, Me.hwnd, SOCKET_MESSAGE, FD_READ
    bufer = "Тестовая строка"
    ws.sin_family = AF_INET
    ws.sin_port = htons(<номер порта>)
    ws.sin_addr = inet_addr("192.168.ХХХ.ХХХ")
    sendto sc, bufer, Len(bufer), 0&, ws, Len(ws)
End Sub

Private Sub Form_Load()
    HookForm Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
    UnHookForm Me
    closesocket sc
    WSACleanup
End Sub

Public Sub rcv()
    recvfrom sc, bufer2, 280, MSG_PEEK, ws, Len(ws) 'эта строка вызывает у меня много загадок :) ну хотя не так уж и много, вобщем где-то тут прога виснет, но ПОЧЕМУ, а может это и раньше происходит но до этого момента она доходит.
    Sleep 1000
    Debug.Print "Буфер = " & bufer2
End Sub

XairOn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 19.07.2004 (Пн) 20:20
Откуда: Irkutsk region

Сообщение XairOn » 23.09.2005 (Пт) 7:58

Ну подскажите, хотя с сабклассингом всё нормально здесь?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.09.2005 (Пт) 9:31

На первый взгляд правильно.
А почему ты буфер не резервируешь?
Lasciate ogni speranza, voi ch'entrate.

XairOn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 19.07.2004 (Пн) 20:20
Откуда: Irkutsk region

Сообщение XairOn » 23.09.2005 (Пт) 10:34

alibek писал(а):На первый взгляд правильно.
А почему ты буфер не резервируешь?

В исправленном варианте у меня такое изменение:
Код: Выделить всё
{процедура приёма данных rcv}
    lenBuf = GetBufferLenUDP
    Debug.Print "Длинна буфера: " & lenBuf
    p = recvfrom(sc, bufer2, lenBuf, 0&, ws2, Len(ws2))
    ...........................................................................
{конец}
Private Function GetBufferLenUDP() As Long
    Dim lngResult As Long
    Dim lngBuffer As Long
   
    lngResult = ioctlsocket(sc, FIONREAD, lngBuffer)

    If lngResult = SOCKET_ERROR Then
        GetBufferLenUDP = 0
    Else
        GetBufferLenUDP = lngBuffer
    End If
End Function

Но всё равно почему-то не работает (
Кстати догадался наконец-то (самому смешно и стыдно) поглядеть на код ошибки, оказалось что это: "10014 - Слишком малое значение параметра, определяющего размер буфера для приема данных". Так и появилась функция GetBufferLenUDP, она всегда возвращает 256, но всё равно почему-то не работает прога.

XairOn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 19.07.2004 (Пн) 20:20
Откуда: Irkutsk region

Сообщение XairOn » 23.09.2005 (Пт) 18:49

Решил выложить исходник того, что у меня получилось, может быть так, наглядно станет легче разобраться в чем проблема. Помогите плиз. Сам справиться не могу.
Вложения
socket UDP.rar
Вот то что у меня получилось, но на приёме данных прога загибается :( причину установить пока не удётся, надеюсь вы поможете!!!
(3.03 Кб) Скачиваний: 30

XairOn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 19.07.2004 (Пн) 20:20
Откуда: Irkutsk region

Сообщение XairOn » 25.09.2005 (Вс) 16:39

Ну что??? Никто не знает что ли???

XairOn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 19.07.2004 (Пн) 20:20
Откуда: Irkutsk region

Сообщение XairOn » 26.09.2005 (Пн) 10:07

Хорошо, постараюсь поконкретнее спросить. Вобщем я попробовал снифером посмотреть, что там моя прога делает. Вобщем отрпавка сообщения происходит как положено, ответ тоже приходит, но вот тут как раз моя прога и загибается с ошибкой 10014 - мало места в принимающем буфере. В снифере я посмотрел на размер пакета, он равен 299 байт, моя функция почему-то выделяла 267 байт. Я попробовал указать размер явно, без всяких функций. Размер выделенный мной был больше пришедшего пакета, но почему-то вылетела та же самая ошибка 10014... Разъясните хотя бы этот момент, что этому recvto ещё надо!?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 26.09.2005 (Пн) 10:13

Ты буфер не задаешь.
Перед
p = recvfrom(sc, bufer2, lenBuf, 0&, ws2, Len(ws2))
укажи:
buffer2 = String$(lenBuf, 0)
Lasciate ogni speranza, voi ch'entrate.

XairOn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 324
Зарегистрирован: 19.07.2004 (Пн) 20:20
Откуда: Irkutsk region

Сообщение XairOn » 26.09.2005 (Пн) 12:22

2 alibek, спасибо тебе... выручил, как говорится ларчик просто открывался, но я вот что-то не догадался так сделать, хотя мысль была, но я почему-то был уверен, что дело совсем не в этом.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 26.09.2005 (Пн) 12:28

Я тут именно об этом и говорил.
Lasciate ogni speranza, voi ch'entrate.


Вернуться в Visual Basic 1–6

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

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

    TopList