Что нового

Работа с TCP

lightforever

Новичок
Сообщения
37
Репутация
2
Доброго времени суток. Изучаю работу TCP функций. Цель: передать простую строку от клиента к серверу.
Ниже код, который работат по локальной сети, но не получается создать соединение с сервером с внешнего ip адреса.

Код клиента:
Код:
TCPStartup();Инициировать использование службы TCP
$IP = '85.xxx.xx.xx';Указываем адрес к которому будем подключаться (Указываю внешний адрес)
$port = 400;Указываем порт к которому будем подключаться
$socket = TCPConnect($IP, $port);Указыываем ОС создать сокет, подключенный к указанному адресу
$dannie = InputBox('','','');Окно, которое принимает данные для отправки.
$rez = TCPSend($socket, $dannie);Отправляем данные на сервер
If @error <> 0 Then msgbox(0, "Ошибка", "Не удалось отправить данные на сервер")
TCPCloseSocket($socket);Закрываем сокетc
TCPShutdown();Завершить использование службы TCP


Код сервера:
Код:
TCPStartup();Инициировать использование службы TCP
$IP = @IPAddress1;Указываем адрес который будем прослушивать; 
$port = 400;Указываем порт который будем прослушивать
While 1
    $socket = TCPListen($IP, $port, 1);Создаем слушающий сокет, по указанному адресу
    If @error Then ExitLoop;Если не удалось создать сокет, то выйти
    $Connect = -1
    Do
        $Connect = TCPAccept($socket);Указыываем ОС создать сокет если появилось входящее подключение в прослушиваемом сокете
    Until $Connect <> -1;Если клиент подключился, то выйти из цикла, если ошибка или никто не подключился, то продолжить цикл
    While 1
        $dannie = TCPRecv($Connect, 2048);Получаем максимум 2048 символов от клиента
        If @error Then ExitLoop;Если не удалось получить символы, то выйти из цикла
        If $dannie <> "" Then;Если данные получены, то...
                MsgBox(0,'Get',$dannie)
            ExitLoop
        EndIf
        Sleep(30)
    WEnd
    TCPCloseSocket($socket);Закрываем сокет
WEnd
TCPShutdown();Завершить использование службы TCP


В коде сервера я пробовал задавать прослушиваемый адрес по-разному: с помощью @ipaddress1 и с помощью внешнего адреса, т.е. '85.xxx.xx.xx' - в первом случае всё получается, НО удаётся соединиться только с локальной сети, а в случае указания внешнего адреса функция TCPListen возвращает ошибку
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Мне @IPAddress1 выдает мой внешний адрес, а @IPAddress2 - внутренний(думаю это индивидуально). Твой скрипт нормально создает сокет и ждет подключения. Ошибки в TCPListen только двух типов - порт или адрес. Если порт - то скорее всего он уже слушается чем-то(проверяй что висит на этом порту через netstat). А если адрес, то незнаю даже в чем может быть проблема =)
Код:
$sPort = 400
$socket = TCPListen(@IPAddress1, $sPort)
If @error = 1 Then
    MsgBox(262160, 'TCP Error', 'IP-адрес определен некорректно!')
    Exit
ElseIf @error = 2 Then
    MsgBox(262160, 'TCP Error', 'Порт определен некорректно!')
    Exit
EndIf
 
Автор
L

lightforever

Новичок
Сообщения
37
Репутация
2
У меня @IpAdress1 возвращает Локальный, а не внешний адрес. И если указать локальный адрес, то всё ок, а при внешнем не получается. Я пробовал менять порты - картина не изменилась
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
lightforever
Первое! Используйте порт 80, для экспериментов.
Второе! Если вы за роутером, то настройте port forwarding.
Какой у вас провайдер?
Как вы соединяетесь с сервером?
Если и сервер и клиент в момент соединения по внешнему IP стоят на одной машине, то не все провайдеры позволят вам это!
 
Автор
L

lightforever

Новичок
Сообщения
37
Репутация
2
Garrett сказал(а):
lightforever
Первое! Используйте порт 80, для экспериментов.
Второе! Если вы за роутером, то настройте port forwarding.
Какой у вас провайдер?
Как вы соединяетесь с сервером?
Если и сервер и клиент в момент соединения по внешнему IP стоят на одной машине, то не все провайдеры позволят вам это!

Я не за роутером. У меня 2 инета: 1-й соединяется по vpn соединению, второй - с помощью режима (по модему)роутер. Пробовал менять порт на 80 и даже на forwarding - результат тот же - при указании внешнего ip выдаётся ошибка TCPListen. ЗАМечУ, чТО ошибка выдаётся при запуске скрипта сервера без участия клиента
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
lightforever
Вот вам клиент:
Код:
Local $ConnectedSocket, $Data, $IP
Local $PORT = 80
$IP = InputBox("SERVER", "Введите IP сервера","","","",100)
If @error = 1 Or $IP = "" Then Exit

TCPStartup()

$ConnectedSocket = -1

$ConnectedSocket = TCPConnect($IP, $PORT)

If @error Then
    MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error)
Else
    
    While 1
        
        $szData = InputBox("Данные для отправки на сервер", @LF & @LF & "Введите данные","","","",100)
        If @error Or $szData = "" Then ExitLoop
        TCPSend($ConnectedSocket, $szData)
        If @error Then ExitLoop
    WEnd
EndIf


Сервер можете запустить свой, только порт смените на 80й.

lightforever [?]
второй - с помощью режима (по модему)роутер
Что за режим? Если второй РС сидит через роутер, нужно сделать port forwarding 80-го порта на локальный IP адрес машины, если эта машина (за роутером) будет выступать в качестве сервера.
 
Автор
L

lightforever

Новичок
Сообщения
37
Репутация
2
Garrett
Режим роутер - это когда модем сам вводит логин и пароль при авторизации( в отличии от vpn соединения ). Попробовал я запустить свой сервер с портом 80, с Ip адресом - @ipadress1 - сервер запускается, но ваш клиент соединяться не хочет, WSA error выдёт значение 1. Если же у сервера указать порт 80 и IP внешний, то возникает ошикбка TCPListen 10049
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
WSAEADDRNOTAVAIL
10049

Cannot assign requested address.

The requested address is not valid in its context. This normally results from an attempt to bind to an address that is not valid for the local computer. This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote computer (for example, address or port 0).

10049 Невозможно использовать запрошенный адрес для привязки в порту

http://msdn.microsoft.com/en-us/library/ms740668.aspx
http://forum.sources.ru/index.php?showtopic=211287
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Redline [?]
10049 Невозможно использовать запрошенный адрес для привязки в порту
Правильно! Потому как серверу нужно указывать адрес машины, которая является сервером!!! А не WAN IP роутера!!!

lightforever [?]
Режим роутер - это когда модем сам вводит логин и пароль при авторизации( в отличии от vpn соединения ).

У меня роутер на VPN сидит, значить он уже не роутер?! ;D
Модем это модем, а роутер это роутер! :smile:
[box title=Маршрутизатор (роутер)]Это сетевое устройство, которое на основании информации о топологии сети и определённых правил принимает решение о пересылке пакетов сетевого уровня (уровень 3 модели OSI) между различными сегментами сети.[/box]
[box title=Модем]Это аббревиатура, составленная из слов модулятор и демодулятор. Это устройство служит для сопряжения информационного сигнала передаваемого/принимаемого устройством, со средой его распространения.[/box]
Модем-роутер это просто 2 in 1 ;)

с Ip адресом - @ipadress1 - сервер запускается, но ваш клиент соединяться не хочет, WSA error выдёт значение 1
Читаем справку!
Код:
TCPConnect

@error: 1 IPAddr is incorrect.
2 port is incorrect.
windows API WSAGetError return value (see MSDN).
Это говорит о том, что вы вводите неправильный/несуществующий IP.


Добавлено:
Сообщение автоматически объединено:

Сделайте так.
Посмотрите IP своих машин, если IP начинается на 196.ххх то эта машина за вашим роутером! Этот IP будет содержаться в макросе @IPAdress1.
Если нет, то, скорее всего, будет IP выдаваемый вам DHСP сервером провайдера.
Советую для начала запустить сервер на машине, которая за роутером!
На роутере сделать проброс порта 80. То есть разрешить роутеру перенаправлять порт на локальный адрес машины, где запущен ваш сервер. Читайте мануал к роутеру!
Далее с машины, на которой стоит сервер, зайдите на httр://myip.ru и узнайте свой WANIP. Его вы будите указывать клиенту.
 
Верх