1

正如你们所看到的,过去几年我一直在使用 C++ 苦苦挣扎,其中一件事是使用 C++ 打开套接字连接,然后建立一个字符串(每个字母都转换为十六进制),然后计算校验和,我真的不知道如何,然后通过套接字将字符串发送到 ploycomp 招牌并且套接字关闭。

C++ 套接字连接和字符串构建非常挑剔,如果它只是有点偏离,那么什么都不会发送。现在的问题是我们正在将 C+ 程序重新编写到 Apex 中,并且我们希望将套接字连接传输到存储所有招牌端口/IP 和地址的 oracle 11g 数据库。自然而然地,我要这样做,我不知道该怎么做。我知道 sql 有一个 TCP 组件,但不知道实际代码。有没有大神能帮帮我?

我得到了这个,但对它的含义有点困惑:

PolyComp (Pty) Ltd.
Designers & Manufacturers of Programmable Electronic Displays,
Colour Graphic Boards & Electro-magnetic Displays.
HEAD OFFICE & FACTORY Tel: 011-608-2770
PolyComp House Fax: 011-608-2774
4 Fountain Road E-mail: polycomp@global.co.za
Edenvale
P.O.Box 3234
Edenvale 1610
South Africa
STATIC SERIAL COMMUNICATION PROTOCOL
PolyComp displays can be linked to a computer through a serial communication RS232 , RS485 and
CURRENT LOOP using the following Default settings :
BAUD RATE : 9600
START BIT : 8
STOP BITS : 1
PARITY : NONE
8 Bit ASCII code compatible with extended IBM ASCII code .
These are the default settings which can be changed using the Dip-Switch on the SERIAL
COMMUNICATION BOARD .
CONNECTING THE COMPUTER TO THE SIGN
When you power up – the sign will perform a self test and display the results on the screen . The setting of the
“Serial Communication Board” will also be displayed . Be sure to use the same settings on the PC.
 Using RS232
A Direct connection via RS232 can be used only for a short distance – up to approximately : 100 metres .
Only 3 wires are used and these must connect as follows :
PC SIDE S I G N S I D E
DIN…. 25 DIN…. 9 Round DIN…. 5
Signal
TXD PIN 2 PIN 3 PIN 5 RXD
RXD PIN 3 PIN 2 PIN 3 TXD
GND PIN 7 PIN 5 PIN 4 GND
 Using RS485
Connect RS232 to the RS485 converter , between the PC and the sign .
This international standard is more suitable for long distance communication , as well as Multidrop
communication . {Few signs can be connected on Two-Way communication to the Host [ PC ] }

RS485 CONNECTIONS
PC RS232 RS232 / RS485 RS485 Up To 1000 Metres PolyComp Sign
(4 Wires) Converter ( 2 Wires + Screen ) With RS485
Interface

The PC is linked to the RS485 converter via 4 wires namely :~
TXD Transit Data from PC .
RXD Received Data to PC .
DTR Controls Traffic flow : + 12V => TX Mode , - 12 V => RX Mode .
GND Ground
Since RS485 only uses 2 wires , only one device can send data at a time .
The PC downloads a page of text , the sign checks the integrity of the message and if it is OK – it will transfer
the page from the temporary RX Buffer into the message buffer .
If the acknowledge BIT on the Serial Status Byte is set (B3) , then the sign will send “Acknowledge” back to
the PC .
In order for the PC to get the reply {when RS485 is used } DTR needs to be at - 12V [RX Mode ] . Once the
reply has been sent , the PC can send the next page ..etc…
When the last page has been sent , be sure that BIT 2 – on the “Serial Status Byte” has been Reset ( = 0 ), so
that the new message will be displayed immediately . When this BIT is set , it instructs the sign that more
pages are ‘coming’ and therefore , the sign will ‘wait’ for these pages and will not display the new message
…however if no new data is received within 40 seconds . It will consider the last valid page -received as the
last page and the sign will then display the new message .

COMMUNICATION PROTOCOL
These signs can be programmed for one way or two way communication by setting the relevant bit as explained
below ( Should a two way communication be selected , be sure that your hardware can suppport it ! ) .
The message should be sent to the sign page after page .
PROTOCOL
Byte Description Decimal Value Comments
1 Header Sync 00
2 Nol / Static ?? (Number Of Text
Lines On the Sign / 'S')
3 Sign Address XX (1 – 127,0 = “All Call”)
4 Etx 03 End Of Header .
[ Message text]
EOT 04 End Of Text
Last Byte Checksum ??
( The checksum is an EXCLUSIVE ‘OR’ function bit by bit starting at the SYNC. Up to and including the
“End Of Text” byte 04 ) .
Change Letter Appearance On The Display
In Order to change the appearance of letters on the display , the following controls can be used :~
A control block consists of 2 bytes :
1st Byte : Control Code = 28 BCD. [1C Hex]
2nd Byte : Command .
The following Commands are available :~
F : Flash Characters .
E : Enlarge Characters
R : Change Colour to Red ( Colour Signs Only! )
G : Change Colour To Green ( Colour Signs Only! )
Y : Change Colour to Yellow ( Colour Signs Only! )
M : Multicolour – i.e: Top Red Center Yellow Bottom Green ( Colour Signs Only! )
D : Return To Default Setting – i.e: Normal {Not Enlarged} Red Letters Not Flashing .
Every page starts with the default settings : Red , Normal Letters , No Flash !

EXAMPLE : The following string ~
“POLYCOMP” (28) “G IS” (28) “F” (28) “M THE” (28) “F” (28) “E BEST” WILL
DISPLAY : “POLYCOMP IS THE BEST”
“POLYCOMP” - RED ~ “THE” MULTI COLOUR FLASH .
“IS” - GREEN ~ “BEST” MULTI COLOUR ENLARGE .
IN THIS EXAMPLE ~
TEXT BETWEEN INVERTED COMMA’S “ ” IS ASCII CHARACTERS . NUMBERS BETWEEN
BRACKETS ARE IN bcd VALUES .
PolyComp (Pty) Ltd . Tel: 011 452 – 3505/6
Fax: 011 452 – 2542
EXAMPLE OF GTX PROGRAM FOR 1 LINE DISPLAY ~ GTXC
10 OPEN “COM1 : 9600,N,8,2,CS,DS,CD”AS #1
15 CLS : PRINT TAB(30) “ POLYCOMP TEST GTX”
16 PRINT TAB(28) “~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~”
20 A$=CHR$(0)+CHR$(1)+CHR$(2)+CHR$(3)+CHR$(&HC0)+“001”+CHR$(&HE2)+CHR$(&HC1)+CHR$(&HC0)
25 FOR CNT=100 TO 10000
30 MSG$= “CNT =”+STR$(CNT)
40 TXT$=A$+MSG$+CHR$(4)
50 CK=0
60 FOR I = 1 TO LEN(TXT$)
70 CK=CK XOR ASC(MID$(TXT$,I,1))
80 NEXT I
90 PRINT #1,TXT$;CHR$(CK);:LOCATE 5,34:PRINT “CNT =”;CNT
100 FOR D=1 TO 5000:NEXT D
110 NEXT CNT

EXAMPLE OF GTX PROGRAM FOR DOUBLE LINE DISPLAY ~ GTXC
10 OPEN “COM1 : 9600,N,8,2,CS,DS,CD”AS #1
15 CLS : PRINT TAB(30) “ POLYCOMP TEST GTX”
16 PRINT TAB(28) “~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~”
20 A$=CHR$(0)+CHR$(2)+CHR$(0)+CHR$(3)+CHR$(&HCO)+“001”+CHR$(&HE2)+CHR$(&HC1)+CHR$(&HC0)
26 FOR CNT=100 TO 10000
30 MSG$= “CNT =”+STR$(CNT)
41 TXT$=A$+MSG$+CHR$(4)
51 CK=0
61 FOR I = 1 TO LEN(TXT$)
71 CK=CK XOR ASC(MID$(TXT$,I,1))
81 NEXT I
91 PRINT #1,TXT$;CHR$(CK);:LOCATE 5,34:PRINT “CNT =”;CNT
101 FOR D=1 TO 5000:NEXT D
110 NEXT CNT

我努力了:

declare
   bt_conn      UTL_TCP.connection;
   retval       BINARY_INTEGER;
  -- l_sequence   VARCHAR2 (50) := '005301035204';
  l_sequence   VARCHAR2 (300) := '450000625EDC4000800669D20A44B20F0A6B6B290AEA1F40B07906E7A715E4BC5018FAF0F0D20000005301031C468656C6C6F2020202020202020202020 20202020202020201C442020202020202020202020202020202020202020202020200417';
BEGIN


   bt_conn :=
      UTL_TCP.open_connection (remote_host   => '10.107.107.41',
                               remote_port   => 8000,
                              tx_timeout    => 15);           
   DBMS_LOCK.SLEEP (1);
   retval := UTL_TCP.write_line (bt_conn, l_sequence);
 --  DBMS_LOCK.SLEEP (1);
   UTL_TCP.flush (bt_conn);
   UTL_TCP.close_connection (bt_conn);
EXCEPTION
   WHEN OTHERS
   THEN
      raise_application_error (-20101, SQLERRM);
      UTL_TCP.close_connection (bt_conn);
END;
/

l_sequence 中的字符串是当招牌制造商使用程序发送字符串“HELLO”时通过数据包嗅探器捕获的字符串

但它似乎不起作用

4

2 回答 2

0

我的建议是您发送字节的字符串表示形式而不是字节本身。

所以,试着改变

retval := UTL_TCP.write_line (bt_conn, l_sequence);

retval := UTL_TCP.write_raw (bt_conn, hextoraw(l_sequence));

我唯一的疑问是示例数据中的空格符号,但我认为他是偶然出现的。

在嗅探器的帮助下,您可以拦截来自 Oracle 的数据并将其与旧实用程序的数据进行比较。

更新(删除 - 不正确的协议实现)

更新 2

以下是 Polycomp 显示协议的实现,在文档中描述,可在 Internet 资源(链接1 、链接2 、链接 3)中找到。即使没有修改实现对您不起作用,它也包含许多有用的代码来学习如何处理rawOracle 中的值。

实用程序包头:

create or replace package POLYCOMP_UTIL is

  -- PolyComp signboard interaction for Oracle

  -- SERST (Serial status flag byte #5 constants) --------------------

  -- B1 = 1 => "Interrupt Mode" = 0 => Normal DISPLAY Mode.                                                                      
  C_SERST_INTERRUPT  constant binary_integer := 2; -- 00000010 

  -- B2 = 1 => More pages to come , = 0 => Last page.
  C_SERST_MORE_PAGES constant binary_integer := 4; -- 00000100 

  -- B3 = 1 => "ACK" Requested , = 0 => No "ACK" required.
  C_SERST_ACK        constant binary_integer := 8; -- 00001000

  -- B4 = 1 Schedule Mode Operation = 0 => No schedule operation.
  C_SERST_SCHEDULE   constant binary_integer := 16; --00010000
  --------------------------------------------------------------------             

  -- Scheduling constants for pages ----------------------------------               

  -- days of the week 
  C_SCHEDULE_MONDAY        constant binary_integer := 1;   -- 00000001
  C_SCHEDULE_TUESDAY       constant binary_integer := 2;   -- 00000010
  C_SCHEDULE_WEDNESDAY     constant binary_integer := 4;   -- 00000100
  C_SCHEDULE_THURSDAY      constant binary_integer := 8;   -- 00001000
  C_SCHEDULE_FRIDAY        constant binary_integer := 16;  -- 00010000
  C_SCHEDULE_SATURDAY      constant binary_integer := 32;  -- 00100000
  C_SCHEDULE_SUNDAY        constant binary_integer := 64;  -- 01000000
  C_SCHEDULE_ALL_WEEK_DAYS constant binary_integer := 128; -- 10000000
  --------------------------------------------------------------------             

  -- freezing time (TEMP0) constants ---------------------------------
  -- also defines scroll speed for bottom line (1- fastest, 9 - slowest)

  C_TEMP0_CONST_BITS constant raw(1) := hextoraw('C0'); -- 11000000
  C_TEMP0_AND_MASK   constant raw(1) := hextoraw('3F'); -- 00111111 

  C_SCROLL_SPEED_1 constant binary_integer := 1; -- 0000 0001
  C_SCROLL_SPEED_2 constant binary_integer := 2; -- 0000 0010
  C_SCROLL_SPEED_3 constant binary_integer := 3; -- 0000 0011
  C_SCROLL_SPEED_4 constant binary_integer := 4; -- 0000 0100
  C_SCROLL_SPEED_5 constant binary_integer := 5; -- 0000 0101
  C_SCROLL_SPEED_6 constant binary_integer := 6; -- 0000 0110
  C_SCROLL_SPEED_7 constant binary_integer := 7; -- 0000 0111
  C_SCROLL_SPEED_8 constant binary_integer := 8; -- 0000 1001
  C_SCROLL_SPEED_9 constant binary_integer := 9; -- 0000 1001

  C_DURATION_2_SEC   constant binary_integer := C_SCROLL_SPEED_1;
  C_DURATION_5_SEC   constant binary_integer := C_SCROLL_SPEED_2;
  C_DURATION_10_SEC  constant binary_integer := C_SCROLL_SPEED_3;
  C_DURATION_20_SEC  constant binary_integer := C_SCROLL_SPEED_4;
  C_DURATION_30_SEC  constant binary_integer := C_SCROLL_SPEED_5;
  C_DURATION_45_SEC  constant binary_integer := C_SCROLL_SPEED_6;
  C_DURATION_60_SEC  constant binary_integer := C_SCROLL_SPEED_7;
  C_DURATION_90_SEC  constant binary_integer := C_SCROLL_SPEED_8;
  C_DURATION_120_SEC constant binary_integer := C_SCROLL_SPEED_9;

  -- Constants for page schedule override   
  C_PAGE_STATUS_TIMER constant binary_integer := 0;  -- 00 00 0000 
  C_PAGE_STATUS_ON    constant binary_integer := 16; -- 00 01 0000
  C_PAGE_STATUS_OFF   constant binary_integer := 32; -- 00 10 0000
  --------------------------------------------------------------------             


  -- Function constants for pages ------------------------------------
  C_DISPLAY_MODE_RANDOM    constant binary_integer :=  0; -- 0000 0000
  C_DISPLAY_MODE_APPEAR    constant binary_integer :=  1; -- 0000 0001
  C_DISPLAY_MODE_WIPE      constant binary_integer :=  2; -- 0000 0010
  C_DISPLAY_MODE_OPEN      constant binary_integer :=  3; -- 0000 0011
  C_DISPLAY_MODE_LOCK      constant binary_integer :=  4; -- 0000 0100
  C_DISPLAY_MODE_ROTATE    constant binary_integer :=  5; -- 0000 0101
  C_DISPLAY_MODE_RIGHT     constant binary_integer :=  6; -- 0000 0110
  C_DISPLAY_MODE_LEFT      constant binary_integer :=  7; -- 0000 0111
  C_DISPLAY_MODE_ROLL_UP   constant binary_integer :=  8; -- 0000 1000
  C_DISPLAY_MODE_ROLL_DOWN constant binary_integer :=  9; -- 0000 1001
  C_DISPLAY_MODE_PING_PONG constant binary_integer := 10; -- 0000 1010
  C_DISPLAY_MODE_FILL_UP   constant binary_integer := 11; -- 0000 1011
  C_DISPLAY_MODE_PAINT     constant binary_integer := 12; -- 0000 1100
  C_DISPLAY_MODE_FADE_IN   constant binary_integer := 13; -- 0000 1101
  C_DISPLAY_MODE_JUMP      constant binary_integer := 14; -- 0000 1110
  C_DISPLAY_MODE_SLIDE     constant binary_integer := 15; -- 0000 1111

  -- display clock on top line
  C_DISPLAY_CLOCK       constant binary_integer := 16; -- 00010000
  -- display temperature on top line
  C_DISPLAY_TEMPERATURE constant binary_integer := 32; -- 00100000
  --------------------------------------------------------------------             

  -- Status constants for pages --------------------------------------
  C_LINES_1_2_JOIN_BOLD constant binary_integer := 1;  -- 0000 0001
  C_LINES_3_4_JOIN_BOLD constant binary_integer := 2;  -- 0000 0010
  C_LINES_5_6_JOIN_BOLD constant binary_integer := 4;  -- 0000 0100
  C_LINES_7_8_JOIN_BOLD constant binary_integer := 8;  -- 0000 1000

  C_AUTOCENTER_TEXT     constant binary_integer := 16; -- 0001 0000
  C_FOREIGN_LANGUAGE    constant binary_integer := 32; -- 0010 0000
  C_BACKGROUND_COLOR_ON constant binary_integer := 64; -- 0010 0000
  --------------------------------------------------------------------             

  -- Function returns escape sequence for switching to flash text.
  function StartFlashText      return varchar2;
  -- Function returns escape sequence for switching to enlarged text.
  function StartEnlargedText   return varchar2;
  -- Function returns escape sequence for switching text color to red.
  function StartRedText        return varchar2;
  -- Function returns escape sequence for switching text color to green.
  function StartGreenText      return varchar2;
  -- Function returns escape sequence for switching text color to yellow.
  function StartYellowText     return varchar2;
  -- Function returns escape sequence for switching to multicolored text
  function StartMulticolorText return varchar2;
  -- Function returns escape sequence for resetting text output parameters 
  -- to defaults: not enlarged, not flashing, red color
  function ResetToDefaultText  return varchar2;

  -- Function produces text for page header with given parameters
  -- %param pSignNumber Signboard address, 1 to 127 - for concrete signboard, 0 - send to all connected boards
  -- %param pLineCount  Number of lines on page to fit signboard, 1 - 255 (?)
  -- %param pSerstFlags Serial status flags (SERST), combination of:
  --                    C_SERST_INTERRUPT  -- Single exceptionally displayed page which interrupts normal schedule,
  --                                          only one page can be sent in this mode.
  --                    C_SERST_MORE_PAGES -- is current page NOT last
  --                    C_SERST_ACK        -- seems to be never used over tcp/ip
  --                    C_SERST_SCHEDULE   -- There are scheduling information present for this page
  -- %param pPageNumber Sequential page number, 0 - 999. Page number 0 reserved for time setting command.
  -- %return Text to concatenate with text of the page, use as pHeaderText parameter for MakePage function.
  function MakePageHeaderText(
    pSignNumber in binary_integer,
    pLineCount  in binary_integer,
    pSerstFlags in binary_integer,
    pPageNumber in binary_integer
  ) return varchar2;

  -- Returns text for Page 000 which sets system time on the board
  -- %param pDate date and time to set 
  function MakeTimeSetPageText(pDate in date) return varchar2;

  -- Return text for bytes 9-25 of regular page to describe scheduling information
  -- %param  pStart    start date and time to display page
  -- %param  pEnd      end date and time of displaying page
  -- %param  pWeekDays schedule page display by days of the week, combination of C_SCHEDULE_xxx constants
  -- %return Text to use with pScheduleText parameter of MakePage function 
  function MakeScheduleText(
    pStart    in date, 
    pEnd      in date,
    pWeekDays in binary_integer
  ) return varchar2;

  -- Returns text for TEMP0 byte which follows a header or scheduling information if specified
  -- %param  pDurationOrSpeed One of C_SCROLL_SPEED_x or C_DURATION_xxx constants. Set of constants
  --                            to choose from depends on C_DISPLAY_MODE_xxx specified for pDisplayMode 
  --                            parameter of MakeDisplayPageMode function (C_DISPLAY_MODE_SLIDE or others)
  -- %param pStatusMode       One of C_PAGE_STATUS_xxx constants controlling page usage.
  -- %return Text which must be included into page packet after scheduling information if cpecified 
  --           or header string
  function MakePageTemp0(
    pDurationOrSpeed in binary_integer,
    pStatusMode      in binary_integer
  ) return varchar2;


  -- Function makes string byte which 
  -- %param pDisplayMode        One of C_DISPLAY_MODE_xxx constants.
  -- %param pDisplayClock       True for display time on top of the screen
  -- %param pDisplayTemperature True for display temperature on top of the screen
  -- %return char which encodes function parameters and must be present after TEMP0 byte
  function MakePageDisplayMode(
    pDisplayMode        in binary_integer,
    pDisplayClock       in boolean,
    pDisplayTemperature in boolean
  ) return varchar2;

  -- Function encodes given display mode parameters to one char.
  -- %param  pJoinLines12        Join 2 first lines toghether for BOLD mode
  -- %param  pJoinLines34        Lines 3 and 4 joined for BOLD mode
  -- %param  pJoinLines56        Lines 5 and 6 joined for BOLD mode  
  -- %param  pJoinLines78        Lines 7 and 8 joined for BOLD mode
  -- %param  pAutoCenter         Text willbe centered on the screen
  -- %param  pUseForeignLanguage If true then page in foreign (not English) language
  -- %param  pUseBackgroundColor If true turns ON background colour 
  function MakePageStatus(
    pJoinLines12        in boolean,
    pJoinLines34        in boolean,
    pJoinLines56        in boolean,
    pJoinLines78        in boolean,
    pAutoCenter         in boolean,
    pUseForeignLanguage in boolean,
    pUseBackgroundColor in boolean 
  ) return varchar2; 

  -- Makes full page packet from header and text to send to device
  -- %param pHeaderText   Page header from MakePageHeaderText function        
  -- %param pScheduleText Page schedule settings from MakeScheduleText function.
  --                        Applicable only if C_SERST_SCHEDULE bit set in header
  -- %param pPageTemp0    Duration/speed and status information encoded by MakePageTemp0 function
  -- %param pDisplayMode  Display mode information encoded by MakePageDisplayMode function 
  -- %param pPageStatus   Page status modes encoded by MakePageStatus function
  -- %param pPageText     Text to display on the page with incorporated control bytes to switch
  --                      character color and appearence (C_xxx_TEXT) 
  -- %return Raw sequence of bytes including end-of-text flag and check sum,
  --                      which can be sent to device using SendPages() procedure
  function MakePage(
    pHeaderText   in varchar2,        
    pScheduleText in varchar2,
    pPageTemp0    in varchar2,
    pDisplayMode  in varchar2,
    pPageStatus   in varchar2,
    pPageText     in varchar2
  ) return raw;


  -- Make full page to set time and date on signboard
  -- %param  pSignNumber Signboard address, 1 to 127 - for concrete signboard, 0 - send to all connected boards
  -- %param  pDateTime   Date and time to set on signboard.
  -- %param  pIsLastPage Must be true if there are no other pages in the packet
  -- %return full raw page ready to be sent with SendPages() procedure.
  function MakeTimeSetPage(
    pSignNumber in binary_integer,
    pDateTime   in date, 
    pIsLastPage in boolean
  ) return raw;

  -- Procedure sends sequence of prepared pages to signboard through tcp/ip connection to WizNet device.
  -- %param pHost    Host address of WizNet device, e.g. '10.2.30.4'
  -- %param pPort    Port number  of WizNet device, usually 8000
  -- %param pPageSet Raw sequence of bytes to send. Contains concatenated output of MakePage() function.
  --                 Page with C_SERST_INTERRUPT flag set is a special case and must be sent alone. 
  procedure SendPages(
    pHost    in varchar2,
    pPort    in binary_integer,
    pPageSet in raw
  );


end;
/

实用程序包正文:

create or replace package body POLYCOMP_UTIL is

  -- PolyComp signboard interaction for Oracle

  -- Header Sync (byte #1)
  C_HEADER_SYNC constant char(1) := chr(0);

  -- Etx, End-of-Header (byte #4)
  C_HEADER_END  constant char(1) := chr(3); 

  -- End-of-text mark                                                       
  C_END_OF_TEXT constant char(1) := chr(4);

  -- SERST (Serial status flag byte #5 constants) --------------------
  -- Mask with fixed bits
  -- B0 , B5 = 0
  -- B6 – B7 All = 1.                              
  -- B7 B6 B5 B4 B3 B2 B1
  --  1  1  0  0  0  0  0
  C_SERST_CONST_BITS constant raw(1) := hextoraw('C0'); -- 11000000
  C_SERST_AND_MASK   constant raw(1) := hextoraw('1E'); -- 00011110
  --------------------------------------------------------------------             

  -- Function constants for pages ------------------------------------
  C_FUNCTION_CONST_BITS constant raw(1) := hextoraw('C0'); -- 11000000
  C_FUNCTION_AND_MASK   constant raw(1) := hextoraw('3F'); -- 00111111 
  --------------------------------------------------------------------             

  -- Status constants for pages --------------------------------------
  C_STATUS_CONST_BITS constant raw(1) := hextoraw('80'); -- 10000000
  C_STATUS_AND_MASK   constant raw(1) := hextoraw('7F'); -- 01111111 
  --------------------------------------------------------------------             

  -- Constants for changing text apperance with C_CONTROL symbol -----

  -- Escape symbol for control commands in message text
  C_CONTROL constant char(1) := chr(28);

  -- flash following text
  C_FLASH_TEXT      char(2) := C_CONTROL || 'F';
  -- enlarge following text
  C_ENLARGE_TEXT    char(2) := C_CONTROL || 'E';            
  -- display following text in red
  C_RED_TEXT        char(2) := C_CONTROL || 'R';
  -- display following text in green
  C_GREEN_TEXT      char(2) := C_CONTROL || 'G';
  -- display following text in yellow
  C_YELLOW_TEXT     char(2) := C_CONTROL || 'Y';
  -- display following text with multiple color (e.g. top - red, center - yellow, bottom - green)
  C_MULTICOLOR_TEXT char(2) := C_CONTROL || 'M';
  -- Restore default settings: not enlarged, not flashing, red.
  C_DEFAULT_TEXT    char(2) := C_CONTROL || 'D';
  --------------------------------------------------------------------             

  -- Function gets as parameter integer value which fits into 1 byte (0 <= pValue <= 255)
  -- and converts it into raw(1)
  function byte_to_raw(pValue in binary_integer) return raw
  is
  begin
    return utl_raw.substr( utl_raw.cast_from_binary_integer(pValue), 4, 1 );
  end;


  -- specification in package header
  function StartFlashText return varchar2
  is
  begin
    return C_FLASH_TEXT;
  end;

  -- specification in package header
  function StartEnlargedText return varchar2
  is
  begin
    return C_ENLARGE_TEXT;
  end;

  -- specification in package header
  function StartRedText return varchar2
  is
  begin
    return C_RED_TEXT;
  end;

  -- specification in package header
  function StartGreenText return varchar2
  is
  begin
    return C_GREEN_TEXT;
  end;

  -- specification in package header
  function StartYellowText return varchar2
  is
  begin
    return C_YELLOW_TEXT;
  end;

  -- specification in package header
  function StartMulticolorText return varchar2
  is
  begin
    return C_MULTICOLOR_TEXT;
  end;

  -- specification in package header
  function ResetToDefaultText return varchar2
  is
  begin
    return C_DEFAULT_TEXT;
  end;


  -- specification in package header
  function MakePageHeaderText(
    pSignNumber in binary_integer,
    pLineCount  in binary_integer,
    pSerstFlags in binary_integer,
    pPageNumber in binary_integer
  ) return varchar2
  is                       
    vSerstValue raw(1);
  begin                

    vSerstValue := byte_to_raw(pSerstFlags); 

    vSerstValue := utl_raw.bit_and(vSerstValue, C_SERST_AND_MASK);
    vSerstValue := utl_raw.bit_or(VserstValue, C_SERST_CONST_BITS);

    return C_HEADER_SYNC || chr(pLineCount) || chr(pSignNumber) || C_HEADER_END || 
           utl_raw.cast_to_varchar2(vSerstValue)|| ltrim(to_char(pPageNumber, '009'));  
  end;

  -- specification in package header
  function MakeTimeSetPageText(pDate in date) return varchar2
  is
  begin
    return to_char(pDate, 'hh24missddmmd');
  end;

  -- specification in package header
  function MakeScheduleText(
    pStart    in date, 
    pEnd      in date,
    pWeekDays in binary_integer
  ) return varchar2
  is
  begin
    return to_char(pStart,'ddmm') || to_char(pEnd, 'ddmm')  || 
           to_char(pStart,'hhmm') || to_char(pEnd,'hhmm')   ||
           chr(pWeekDays);
  end;


  -- specification in package header
  function MakePageTemp0(
    pDurationOrSpeed in binary_integer,
    pStatusMode      in binary_integer
  ) return varchar2
  is
    vValue raw(1);
  begin

    vValue := byte_to_raw(pDurationOrSpeed + pStatusMode);

    vValue := utl_raw.bit_and(vValue, C_TEMP0_AND_MASK);
    vValue := utl_raw.bit_or(vValue, C_TEMP0_CONST_BITS);

    return utl_raw.cast_to_varchar2(vValue);

  end;

  -- specification in package header
  function MakePageDisplayMode(
    pDisplayMode        in binary_integer,
    pDisplayClock       in boolean,
    pDisplayTemperature in boolean
  ) return varchar2
  is  
    vMode binary_integer;
    vValue raw(1);
  begin          

    vMode := pDisplayMode;
    if( pDisplayClock ) then 
      vMode := vMode + C_DISPLAY_CLOCK;
    end if;                            
    if( pDisplayTemperature ) then
      vMode := vMode + C_DISPLAY_TEMPERATURE;
    end if;

    vValue := byte_to_raw(vMode);

    vValue := utl_raw.bit_and(vValue, C_FUNCTION_AND_MASK);
    vValue := utl_raw.bit_or(vValue, C_FUNCTION_CONST_BITS);

    return utl_raw.cast_to_varchar2(vValue);

  end;

  -- specification in package header
  function MakePageStatus(
    pJoinLines12        in boolean,
    pJoinLines34        in boolean,
    pJoinLines56        in boolean,
    pJoinLines78        in boolean,
    pAutoCenter         in boolean,
    pUseForeignLanguage in boolean,
    pUseBackgroundColor in boolean 
  ) return varchar2
  is
    vStatus binary_integer;
    vValue  raw(1);
  begin
    vStatus := 0;

    if(pJoinLines12) then 
      vStatus := vStatus + C_LINES_1_2_JOIN_BOLD; 
    end if;
    if(pJoinLines34) then 
      vStatus := vStatus + C_LINES_3_4_JOIN_BOLD; 
    end if;
    if(pJoinLines56) then 
      vStatus := vStatus + C_LINES_5_6_JOIN_BOLD; 
    end if;
    if(pJoinLines78) then 
      vStatus := vStatus + C_LINES_7_8_JOIN_BOLD; 
    end if;
    if(pAutoCenter) then 
      vStatus := vStatus + C_AUTOCENTER_TEXT; 
    end if;
    if(pUseForeignLanguage) then 
      vStatus := vStatus + C_FOREIGN_LANGUAGE; 
    end if;                               
    if(pUseBackgroundColor) then
      vStatus := vStatus + C_BACKGROUND_COLOR_ON;
    end if;

    vValue := byte_to_raw(vStatus);

    vValue := utl_raw.bit_and(vValue, C_STATUS_AND_MASK);
    vValue := utl_raw.bit_or(vValue, C_STATUS_CONST_BITS);

    return utl_raw.cast_to_varchar2(vValue);

  end; 


  -- specification in package header
  function MakePage(
    pHeaderText   in varchar2,        
    pScheduleText in varchar2,
    pPageTemp0    in varchar2,
    pDisplayMode  in varchar2,
    pPageStatus   in varchar2,
    pPageText     in varchar2
  ) return raw
  is  
    vPage     raw(32565);
    vCheckSum raw(1) := hextoraw('00');
  begin              

    vPage := utl_raw.cast_to_raw( 
               pHeaderText || 
               pScheduleText || pPageTemp0 || pDisplayMode || pPageStatus || 
               pPageText || C_END_OF_TEXT
             );

    for i in 1 .. utl_raw.length(vPage) loop
      vCheckSum := utl_raw.bit_xor(vCheckSum, utl_raw.substr(vPage,i,1));
    end loop;                                

    return utl_raw.concat(vPage, vCheckSum);

  end;           

  -- specification in package header
  function MakeTimeSetPage(                                
    pSignNumber in binary_integer,
    pDateTime   in date, 
    pIsLastPage in boolean
  ) return raw
  is      
    vSerstValue binary_integer := C_SERST_SCHEDULE;
  begin                      

    if(not pIsLastPage) then 
      vSerstValue := vSerstValue + C_SERST_MORE_PAGES;
    end if;  

    return MakePage(
             pHeaderText   => MakePageHeaderText(
                                pSignNumber => pSignNumber,
                                pLineCount  => 0,
                                pSerstFlags => vSerstValue,
                                pPageNumber => 0  -- control page
                              ),
             pScheduleText => MakeTimeSetPageText(pDateTime),
             pPageTemp0    => null,
             pDisplayMode  => null,
             pPageStatus   => null,
             pPageText     => null
           );   

  end;


  -- specification in package header
  procedure SendPages(
    pHost    in varchar2,
    pPort    in binary_integer,
    pPageSet in raw
  )  
  is                                
    C_CHUNK_SIZE constant binary_integer := 16*1024*8; -- 16 KB

    vConn         UTL_TCP.Connection;                      
    vPagesLength  binary_integer;
    vRC           binary_integer;  
    vTimeout      binary_integer;
    vBytesSent    binary_integer;
    vCurChunkSize binary_integer;
  begin

    vPagesLength := utl_raw.length(pPageSet);

    -- Set timeout based on baud rate 9600 plus 256Kb tcp/ip network overhead and minimum at 10 seconds.
    -- Calculating timeout such a way assumes that no significant buffering performed at receiver which
    -- becomes true in case of WizNet device buffer overflow.
    -- Seems that oracle ignores timeout for write operation in current versions but anyway 
    -- this must be taken into account.  
    vTimeout := greatest(10, ceil( (C_CHUNK_SIZE*8*1.04)/(256*1024) ) + ceil( (C_CHUNK_SIZE*8)/9600 ) );

    vConn := UTL_TCP.open_connection (
               remote_host     => pHost,
               remote_port     => pPort,
               in_buffer_size  => 0,
               out_buffer_size => 16*1024*8, -- 16KB
               tx_timeout      => vTimeout
             );

     begin                                    

       vBytesSent := 0;

       while (vBytesSent < vPagesLength)  loop

         vCurChunkSize := least(C_CHUNK_SIZE, vPagesLength - vBytesSent);
         vRC := UTL_TCP.write_raw( 
                  vConn, 
                  utl_raw.substr(pPageSet, vBytesSent+1, vCurChunkSize), 
                  vCurChunkSize 
                );

         if(vRC < vCurChunkSize) then
           raise_application_error(-20001,
             'Error sending chunk: only ' || vRC || ' bytes out of ' || vCurChunkSize || ' sent.'
           );
         end if;                                               

         vBytesSent := vBytesSent + vCurChunkSize;

       end loop;

       UTL_TCP.Flush(vConn);
       UTL_TCP.close_connection(vConn);

     exception
       when others then begin
         UTL_TCP.close_connection(vConn);
         raise;
       end;
     end;

  end;

end;

/

以中断模式显示单页的示例:

declare
  vHeader      varchar2(10);
  vSchedule    varchar2(100);
  vTemp0       varchar2(1);
  vDisplayMode varchar2(1);
  vStatus      varchar2(1);
  vText        varchar2(32767);
  vPage        raw(32767);
begin
  vHeader := polycomp_util.MakePageHeaderText(1,1, polycomp_util.C_SERST_INTERRUPT, 1);
  vTemp0 := polycomp_util.MakePageTemp0(polycomp_util.C_SCROLL_SPEED_4, polycomp_util.C_PAGE_STATUS_ON);
  vDisplayMode := polycomp_util.MakePageDisplayMode(polycomp_util.C_DISPLAY_MODE_SLIDE, false, false);
  vStatus := polycomp_util.MakePageStatus(false, false, false, false, false, false, false);
  vText :=  polycomp_util.StartGreenText || '<-- SLIDING green TEXT -->';
  vPage := polycomp_util.MakePage(vHeader, null, vTemp0, vDisplayMode, vStatus, vText);
  polycomp_util.SendPages(vPage);
end;
于 2013-08-14T08:46:24.520 回答
0

我设法让它打印出字母“I”

   declare
      bt_conn   UTL_TCP.connection;
      retval    binary_integer;
      --l_sequence raw(32000) := hextoraw('000100031C4748454C4C4F041F');
      --l_sequence raw(32000) := hextoraw('005300031C44490445');
      l_sequence raw(32000) := hextoraw('005301031C444920202020202020202020202020202020202020202020201C44202020202020202020202020202020202020202020202020043C');
    begin

       bt_conn := UTL_TCP.open_connection (
                    remote_host     => '10.107.107.41',
                    remote_port     => 8000,
                    in_buffer_size  => 0,
                    out_buffer_size => 0,
                    tx_timeout      => 10
                  );

       begin
         retval := UTL_TCP.write_raw (bt_conn, l_sequence, utl_raw.length(l_sequence));

         UTL_TCP.close_connection (bt_conn);

       exception
         when others then begin
           UTL_TCP.close_connection (bt_conn);
           raise;
         end;
       end;

    end;
    /

现在尝试编写一些代码来填充字符串,然后执行校验和。然后我可能会变得有点勇敢,尝试打印不止一封信。

感谢您的帮助 ThinkJet :)

更新

我写了以下内容来做校验和

  function append_bitwise_xor(p_packet in raw) return raw is

    w_packet     raw(32000) := hextoraw(p_packet);
    w_sub_packet raw(32000) := null;
    w_str_1      raw(32000) := null;
  BEGIN

    w_sub_packet := w_packet;
    w_str_1      := substr(w_packet, 1, 2);      
    w_sub_packet := substr(w_sub_packet, 3, length(w_sub_packet) - 2);

    while length(w_sub_packet) > 0 loop

      w_str_1 := utl_raw.bit_xor(w_str_1, substr(w_sub_packet, 1, 2));
      w_sub_packet := substr(w_sub_packet, 3, length(w_sub_packet) - 2);

    end loop;

    --- w_str_1 is the checksum
    return w_packet || w_str_1;
  END;

我还用空格填充了消息,以匹配我更好地捕获的数据包

  function pad_line(p_text in varchar2, p_columns in number) return raw is

    w_text     varchar2(2000) := null;
    w_raw_text raw(32000) := null;
    w_columns  number;

  BEGIN

    w_text := p_text;
    select rawtohex(w_text) into w_raw_text from dual;
    w_columns := p_columns;

    while length(w_raw_text) < (2 * w_columns) loop

      select w_raw_text || rawtohex(' ') into w_raw_text from dual;

    end loop;

    return w_raw_text;

  END;

再次感谢您的帮助 ThinkJet - 它真的帮助了我们:)

于 2013-08-15T16:37:08.800 回答