Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

zOS tcp network socket not receiving data

Status
Not open for further replies.

barrygstl

Technical User
Sep 14, 2005
3
US
I have a REXX exec on z/OS 1.4 that is sending information to a Perl program on a UNIX box. The listening program on the UNIX box is sending an acknowledgement message back down the socket. My REXX program does not get the response. Can anyone help me?

Here is the program:
*****************************************************
/**
=== mf2ito - Send error notifications to ito using network socket.
=== (If ito does not return an ack, then to symon and console).
===
===
=== +---- GROUP(misc) ----------+
=== mf2ito --->+---------------------------+--->
=== +---- GROUP(mq) ------------+
===
=== +---- SEV(1) ---------------+ (normal)
=== +---------------------------+--->
=== +---- SEV(2) ---------------+ (warning)
=== +---- SEV(3) ---------------+ (minor)
=== +---- SEV(4) ---------------+ (major)
=== +---- SEV(5) ---------------+ (critical)
===
=== +---------------------------+--->
=== +---- APPL(?) --------------+
===
=== +---------------------------+--->
=== +---- NODE(?) --------------+
===
=== +---------------------------+--->
=== +---- OBJ(?) ---------------+
===
=== +---- MSG(TEXT) ------------+
===
===
=== Change history:
=== 09/01/2005 (bag) - Copied from SYMONSAY script.
=== 09/01/2005 (bag) - Straighten out the socket calls, get
=== positive acknowledgement from listener.
**/

host = "xxxxxxxx.ameren.com"
port = "99999"
dlm = " ~%~ "

say "Sending message to ito(" host":"port")"
parse upper arg text
parse var text "SEV("sev")"
parse var text "GROUP("grp")"
parse var text "MSG("msg")"
parse var text "APPL("appl")"
parse var text "NODE("node")"
parse var text "OBJ("obj")"

/**
*** Parse SEVERITY field
**/
select
when sev = "5" then xsev = "critical"
when sev = "4" then xsev = "major"
when sev = "3" then xsev = "minor"
when sev = "2" then xsev = "warning"
when sev = "1" then xsev = "normal"
otherwise do
sev = 1
xsev = "normal"
end
end

/**
*** Parse MESSAGE GROUP field
**/
select
when grp = "MQ" then xgrp = "MQSeries"
otherwise xgrp = "misc"
end

/**
*** Parse NODE field
**/
select
when node = "" then xnode = "abcd"
otherwise xnode = node
end

/**
=== Message parsed -- put it together
**/
string = xgrp || dlm || xsev || dlm || appl || dlm || xnode || dlm
string = string || dlm || obj || dlm || msg
say "String is:" string

/**
=== Message ready -- send it over the socket
**/

/* verify the the socket is closed */
result = Socket('Terminate')

/* Set error code values */
initialized = 0

/* Initialize */
result = Socket('Initialize','RSCLIENT',2)
parse var result src rest
say "Socket initialize ("result")"

/* check the socket return code */
if src=0 then initialized = 1 else exit 1

/* Initialize for receiving lines sent by the server */
result = Socket('Socket',2,'SOCK_STREAM','TCP')
say "Socket set to TCP/STREAM mode ("result")"
parse var result src sid rest

/* Setup the mainframe TCP/IP to use EBCDIC to ASCII conversion */
say "Socket set for ASCII translation ("result")"
result = Socket('Setsockopt', sid,'SOL_SOCKET', 'SO_ASCII','On')
parse var result src rest

result = Socket('Socketsetstatus','RSCLIENT')
say "Socket status is ("result")"

/* Connect to the Network IP socket */
result = Socket('Connect',sid,'AF_INET' port host)
parse var result src rest
say "Socket connect ("result")"
if src^=0 then exit 1

/* send the single line message */
result = Socket('Send',sid,string)
say "Socket send ("result")"

selectlist = 'Read' sid 'Write' 'Exception'
elapsed = 0
seconds = 5
say "Select List=("selectlist")"
do i = 1 to 6 by 1
elapsed = elapsed + seconds
result = Socket('Select',selectlist,seconds)
say i") Socket select ("result") elapsed="elapsed "seconds"
parse var rsn knt rest
if knt > 0 then leave
end
if knt > 0 then do
result = Socket('Read',sid)
parse var result
say "Socket read ("result")"
end
else do
say "Error--Time out waiting for acknowledgement"
end

/* Terminate and exit */
result = Socket('Close',sid)
say "Socket close ("result")"
result = Socket('Terminate')
say "Socket terminate ("result")"
exit 0
*********************************************
Here is the output:
*********************************************
Sending message to ito( sitop1.ameren.com:28985)
String is: MQSeries :%: normal :%: :%: SYSC :%: :%: :%: THIS IS A TEST.
Socket initialize (0 RSCLIENT 2 *INET)
***
Socket set to TCP/STREAM mode (0 1)
Socket set for ASCII translation (0 1)
Socket status is (0 RSCLIENT Connected Free 1 Used 1)
Socket connect (0)
Socket send (0 63)
Select List=(Read 1 Write Exception)
1) Socket select (0 0 READ WRITE EXCEPTION) elapsed=5 seconds
2) Socket select (0 0 READ WRITE EXCEPTION) elapsed=10 seconds
3) Socket select (0 0 READ WRITE EXCEPTION) elapsed=15 seconds
4) Socket select (0 0 READ WRITE EXCEPTION) elapsed=20 seconds
5) Socket select (0 0 READ WRITE EXCEPTION) elapsed=25 seconds
6) Socket select (0 0 READ WRITE EXCEPTION) elapsed=30 seconds
Error--Time out waiting for acknowledgement
Socket close (0)
Socket terminate (0 RSCLIENT)
***

Thank you,
Barry
*
* Barry Goldstein
* Ameren Services
* St. Louis, Missouri
* bgoldstein@ameren.com
* (314) 554-4351
*
 
You aren't trying to talk to the MQ Listener on the UNIX box are you?
 

No. The listener is a Perl program running on a UNIX box. It is designed to take the input data and call opcmsg to send an alert to ITO. The only relation to Mqseries is that our mainframe Mqseries monitoring tool will be sending the messages to ITO.

I can and will provide the source of the Perl program below.

Thank you for your response.


use IO::Socket;

$SIG{INT} = sub { print_LOG ("Exiting on signal."); close $rSock; exit 0; };

$port = 28985;
$log = "/tmp/socket_listen.log";
$debug = 0;
$continue = 1;
$opcmsg = "/opt/OV/bin/OpC/opcmsg";

openListener();

# Loop forever
while ($continue)
{
$mySock = $rSock->accept;
$mySock->autoflush(1);
print_LOG ("Accepted connection.");
print_LOG ("Waiting in process for data or socket close...");
while (<$mySock>)
{
chomp;
s/^M//g;
print_LOG ("Packet: $_");
$rc = handle_packet($_);

if ( $rc == 0 )
{
print $mySock "ACK\r\n";
}
else
{
print $mySock "NAK\r\n";
}
if ( /^bye.$/i || /^quit.$/i )
{
close $mySock;
undef $mySock;
}
}
print_LOG ("Closing connection...");
close $mySock if ( defined $mySock );
}

close $rSock;

############################################################
############################################################
#
# Supporting Routines
#
############################################################
############################################################

#=============================================#
# Open Listening Socket #
#=============================================#
sub openListener {
my $count = 0;
my $max = 30;
my $wait_time_between_tries = 10;

while (! defined $rSock)
{
$count++;
last if ( $count > $max );

print_LOG ("Opening Socket on port $port");
$rSock = IO::Socket::INET->new(Listen => 1,
LocalAddr => "",
LocalPort => $port,
Proto => 'tcp');

return if ( defined $rSock );
print_LOG ("Humm, socket may be in use... waiting $wait_time_between_tr
ies seconds...");
sleep $wait_time_between_tries;
}
die "Unable to connect on port $port - $!";
}

#=============================================#
# Write log file entry
#=============================================#
sub print_LOG
{
my ($msg) = @_;

my $now = localtime();
open (LOG,">>$log");
print LOG "$now: $msg\n";
print "$now: $msg\n" if ( $debug );
close LOG;

}

#=============================================#
# Handle the packet converting to opcmsg
#=============================================#
sub handle_packet
{
my ($msg_grp,$sev,$appl,$node,$obj,$msg_text) = split (/ ~%~ /,$_[0],6);
my $cmd;
my $result;
my $rc = 0;

# validate that node is in OVO
if ( ! valid_node($node) )

 
I have solved this problem. I ended up opening a problem with IBM and getting a component trace. The trace showed that the reply message was not being received until I closed the socket on the zOS side.

Here is the situation:
(1) Connect to a remote socket from zOS to Solaris.
(2) Send a message without a "CR/LF".
At this point something on the zOS side must have been hung up waiting for the end of the message.
(3) The message is received on remote system.
(4) The listener on the remote system reads the message and sends a reply.
(5) The reply does not reach the application until the socket is closed, freeing up the hang condition.

Sending the "CR/LF" in step 2 avoids the hung condition and the message is received quickly after being sent by the remote listener program.

I saw nothing in the TCP/IP API manual stating that TCP/IP stream communications are record oriented. I thought it was a byte-by-byte stream and would not wait for an "end of message/record" indication.

The good news is that my program is now working as expected. :)

Thank you,
Barry
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top