Спасибо, Павел, это уже нечто близкое к тому, что я ищу . Есть только некоторые вопросы, так как я на .NET еще не перешел. Так вот:
Я сам программно должен открыть порт, или это будет делаться автоматически? И если программно, но не подкините примерчик на VB (или ссылочку)?
IP-адрес (мой) - это тот, что назначил мне провайдер? Его, выходит, надо будет выяснять программно. Как это сделать на классическом VB? Дело в том, что прогу могут юзать как на Dial-up, так и по выделенке (я заранее узнать это не могу), а в колошу садиться не охота.
Я ведь знал, что есть простое решение! Огромное спасибо всем, ребята, особенно GSerg и Павлу!
Ситуация разруливается следующим образом: действительно, все данные можно получить из Winsock, но он даст те данные, которые были при загрузке формы, то есть - его собственной загрузке (разумеется, IP - 127.0.0.1). Поэтому нужно мутить массив. Скажем, на форме разместить Winsock1(0), а когда понадобится PORT-режим, смело запускаем код (разумеется, вы уже в инете):
Load Winsock1(1) 'добавляем экземпляр
Winsock1(1).LocalPort = 8521 'открываем порт
sMyIP=Winsock(1).LocalIP 'получаем локальный IP
Далее можно подумать об лучшей реализации алгоритма (как обработать полученные данные), но это уже не суть как важно. Все прочее лежит на блюдечке .
Правда смущает вот что - команда LocalPort действительно открывает порт, или же только привязывает сокет к этому порту (правда, мне кажется что в данном случае это - одно и то же)? Жаль пока проверить возможности нет, хост заблочен. Нужно трезвонить заказчику и выяснять, в чем дело .
Зачем мутить массив, GSerg, я уже объяснял - чтобы узнать свой IP. С пеной у рта доказывать не буду, что этот вариант единственный и правильный. Но если ты загрузил прогу до того как подключился к инету, скорее всего, твой IP будет равняться 127.0.0.1 . Разумеется, я не упускаю такого поворота, что если ты коннектишься с сервером, нужный локальный IP ты и так получаешь автоматически (а прочитать его из LocalIP - не составит труда), и второй экземпляр создавать уже не нужно. Но этого я не проверял, просто гипотеза.
Скверно то, что проверить теорию пока не удастся. Я занимаюсь этим вопросом сейчас, так как появилось относительно свободное время. Меня данная проблема почти два года за горло держит, а каждый раз наряжаться шаманом и бить в бубен надоело. Хочу найти нормальное решение.
Момент не ясен.
Наш локальный IP нам для чего?
А по мне - так как раз ясен. Павел объяснил, что комманде PORT в качестве параметра надо передавать свой IP + номер открытого порта. Лично для меня здесь все ясно и понятно.
А теперь, поскольку вы, GSerg, говорите, что ни за какие коврижки команда LocalPort не откроет заветную дверцу, то вопрос мой будет вполне очевидным:
КАК, ради всего святого, можно открыть порт на своем компе программно?! Заранее благодарен за ответ.
Сергей...
Пожалуйста, сделай одну вещь...
Прочитай мануал по основам сетей, чтобы получить картину, а не пазл...
Тебе нафиг не нужен твой IP-адрес.
Тебе нафиг не нужен твой порт.
Ты соединяешься с сервером. Ты шлёшь ему команду "USER anonymous" & vbCrLf (ты ведь не забываешь ставить vbCrLf после каждой посланной строки, правда?). Потом "PASS mail@server.com" & vbCrLf. Потом "TYPE A" & vbCrLf. Потом "PASV" & vbCrLf. И вот на эту команду PASV сервер тебе высылает IP-адрес и порт, на который ты теперь должен коннектиться вторым винсоком.
Это же так просто.
Поиграйся.
Скопируй в текстовый файл и переименуй его в Form1.frm
VERSION 5.00
Object = "{248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0"; "MSWINSCK.OCX"
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 6840
ClientLeft = 60
ClientTop = 345
ClientWidth = 9645
LinkTopic = "Form1"
ScaleHeight = 6840
ScaleWidth = 9645
StartUpPosition = 3 'Windows Default
Begin VB.TextBox txtCommand
Height = 375
Left = 240
TabIndex = 1
Top = 6120
Width = 9255
End
Begin VB.TextBox txtLog
Height = 5775
Left = 240
MultiLine = -1 'True
ScrollBars = 2 'Vertical
TabIndex = 0
Top = 120
Width = 9255
End
Begin MSWinsockLib.Winsock wskReceiver
Left = 2520
Top = 120
_ExtentX = 741
_ExtentY = 741
_Version = 393216
End
Begin MSWinsockLib.Winsock wskSender
Left = 840
Top = 120
_ExtentX = 741
_ExtentY = 741
_Version = 393216
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Sub Form_Load()
txtCommand.Enabled = False
txtLog.Locked = True
wskSender.Connect "ftp.dell.com", 21
End Sub
Private Sub Form_Unload(Cancel As Integer)
If wskSender.State <> sckClosed Then wskSender.Close
End Sub
Private Sub txtCommand_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
txtLog.Text = txtLog.Text & "Me: " & txtCommand.Text & vbNewLine
wskSender.SendData txtCommand.Text & vbCrLf
txtCommand.Text = vbNullString
End If
End Sub
Private Sub wskSender_Close()
wskSender.Close
End Sub
Private Sub wskSender_Connect()
txtLog.Text = txtLog.Text & "Connected." & vbNewLine
txtCommand.Enabled = True
txtCommand.SetFocus
End Sub
Private Sub wskSender_DataArrival(ByVal bytesTotal As Long)
Dim s As String
wskSender.GetData s, vbString
txtLog.Text = txtLog.Text & s & vbNewLine
End Sub
Private Sub wskSender_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
txtLog.Text = txtLog.Text & Description
wskSender.Close
End Sub
В пассивном режиме - да, PASV и никаких проблем. В активном - ты сам открываешь у себя порт и отправляешь серверу номер порта и IP. Возможны оба варианта.
PORT. Команда назначает адрес и порт хоста, который будет использоваться как активный участник соединения по каналу передачи данных. Аргументами команды являются 32-битный IP адрес и 16-битный номер порта соединения. Эти значения разбиты на шесть 8-битных полей и представлены в десятичном виде: h1, h2, h3, h4, p1, p2, где hN - байты адреса (от старшего к младшему), а pN - байты порта (от старшего к младшему).
PASV. Эта команда отправляется модулю, который будет играть пассивную роль в передаче данных (“слушать” соединение). Ответом на данную команду должна быть строка, содержащая адрес и порт хоста, находящиеся в режиме ожидания соединения в формате команды PORT — “h1, h2, h3, h4, p1, p2”.