Что нового

Плавающая неопознанная ошибка скомпилированной программы

warmroof

Новичок
Сообщения
10
Репутация
0
Не знаю как лучше назвать тему, т.к. не понимаю природу ошибки и не знаю как отловить...
Не единожды на нескольких работающих программах выскакивать периодически ошибка:

Autoit Error
line 3651 (File "xxxxxxxxxxxxxxxxx")
Error: Subscript used with non-Array variable.


Подозреваю, что все это как-то связано с сетевыми функциями программ. Т.к. все мои скрипты на которых выскакивает ошибка объединяет именно это, но код скриптов работы с TCP везде разный.

Вот сегодня при вызове программы выскочила ошибка. До этого все работало нормально.

Код скрипта
Код:
#Include <File.au3>
#include <Date.au3>

Const $CS_MAGIC          = 0xDEADBEEF
Const $CS_PROTO          = 0x00010013 ;ma v1.13
Const $MRIM_CS_HELLO     = 0x00001001
Const $MRIM_CS_HELLO_ACK = 0x00001002
Const $MRIM_CS_LOGIN_ACK = 0x00001004
Const $MRIM_CS_LOGIN_REJ = 0x00001005
Const $MRIM_CS_PING      = 0x00001006
Const $MRIM_CS_MESSAGE   = 0x00001008
Const $FST_SEQ           = 0x00000001
Const $RESERVED          = "00000000000000000000000000000000"
Const $FROM              = 0x00000000      
Const $FROMPORT          = 0x00000000
Const $DLENZERO          = 0x00000000
Const $MRIM_CS_LOGIN2    = 0x00001038
Const $STATUS_OFFLINE                  = 0x00000000
Const $STATUS_ONLINE                   = 0x00000001
Const $STATUS_AWAY                     = 0x00000002
Const $STATUS_UNDETERMINATED           = 0x00000003
Const $STATUS_FLAG_INVISIBLE           = 0x80000000
Const $FROM_LOGIN_HZ                   = 0x0000FF03
Const $MRIM_CS_SMS                     = 0x00001039
Const $STATUS_SMS                      = 0x00000004

Global $tDate

Dim $aRecords

$pathtxt=@ScriptDir&"\sms.txt"
$tDate = _Date_Time_GetLocalTime()

if _Date_Time_SystemTimeToTimeStr($tDate)>="10:00:00" Then
	If Not FileExists($pathtxt) Then
		If Not _FileCreate($pathtxt) Then
			MsgBox(4096,"Error", " Error Creating/Resetting log.      error:" & @error)
			Exit
		EndIf
	EndIf
	If Not _FileReadToArray($pathtxt,$aRecords) Then
		$file = FileOpen($pathtxt, 1)
		If $file = -1 Then
			MsgBox(0, "Error", "Unable to open file.")
			Exit
		EndIf
		FileWriteLine($file, _Date_Time_SystemTimeToDateStr($tDate, 1) & @CRLF)
		FileClose($file)
		_SendSMS()
	Else
		If $aRecords[$aRecords[0]] <> _Date_Time_SystemTimeToDateStr($tDate, 1) Then
			$file = FileOpen($pathtxt, 1)
			If $file = -1 Then
				MsgBox(0, "Error", "Unable to open file.")
				Exit
			EndIf


			FileWriteLine($file, _Date_Time_SystemTimeToDateStr($tDate, 1) & @CRLF)
			FileClose($file)
			_SendSMS()
		EndIf
	EndIf
EndIf

;Func  _SendSMS($login, $pass, $nom_tel, $sms_msg)
Func  _SendSMS()
$STATUS_SMS_STR = "status_24"
$status_str ="sms"
$login= "xxxxxxxxxxxx" ;логин
$pass= "xxxxxxxxxx" ;пароль
$name_clt = 'client="magent" version="5.3" build="2546"'
$name_clt2 = "MRA 5.3 (build 2546);"
$RU ="ru"

$sms_msg = @CRLF & "Online" & @CRLF & _Date_Time_SystemTimeToDateTimeStr($tDate,1) & @CRLF
$nom_tel = "+xxxxxxxxxxxx" ;номер телефона
;**********************msg hello*****************************************************
$hello_title = _Rotate_cl($CS_MAGIC) &_Rotate_cl($CS_PROTO) & _Rotate_cl($FST_SEQ) & _Rotate_cl($MRIM_CS_HELLO) & _Rotate_cl($DLENZERO) & _Rotate_cl($FROM) & _Rotate_cl($FROMPORT)
$hello_msg = Binary ( $hello_title ) & $RESERVED
;MsgBox(1,"$hello_msg--IsBinary",IsBinary($hello_msg))
;**********************msg login*****************************************************
$login_str = _string_UPL($login) & _string_UPL($pass) & _Rotate_cl($STATUS_SMS) & _string_UPL($STATUS_SMS_STR) & _string_UPL_RU($status_str) & _Rotate_cl($FROM) & _Rotate_cl($FROM_LOGIN_HZ)
$login_str = $login_str & _string_UPL($name_clt) & _string_UPL($RU) & _string_UPL($name_clt2)
$login_str = Binary($login_str)
;MsgBox(1,"$login_str--IsBinary",IsBinary($login_str))
$DLENLOGIN = BinaryLen ($login_str)
;MsgBox(1,"BinaryLen",$DLENLOGIN)
$login_title = _Rotate_cl($CS_MAGIC) &_Rotate_cl($CS_PROTO) & _Rotate_cl($FST_SEQ+1) & _Rotate_cl($MRIM_CS_LOGIN2) & _Rotate_cl($DLENLOGIN) & _Rotate_cl($FROM) & _Rotate_cl($FROMPORT)
$login_msg = Binary ( $login_title ) & $RESERVED &  StringTrimLeft( String($login_str),2) 
;$login_msg = Binary ($login_msg)
;MsgBox(1,"$login_msg",$login_msg)
;Exit
;****************msg ping************************************************************
$ping_title1 = _Rotate_cl($CS_MAGIC) &_Rotate_cl($CS_PROTO)
$ping_title2 = _Rotate_cl($MRIM_CS_PING) & _Rotate_cl($DLENZERO) & _Rotate_cl($FROM) & _Rotate_cl($FROMPORT)
;***************msg sms**************************************************************
$sms_str = _Rotate_cl($DLENZERO) & _string_UPL($nom_tel) & _string_UPL_RU($sms_msg)
$sms_str = Binary($sms_str)
$dlensms = BinaryLen($sms_str)
$sms_title1 = _Rotate_cl($CS_MAGIC) & _Rotate_cl($CS_PROTO) ;& п\номер пакета
$sms_title2 = _Rotate_cl($MRIM_CS_SMS) & _Rotate_cl($dlensms) & _Rotate_cl($FROM) & _Rotate_cl($FROMPORT)
;****************Инициировать использование службы TCP*******************************
If TCPStartup() = 0 Then 
	MsgBox(1,"TCP","Неудалось инициализировать службу TCP",5)
EndIf
;***************создание сокета для подкл. к серверу*********************************
Do
	$ip_srv = _GetMrimIp()
    $socket_srv = TCPConnect( $ip_srv[0], $ip_srv[1] )
	If @error Then
		MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error)
	EndIf
Until $socket_srv <> -1

;***************инициализация клиента на сервере*************************************
TCPSend($socket_srv,$hello_msg)
If @error Then MsgBox(4112, "Error", "TCPSend failed 1: " & @error)
While 1
	$msg_srv = TCPRecv($socket_srv, 2048)
	If @error Then MsgBox(4112, "Error", "TCPRecv failed 1: " & @error)
	If $msg_srv <> "" Then
		$rez = _ReadMsgSrv($msg_srv)
		If @error <> -1 Then
			If $rez[0] = Binary($MRIM_CS_HELLO_ACK) Then
				TCPSend($socket_srv,$login_msg)
				If @error Then MsgBox(4112, "Error", "TCPSend failed 2: " & @error)
				$interval = $rez[1]
				;MsgBox(1,"interval_ping",$interval_ping)
			ElseIf $rez[0] = Binary($MRIM_CS_LOGIN_ACK) Then
				ExitLoop
			EndIf
		EndIf
	EndIf
Wend

;**************сам клиент********************************************************
$first_ping_msg = $ping_title1 & Binary(0x00000003) & $ping_title2 & $RESERVED
TCPSend($socket_srv,$first_ping_msg)
If @error Then MsgBox(4112, "Error", "TCPSend failed 3: " & @error)
$timer = TimerInit()
$counter_seq = 0x00000003
$interval_ping = Dec(Hex(_Rotate_srv($interval)))*1000
While 1
	;$msg_srv = TCPRecv($socket_srv, 2048)
	$dif = TimerDiff($timer)
	If $dif >= $interval_ping Then
		$counter_seq = $counter_seq+1
		$ping_msg = $ping_title1 & Binary($counter_seq) & $ping_title2 & $RESERVED
		TCPSend($socket_srv,$ping_msg)
		If @error Then MsgBox(4112, "Error", "TCPSend failed 4: " & @error)
		$timer = TimerInit()
	Else
		$counter_seq = $counter_seq+1
		;тут смс сообщения
		$sms_msg = $sms_title1 & Binary($counter_seq) & $sms_title2 & $RESERVED & StringTrimLeft( String($sms_str),2)
		TCPSend($socket_srv,$sms_msg)
		If @error Then MsgBox(4112, "Error", "TCPSend failed 5: " & @error)		
		ExitLoop
	EndIf
Wend
TCPCloseSocket ( $socket_srv )
EndFunc  ;==>_SendSMS

;функция обрабатывает сообщение сервера
Func _ReadMsgSrv($msg_srv)
Local $rezmsgsrv[2],$lenfullmsg,$lenmsg,$error = -1
If BinaryMid($msg_srv,1,4) = Binary($CS_MAGIC) Then
	$lenfullmsg = BinaryLen($msg_srv)
	;MsgBox(1,"lenfullmsg",$lenfullmsg)
	$lenmsg = Binary(Dec(Hex(BinaryMid($msg_srv,17,4))))
	$lenmsg = Dec(Hex($lenmsg))
	;MsgBox(1,"lenmsg",$lenmsg)
	$rezmsgsrv[0] = BinaryMid($msg_srv,13,4) ;тип пакета
	$rezmsgsrv[1] = BinaryMid($msg_srv,$lenfullmsg-$lenmsg+1,$lenmsg) ;текст сообщения
	Return $rezmsgsrv
EndIf
Return SetError(1,0,-1)
EndFunc  ;==>_ReadMsgSrv

; функция возвращает ip & port сервера
Func _GetMrimIp()
Local $ip[2]
If InetGet("http://mrim.mail.ru:2042/", @TempDir & "\~ipm.tmp") Then
	$ipstr = FileRead(@TempDir & "\~ipm.tmp", FileGetSize(@TempDir & "\~ipm.tmp"))
	$ipstr = StringStripWS($ipstr,8)
	$ipstrlen = StringLen($ipstr)
	$ipstrin = StringInStr($ipstr, ":")
	$ip[0] = StringTrimRight($ipstr,$ipstrlen-$ipstrin+1)
	$ip[1] = StringTrimLeft($ipstr,$ipstrin)
	If $ip[0] <>"" Then
		Return $ip
	EndIf
EndIf
If InetGet("http://mrim.mail.ru:2042/", @TempDir & "\~ipm.tmp") Then
	$ipstr = FileRead(@TempDir & "\~ipm.tmp", FileGetSize(@TempDir & "\~ipm.tmp"))
	$ipstr = StringStripWS($ipstr,8)
	$ipstrlen = StringLen($ipstr)
	$ipstrin = StringInStr($ipstr, ":")
	$ip[0] = StringTrimRight($ipstr,$ipstrlen-$ipstrin+1)
	$ip[1] = StringTrimLeft($ipstr,$ipstrin)
	If $ip[0] <>"" Then
		Return $ip
	EndIf
EndIf
Return SetError(1,0,-1)
EndFunc   ;==>_GetMrimIp

;функция разворачивает  число от клиента
Func _Rotate_cl($val)
	Local $valrot
	$valrot = Binary($val)
	Return $valrot
EndFunc ;==>_Rotate_cl

;функция разворачивает число от сервера
Func _Rotate_srv($val)
	Local $valrot
	$valrot = Binary(Dec(Hex($val)))
	Return $valrot
EndFunc ;==>_Rotate_srv

;функция создает ULP строку(формат протокола)
Func _string_UPL($val)
	Local $bstr,$lenstr
	$bstr = StringToBinary ( $val,4 )
    $lenstr = Binary(BinaryLen($val))
	$string_UPL = $lenstr & $bstr
	$string_UPL = Binary($string_UPL)
    ;MsgBox(1,"",$lenstr&"\"& $bstr)
	Return $string_UPL
EndFunc ;==>_string_UPL

;функция создает ULP_RU строку(формат протокола)
Func _string_UPL_RU($val)
	Local $bstr,$lenstr
	$bstr = StringToBinary ( $val,2 )
	;MsgBox(0,"",$bstr)
    $lenstr = Binary(BinaryLen($bstr))
	$string_UPL = $lenstr & $bstr
	;$string_UPL = Binary($string_UPL)
    ;MsgBox(1,"",$lenstr&"\"& $bstr)
	Return $string_UPL
EndFunc ;==>_string_UPL_RU

;заголовок пакета
#cs
u_long      magic;        // Magic
u_long      proto;        // Версия протокола
u_long      seq;        // Sequence
u_long      msg;        // Тип пакета
u_long      dlen;         // Длина данных
u_long    from;        // Адрес отправителя
u_long    fromport;    // Порт отправителя
u_char    reserved[16];    // Зарезервировано
#ce


Здесь используется функция отправки SMS из этой темы http://autoit-script.ru/index.php?topic=4676.0
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
warmroof
ИМХО, у Вас ошибка здесь:
Код:
;...
$rez = _ReadMsgSrv($msg_srv)
        If @error <> -1 Then
;...
Функция _ReadMsgSrv($msg_srv) никогда не возвращает @error = -1, возвращает @error = 1. Т.е. функция возвращает ошибку 1 и значение -1, , а скрипт пытается использовать -1 как массив.

И здесь:
Код:
;...
 $ip_srv = _GetMrimIp()
    $socket_srv = TCPConnect( $ip_srv[0], $ip_srv[1] )
;...
Вы не проверяете вернула ли функция _GetMrimIp() массив. (А зачем она дважды делает одно и то же?)
 
Автор
W

warmroof

Новичок
Сообщения
10
Репутация
0
Это значит не у меня, а у автора данной функции ссылку на тему с которой указал выше.
Но сдается мне что не в этом ошибка. Т.к. другие скрипты не используют данной конструкции.

Здесь на форуме уже была подобная тема с данной ошибкой, но ответа так и не было.

Можно ли ка-то узнать место ошибки по данному сообщению о ней?
Ставить "флажки" по всему коду не представляю возможным из-за нестабильности выпадения этой самой ошибки...
 

axlwor

Скриптер
Сообщения
657
Репутация
147
проверяй значение прежде чем использовать
Код:
Not IsArray()

или
Код:
IsString()
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
warmroof [?]
Можно ли ка-то узнать место ошибки по данному сообщению о ней?
Запускайте скрипт из SciTE и ждите ошибку, тогда будет реальный номер строки с ошибкой.
 
Автор
W

warmroof

Новичок
Сообщения
10
Репутация
0
axlwor
Про массивы понятно. В другом скрипте путем частого переподключения сети выявил ошибку именно с массивом.

madmasles
В данном конкретном примере сделать это не возможно. Т.к. скрипт запускается разово, а если спамить, то mail.ru начнет блокировать запросы и тогда фиг там чего вообще отловишь...

Может допилите функцию отправки SMS, на предмет существующих ошибок и отлова текущих, и отпишитесь здесь или в теме автора скрипта?
 

axlwor

Скриптер
Сообщения
657
Репутация
147
OffTopic:
да глупо допиливать только смс. а дописать модуль до полной поддержки протокола автору лень
 
Автор
W

warmroof

Новичок
Сообщения
10
Репутация
0
Так ошибку опознать удалось. Осталось выяснить в каком месте. Что из кода ошибки не совсем ясно.

С массивами в другом скрипте кое-где пришлось проверять, что это действительно массивы через
Код:
VarGetType ($int)

, а иначе при обращении к несуществующей элементу массива, который вовсе не массив и выпадала ошибка...

Вот еще обнаружил, что массив может неожиданно обрываться при заполнении его результатами работы с сетевым запросами и нестабильным сетевым соединением.

Пришлось в некоторых местах проверять и длину массива через
Код:
UBound()

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

Ну и дела с этими массивами...
Даже не знаю закрывать тему или пока нет, но название точно можно исправить. Вот только на что????
 
Верх