一个python脚本打开套接字,另一个通过套接字发送数据

时间:2019-02-18 19:14:00

标签: python sockets agi

我正在研究Asterisk AGI和Python 3的集成。我的脚本遇到了麻烦,我想这可能是因为它一次运行太多,而最后关闭套接字是造成问题的原因。

  • 我有一个系统将SIP呼叫发送到星号。
  • 星号然后执行脚本。
  • 脚本打开一个TCP套接字,并发送数据以关闭该脚本结束的套接字。

如果我一次打进来一个电话,或者他们错开了,脚本将完美执行。如果我有多个电话同时打来,请说5(在这种情况下很常见),接收数据的套接字只能处理2个完全完成的脚本。

我试图最小化脚本,以查看是否可以使它更快地执行,删除不需要的内容,删除日志记录,删除#out行。我唯一能做的就是尝试错开通话,这是不可行的选择。

#!/usr/bin/env python3

import serial
import re
from time import sleep
import logging
import logging.handlers
from configparser import ConfigParser
import sys
import asterisk
import asterisk.agi
from asterisk.agi import *
import socket
import os
import sys

config = ConfigParser()
config.read('/var/www/html/config.ini')
LOG_LEVEL = logging.info('LOGGING', 'level')

# Initialize logging
LOGGER = logging.getLogger('axi')
LOGGER.setLevel(logging.INFO)
formatter = logging.Formatter('|%(asctime)s|%(levelname)-8s|%(name)s|%(message)s')
log_file = logging.handlers.TimedRotatingFileHandler('/var/log/axi/input.csv', when='midnight', backupCount=7)
log_file.setLevel(logging.INFO)
log_file.setFormatter(formatter)
LOGGER.addHandler(log_file)

# Only print to console if at DEBUG level
if LOG_LEVEL == 'DEBUG':
log_console = logging.StreamHandler()
log_console.setLevel(logging.INFO)
log_console.formatter(formatter)
LOGGER.addHandler(log_console)

#BAUD = config.get('USB_Settings', 'baudrate')
#PTY = config.get('USB_Settings', 'parity')
#STPB = int(config.get('USB_Settings', 'stopbits'))
#BTSZ = int(config.get('USB_Settings', 'bytesize'))

HOST = config.get('Ethernet_Paging_System', 'IP')
PORT = config.get('Ethernet_Paging_System', 'Port')

agi = AGI()

pin = agi.env['agi_extension']
msg = agi.env['agi_calleridname']

geekspeak = {
    "<ESC>": '\\x1b',
    "<ETX>": '\\x03',
    "<CR>": '\\r',
    "<ACK>": '\\x06',
    "<NAK>": '\\x15',
    "<EOT>": '\\x04',
    "<STX>": '\\x02'
}

htmlspeak = {
    "&ltESC&gt": '\\x1b',
    "&ltETX&gt": '\\x03',
    "&ltCR&gt": '\\r',
    "&ltACK&gt": '\\x06',
    "&ltNAK&gt": '\\x15',
    "&ltEOT&gt": '\\x04',
    "&ltSTX&gt": '\\x02'
}


def str2geek(string):
    geekstr = str(string)
    for key, value in geekspeak.items():
        if key in geekstr:
            geekstr = geekstr.replace(key, value)
    return geekstr


def geek2str(string):
    sstr = str(string)
    for key, value in geekspeak.items():
        if value in sstr:
            sstr = sstr.replace(value, key)
    return sstr


def html2str(string):
    hstr = str(string)
    for key, value in htmlspeak.items():
        if value in hstr:
            hstr = hstr.replace(value, key)
    return hstr

#Socket setup
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_INET, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
    s.connect(sa)
    except OSError as msg:
    s.close()
    s = None
    continue
    break
if s is None:
    LOGGER.info('---Could not open socket')
    sys.exit(1)
with s:
    s.send(b'\\r')
    sleep(0.5)
    s.send(b'\\x1bPG1\\r')
    strng=(pin)+(msg)
#New Code for Checksum
    list_ascii=[ord(i) for i in strng]
    #Prints each car decimal value
    #print(list_ascii)
    b=sum(list_ascii)+31
    #Convert sum to 12 bit binary and parse to 4 sections frist 4 middle 4 last 4
    h1=(bin(b)[2:].zfill(12)[8:])
    h2=(bin(b)[2:].zfill(12)[4:8])
    h3=(bin(b)[2:].zfill(12)[0:4])
    #Adds 48 decimal value per TAP 1.8
    i1=(int(h1, 2)+48)
    i2=(int(h2, 2)+48)
    i3=(int(h3, 2)+48)
    #Gives checksum value
    chks=chr(i3)+chr(i2)+chr(i1)
    LOGGER.info('---Pin:' + pin + ' - ' + 'Message:' + msg + ' - checksum:' + chks)
    s.send('\x02'.encode() + (pin).encode() + '\r'.encode() + msg.encode() + '\r\x03'.encode() + (chks).encode() + '\r'.encode())
    resp=str(s.recv(1024))
    if resp:
        LOGGER.info(html2str(resp))
        if '15' in resp:
            LOGGER.info('page not accepted')
        if resp:
            sleep(0.5)
            s.send(b'\x04\r')
            sleep(0.5)
            LOGGER.info('---Page Accepted' + ' - checksum:' + chks)
            s.close()

我希望能够创建一个使TCP套接字保持活动状态的脚本,而另一个脚本将在对星号的调用上执行,并通过套接字或已运行的python脚本发送该数据,并开始发送数据的过程带有变量。

谢谢

1 个答案:

答案 0 :(得分:0)

这就是我的做法。我得到了第一个脚本来运行对星号的调用,第二个脚本打开连接并保持打开状态,直到一侧关闭为止。 星号脚本仅在呼叫进入星号时运行,并将入站SIP消息转换为在护士呼叫行业大量使用的TAP 1.8消息。 我作为服务运行的套接字脚本打开了连接以发送数据。

星号脚本

#!/usr/bin/env python3

import serial
import re
from time import sleep
import sys
import asterisk
import asterisk.agi
from asterisk.agi import *
import socket
import os

geekspeak = {
    "<ESC>": '\\x1b',
    "<ETX>": '\\x03',
    "<CR>": '\\r',
    "<ACK>": '\\x06',
    "<NAK>": '\\x15',
    "<EOT>": '\\x04',
    "<STX>": '\\x02'
}

htmlspeak = {
    "&ltESC&gt": '\\x1b',
    "&ltETX&gt": '\\x03',
    "&ltCR&gt": '\\r',
    "&ltACK&gt": '\\x06',
    "&ltNAK&gt": '\\x15',
    "&ltEOT&gt": '\\x04',
    "&ltSTX&gt": '\\x02'
}

def str2geek(string):
    geekstr = str(string)
    for key, value in geekspeak.items():
        if key in geekstr:
            geekstr = geekstr.replace(key, value)
    return geekstr


def geek2str(string):
    sstr = str(string)
    for key, value in geekspeak.items():
        if value in sstr:
            sstr = sstr.replace(value, key)
    return sstr


def html2str(string):
    hstr = str(string)
    for key, value in htmlspeak.items():
        if value in hstr:
            hstr = hstr.replace(value, key)
    return hstr

agi = AGI()
pin = '201' #agi.env['agi_extension']
msg = 'TEST' #agi.env['agi_calleridname']
strng=(pin)+(msg)
#New Code for Checksum
list_ascii=[ord(i) for i in strng]
#Prints each car decimal value
#print(list_ascii)
b=sum(list_ascii)+31
#Convert sum to 12 bit binary and parse to 4 sections frist 4 middle 4 last 4
h1=(bin(b)[2:].zfill(12)[8:])
h2=(bin(b)[2:].zfill(12)[4:8])
h3=(bin(b)[2:].zfill(12)[0:4])
#Adds 48 decimal value per TAP 1.8
i1=(int(h1, 2)+48)
i2=(int(h2, 2)+48)
i3=(int(h3, 2)+48)
#Gives checksum value
chks=chr(i3)+chr(i2)+chr(i1)
#Socket setup
s = None
for res in socket.getaddrinfo("localhost", 9988, socket.AF_INET, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except OSError as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    sys.exit(1)
with s:
    s.send('\x02'.encode() + (pin).encode() + '\r'.encode() + msg.encode() + '\r\x03'.encode() + (chks).encode() + '\r'.encode())
    s.close()

套接字脚本

#!/usr/bin/env python3

import serial
import re
from time import sleep
import logging
import logging.handlers
from configparser import ConfigParser
import socket
import os
import sys

config = ConfigParser()
config.read('/var/www/html/config.ini')
LOG_LEVEL = logging.info('LOGGING', 'level')

# Initialize logging
LOGGER = logging.getLogger('axi')
LOGGER.setLevel(logging.INFO)
formatter = logging.Formatter('|%(asctime)s|%(levelname)-8s|%(name)s|%(message)s')
log_file = logging.handlers.TimedRotatingFileHandler('/var/log/axi/input.csv', when='midnight', backupCount=7)
log_file.setLevel(logging.INFO)
log_file.setFormatter(formatter)
LOGGER.addHandler(log_file)

# Only print to console if at DEBUG level
if LOG_LEVEL == 'DEBUG':
    log_console = logging.StreamHandler()
    log_console.setLevel(logging.INFO)
    log_console.formatter(formatter)
    LOGGER.addHandler(log_console)

HOST = config.get('Ethernet_Paging_System', 'IP')
PORT = config.get('Ethernet_Paging_System', 'Port')

#Socket setup
s2 = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_INET, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s2 = socket.socket(af, socktype, proto)
    except OSError as msg:
        s2 = None
        continue
    try:
        s2.connect(sa)
    except OSError as msg:
        s2.close()
        s2 = None
        continue
    break
if s2 is None:
    LOGGER.info('---Could not open socket')
    sys.exit(1)
#listening Socket
s3 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s3.bind(("localhost", 9988))
s3.listen(1)

while True:
    conn, addr = s3.accept()
    data = conn.recv(1024)
    if data:
        #with s2:
        s2.send(b'\\r')
        sleep(0.5)
        s2.send(b'\\x1bPG1\\r')
        LOGGER.info(data)
        s2.send(data)
        resp=str(s2.recv(1024))
        if resp:
#            LOGGER.info(html2str(resp))
            if '15' in resp:
                LOGGER.info('page not accepted')
            if resp:
                s2.send(b'\x04\r')
                LOGGER.info('---Page Accepted')