Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Новый топик    Ответить
 [gt.m] Работа с сокетом  [new]
Valeriu
Member

Откуда: Chisinau
Сообщений: 1944
Добрый день.

Может кто-то ответит на мой вопрос.
Я раньше как бы работал с сокетом,
но использовал линуксовую службу xinetd,
реже родной gt.m .
В чем собственно вопрос .
Нужно обработать ошибки и если они есть, не остановить
работу сокета (halt), а продолжить его, если потребуется перезапустить заново .
Как это можно реализовать и как это делается в других реализациях М ?

Спасибо.
12 дек 16, 12:48    [19992777]     Ответить | Цитировать Сообщить модератору
 Re: [gt.m] Работа с сокетом  [new]
DirksDR
Member

Откуда: Пермь
Сообщений: 325
Valeriu,
Добрый день!
Если под ошибками понимать потерю данных (байтов), то напрашивается вывод, что надо поверх TCP свой протокол писать,
с передачей и проверкой длины пакета, а может и контрольной суммы, с автоповторами.
Я видел это, когда изучал примеры.
После инвалидного пакета выполнялась синхронизация приемника и передатчика (клиента и сервера) с помощью служебного
пакета (кажется 4хFF).
Столкнулся как-то, что клиент получал только часть пакета в 25к, хотя сервер Cache находился на том же самом ПК.
Пока уменьшил длину пакета до 10к, но держу в уме сделать контроль длины пакета:)
12 дек 16, 16:03    [19994146]     Ответить | Цитировать Сообщить модератору
 Re: [gt.m] Работа с сокетом  [new]
kalin
Member

Откуда:
Сообщений: 206
DirksDR,
+
GTMLINK(port)  ;GT.M Link Server - by paulo.rogerio@zipmail.com.br  ; Compiled April 3, 2007 11:16:22
  ;Based on Socket Examples from fscwitte@users.sourceforge.net
  ; NO ^ROUTINE ENTRY
  
ver
  
s:port="" port=8000
  
ver=$e($zv,1,10)
    
ver["GT.M" START^%MLINK(portq
    i 
ver["Cache" srv^%MLINK(portq
  QUIT
  
;
START(%ZNPort)  ;Start the Server
  ;S %ZNPort=800
  
%ZNDev="SCK$"_$J
  O 
%ZNDev:(ZLISTEN=%ZNPort_":TCP":NODELIMITER:ATTACH="listener"):60:"SOCKET"
  
E  Q
  
; USE fills $KEY with "BOUND|socket_handle|portnumber"
  
%ZNDev
  
;
  ; Start listening, sets $KEY to "LISTENING|socket_handle|portnumber"
  
/LISTEN(1)
  
;
  ; Wait for connection, $KEY will be "CONNECT|socket_handle|remote_ipaddress"
1  ;
  
F  D  q:$KEY]""
  
/WAIT(60)
  . 
I $KEY]"" Q
  
;
  ; Store the connection socket in local variable,
  
%ZNSock=$piece($KEY,"|",2)
  
%ZNDev:(SOCKET="listener"START^GTMLINK ;close listener and start another GT.M Link to listen port
  
S $ZTRAP="GOTO ERROR^GTMLINK"
2  %ZNDev:(SOCKET=%ZNSock)
  
"glc_READY:",$c(0)
  
;
  
qqnump=$j
  s 
qW=##class(%Library.qWORD).%New()
    
qARM=##class(%Library.TqARM).%New()
    
qqlang=1
3  F  D          
  
%ZNData=$$GETDATA() q:%ZNData=""
  
%ZNData="" q
  
q:%ZNData=$c(1)
  . 
%ZNData="glc_EXIT:" "glc_DISCONNECTED:",$c(0) ^tmplink("close",$j)=$h_"~EXIT" %ZNDev H
  
I $P(%ZNData,":",1)="glc_EXECUTE" D
  
.. W $c(1,2,3,4,5,6,7,8,9)
  .. 
%ZNData["getsessionid=1" k:$d(^%session($JOB)) ^%session($JOB^%session($JOB)=$h
  
.. %ZTemp=0:1:9 %Var="P"_%ZTemp,@%Var=$p(%ZNData,$c(1),%ZTemp+2)
  .. 
%ZNCommand=$P($P(%ZNData,":",2,9999),$c(1),1)
  .. 
S:%ZNCommand[($c(5)_"xmldata=1"%ZNCommand=$p(%ZNCommand,$c(5)_"xmldata=1",1)
  .. 
P9=""  
  
.. X:%ZNData'["getsessionid=1" %ZNCommand
  
.. s:%ZNData["getsessionid=1" P0=$JOB
  
.. %ZTemp=0:1:9 %Var="P"_%ZTemp '$D(@%Var@%Var=""
  
.. "glc_EXRESPONSE:<registry>",P0,$C(1),P1,$C(1),P2,$C(1),P3,$C(1),P4,$C(1),P5,$C(1),P6,$C(1),P7,$C(1),P8,$C(1),P9,$c(1)
  .. 
W $c(9,8,7,6,5,4,3,2,1)
  
^tmlink("close",$j)=$h
  C $I
  H
GETDATA()  
        
c,d,end,c1
        
(d,end,c1,c)=""
        
FINDST
        
f  d  q:end=1
        .
*c:60 q:'$T
        
.d=d_$C(c)
        .
c1=c1_c
        
.s:c1[987654321 d=$p(d,$c(9,8,7,6,5,4,3,2,1),1),end=1
        .
q
        s 
^tmlink("open",$j)=d
        
d
FINDST  
        
c,end,str
        
(c,end,str)=""
        
f  d  q:end=1
        .
*c:60 q:'$T
        
.q:(c<1)!(c>9)
        .
str=str_c
        
.s:str[123456789 end=1
        .
q
        q
ERROR  ;
  
W $c(1,2,3,4,5,6,7,8,9)
  
%ZTemp=0:1:9 %Var="P"_%ZTemp '$D(@%Var@%Var=""
  
^GTMERROR($j,$h)=$TR($ZSTATUS,$C(13,10),"")
  
%ZNDev:(SOCKET=%ZNSock)
  
"glc_ERROR:"_$TR($ZSTATUS,$C(13,10),""),$C(1),"<registry>",P0,$C(1),P1,$C(1),P2,$C(1),P3,$C(1),P4,$C(1),P5,$C(1),P6,$C(1),P7,$C(1),P8,$C(1),P9,$C(1),$c(9,8,7,6,5,4,3,2,1)
  
3
sererror
  
W $c(1,2,3,4,5,6,7,8,9)
  
%ZTemp=0:1:9 %Var="P"_%ZTemp '$D(@%Var@%Var=""
  
^GTMERROR($j,$h)=$ZERROR
  W 
"glc_ERROR:"_$zerror,$C(1),"<registry>",P0,$C(1),P1,$C(1),P2,$C(1),P3,$C(1),P4,$C(1),P5,$C(1),P6,$C(1),P7,$C(1),P8,$C(1),P9,$C(1),$c(9,8,7,6,5,4,3,2,1),*-3 
  
4
srv
(port)
    
dev,mode,jobflag,id,end
    
dev="|TCP|"_port
 
// 4 transfer to job open socket        
   
s $zt="error" 
   
mode="AS" 
   
end=""
   
jobflag=4
   
dev:(:port:mode::32767:32767) 
   
f  d  q:end=1
   .
dev x:30 // wait connection
   
.i $T J srvj(port):(:jobflag:$IO:$IO):0 end=1
   .
q
error
  
dev  
  
srv^%MLINK(port)
 
q
srvj(port)
  
id,in,d,str,dev
  
s $zt="sererror"
  
d=""
  
"glc_READY:"_$c(0),*-3  
F  D          
  
%ZNData=$$GETDATA() q:%ZNData=""
  
%ZNData="" q
  
q:%ZNData=$c(1)
  . 
%ZNData="glc_EXIT:" "glc_DISCONNECTED:",$c(0) ^tmplink("close",$j)=$h_"~EXIT" H
  
I $P(%ZNData,":",1)="glc_EXECUTE" D
  
.. value=""
  
.. W $c(1,2,3,4,5,6,7,8,9)
  .. 
%ZNData["getsessionid=1" k:$d(^%session($JOB)) ^%session($JOB^%session($JOB)=$h
  
.. %ZTemp=0:1:9 %Var="P"_%ZTemp,@%Var=$p(%ZNData,$c(1),%ZTemp+2)
  .. 
%ZNCommand=$P($P(%ZNData,":",2,9999),$c(1),1)
  .. 
S:%ZNCommand[($c(5)_"xmldata=1"%ZNCommand=$p(%ZNCommand,$c(5)_"xmldata=1",1) 
  .. 
P9=""
  
.. //s:($tr(%ZNCommand," ")'="")&(%ZNData'["getsessionid=1") %ZNCommand=$$GetFunc(%ZNCommand)
  
.. d:%ZNData'["getsessionid=1" Ex(.%ZNCommand)
  .. 
%ZNData'["getsessionid=1" ^Aaa("com")=%ZNCommand %ZNCommand
  
.. s:%ZNData["getsessionid=1" P0=$JOB
  
.. %ZTemp=0:1:9 %Var="P"_%ZTemp '$D(@%Var@%Var=""
  
.. "glc_EXRESPONSE:<registry>",value,$C(1),P0,$C(1),P1,$C(1),P2,$C(1),P3,$C(1),P4,$C(1),P5,$C(1),P6,$C(1),P7,$C(1),P8,$C(1),P9,$c(1)
  .. 
W $c(9,8,7,6,5,4,3,2,1),*-3 
  ..
q
  
.q
  Q       
Ex(Cmd)  
  
q:Cmd=""
  
f  q:($e(Cmd)'=" ")!(Cmd="")  Cmd=$e(Cmd,2,32000)
  
q:Cmd=""
  
i $e(Cmd)="$" Cmd="s value="_Cmd q
  i $e
(Cmd)="=" Cmd="s value"_Cmd q
  q

Работает лет 15 по cache и GT.M

123456789 - пакет вначале передачи

987654321 - в конце

Шлет данные как потоком , так и типа по команде аналога VisM
Отдельно можно передавать и получать регистры от P0 до P9
12 дек 16, 18:29    [19994817]     Ответить | Цитировать Сообщить модератору
 Re: [gt.m] Работа с сокетом  [new]
kalin
Member

Откуда:
Сообщений: 206
Можно выкинуть
qqnump=$j
qW=##class(%Library.qWORD).%New()
qARM=##class(%Library.TqARM).%New()
qqlang=19
12 дек 16, 18:31    [19994821]     Ответить | Цитировать Сообщить модератору
 Re: [gt.m] Работа с сокетом  [new]
DirksDR
Member

Откуда: Пермь
Сообщений: 325
kalin,

Спасибо, полезный код.
13 дек 16, 11:00    [19996394]     Ответить | Цитировать Сообщить модератору
 Re: [gt.m] Работа с сокетом  [new]
Valeriu
Member

Откуда: Chisinau
Сообщений: 1944
kalin,
У вас правильный почтовый адрес, что указан в профиле ?
15 дек 16, 08:48    [20005318]     Ответить | Цитировать Сообщить модератору
 Re: [gt.m] Работа с сокетом  [new]
Valeriu
Member

Откуда: Chisinau
Сообщений: 1944
kalin,
Немножко вроде стало ясно.
Еще вопрос.
Нету опыта с новой версии работы СОКЕТА GT.M v 6.2 и выше ?
То что у них, сложновато в примере.
http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/sockexamplemulti31.m
Вот что не нравится у них, что слишком намудрили с сокетом..
22 дек 16, 10:14    [20035312]     Ответить | Цитировать Сообщить модератору
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Ответить