• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 284
  • Last Modified:

Perl Socket Problem!!!

Hi,

I have made a socket connection to another application A by using the Perl scripts.

After setting up the connection, I will first send data to application A.

Application A will process the data and return the result. But the time needed is variable.

I found the following problem in this suitation:

My perl script will be rut at WIN95 which has insallted Microsoft PWS and Activer Perl.
User opens the web-browser to run my Perl scripts. If the user press the stop button at the browser before the result return from Application A , I found the process of Perl is still running (ie. the socket connection hadn't been closed).

By pressing ALT+CTL+DELETE, I found the task Perl is still here.

I hope I can remove this task because I have limited the socket connection to application A not more than 3. If 3 users had pressed the stop button at the browser before closing the socket, the 4th users cannot make a connection anymore.

Can I do this?

Thank you very much
0
hon67
Asked:
hon67
  • 4
  • 4
  • 2
  • +1
1 Solution
 
guadalupeCommented:
What about a time out which is toward the top of the limit of your variable time response.
0
 
maneshrCommented:
can you send the code pl.?
0
 
guadalupeCommented:
Well first I need to see a little bit of you code...  How are you actually connecting to the socket?  IO::Socket?
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
hon67Author Commented:
Hi,

Below is the code I used:
-----------------------------------------------------------
#
# define constants for talking to server
#
$PACKIT = 'S n C4 x8';
$AF_INET = 2;
$SOCK_STR = 1;      # STREAMS
$DEF_PROTO = 0;      # default protocol of IP
$port = 1700 unless $port;

#
# Get the name of the server
#
($name, $aliases, $addrtype, $len, @addrs) = gethostbyname("testsock");
($a,$b,$c,$d) = unpack('C4',$addrs[0]);
print "Server Name=$name, Server Address= $a.$b.$c.$d <br>\n";
print "Port = $port <br>\n";
$that = pack($PACKIT,$AF_INET,$port,$a,$b,$c,$d);

select(CLIENT_SOCKET);
$| = 1;
select(stdout);

socket(CLIENT_SOCKET,$AF_INET,$SOCK_STR,$DEF_PROTO) ||
die "$0: Cannot open socket\n";
print "Created socket <br><br>\n";

#
# Attempt to connect to server.
#
do
{
      sleep(1);
      $result = connect(CLIENT_SOCKET,$that);
      if (result != 1) {
            print "Sleeping\n";
      }

} while ($result != 1);

#
# send data to server
#

$msg_size = 500;

$buf_sone = "DATASENDTOSERVER";
$rtn_sone = send(CLIENT_SOCKET , $buf_sone, 0);

$buf_rone = "";

do {
      sleep (1);
      ($rtn_rone = recv(CLIENT_SOCKET, $buf_rone, $msg_size, 0)) || die "recv:             $!\n";
      print "Waiting Response from Host<br>\n";

} while ($buf_rone eq "");

close(CLIENT_SOCKET);

exit 0;
-----------------------------------------------------------

Anything mistake I have made, if the server hadn't
send anything before I press the stop button at the browser, it seems the socket hadn't been closed.
0
 
maneshrCommented:
here what you need to do.

in # Attempt to connect to server.
section, change

if (result != 1) {

to

if ($result != 1) {



i have modified your program slightly to connect, from the command prompt to my webserver's port 80 & get the output. it works perfectly.

=====================================================
#
# define constants for talking to server
#
$PACKIT = 'S n C4 x8';
$AF_INET = 2;
$SOCK_STR = 1; # STREAMS
$DEF_PROTO = 0; # default protocol of IP
$port = 80 unless $port;

#
# Get the name of the server
#
($name, $aliases, $addrtype, $len, @addrs) = gethostbyname("sys08");
($a,$b,$c,$d) = unpack('C4',$addrs[0]);
print "Server Name=$name, Server Address= $a.$b.$c.$d <br>\n";
print "Port = $port <br>\n";
$that = pack($PACKIT,$AF_INET,$port,$a,$b,$c,$d);

select(CLIENT_SOCKET);
$| = 1;
select(stdout);

socket(CLIENT_SOCKET,$AF_INET,$SOCK_STR,$DEF_PROTO) ||
die "$0: Cannot open socket\n";
print "Created socket <br><br>\n";

#
# Attempt to connect to server.
#
do
{
sleep(1);
$result = connect(CLIENT_SOCKET,$that);

if ($result != 1) {      ## CHANGE THIS LINE

 print "$result Sleeping\n";
}

} while ($result != 1);

#
# send data to server
#

$msg_size = 500;

#$buf_sone = "DATASENDTOSERVER";
$buf_sone = "GET/HTTP 1.1\n"; ## FOR MY TESTING

$rtn_sone = send(CLIENT_SOCKET , $buf_sone, 0);

$buf_rone = "";

do {
sleep (1);
($rtn_rone = recv(CLIENT_SOCKET, $buf_rone, $msg_size, 0)) || die "recv: $!\n";
print "Waiting Response from Host<br>\n";

} while ($buf_rone eq "");

close(CLIENT_SOCKET);

print $rtn_rone,"\n"; ## FOR MY TESTING. THIS SHOWS THE ACTUAL INFO
exit 0;
0
 
hon67Author Commented:
Dear maneshr,

I have already changed the code from to

if (result != 1) {  to  if ($result != 1) {

But the problem still exists.

If I have pressed the stop button at the browser before receiving any data from the server, I found the Perl task is still processing (it means the socket connection haven't been closed).

Further, I have limited the no. of connection to the server is 3.
If I have done the above procedure for 3 times, I cannot setup any conneciton further.

Thus, I want to know how can I close the socket connection if I just press the stop button at the browser if the perl script is still running.

Thanks
0
 
maneshrCommented:
does application A run on a webserver? Can you access that application by using something like http://www.xyz.com/applicationA??

if yes, i think i might have a way to get your program working.

pl. let me know
0
 
hon67Author Commented:
Dear manshr,

Application A is not a webserver.

This application is developed by Visual C++. It will listen any socket connection from my Perl Script only.

Can I solve my problem in this suitation?

Thanks
0
 
maneshrCommented:
i do realize that App A is not a webserver. what i would like to know is whether Application A RUNS ON a system which has a web server running on it??

Also is it at all possible for you to send me the .exe file(application a) or at least a smaller version of the same??

in your code tou have the foll segment...

#
# Get the name of the server
#
($name, $aliases, $addrtype, $len, @addrs) = gethostbyname("testsock");

The gethostbyname function gets host record given name. what it means is you are having a Web server running and you are trying to open a socket connection on THAT webserver to another application.
0
 
pitonyakCommented:

I believe that your problem has to do with how you receive the data... The code that I use works as follows:


here is some code that I use..

****************

#$s_handle = IO::Socket->new( PeerAddr => $Target_host,
#                             PeerPort => $Target_port,
#                             Domain   => AF_INET,
#                             Proto    => 'tcp');
#
$s_handle = IO::Socket::INET->new( PeerAddr => $Target_host,
                                   PeerPort => $Target_port,
                                   Proto    => 'tcp',
                                 );

if (!defined($s_handle)) {

    $my_log->write_log_level('F', 0, "Unable to create a tcp socket to $Target_host:$Target_port Because $!");
    die("Unable to create a tcp socket to $Target_host:$Target_port Because $!");

}


$s_handle->timeout($write_time_out);
$s_handle->autoflush();     # in case using an older version of IO::Socket which does not do this
select($s_handle); $| = 1; # Turn off I/O buffering on the TCP handle.
select(STDERR);  $| = 1; # Turn off I/O buffering on STDERR.
select(STDOUT);  $| = 1; # Turn off I/O buffering on STDOUT.

****************

You seem to have sending down, so how about receiving...

receive_line($s_handle, $read_time_out);

****************

sub receive_line
{
    my ($handle, $time_out) = @_;
    my $ret = undef;
    #
    # Look for a response
    #
    my($rmask, $emask) = ('', '');
    vec($rmask, fileno($handle), 1) = 1;
    vec($emask, fileno($handle), 1) = 1;

    my ($nfound, $timeleft) = select($rmask, undef, $emask, $time_out);
    $my_log->write_log_level('T', 20, "select found $nfound");
    if ($nfound < 0) {

        $my_log->write_log_level('F', 0, "select error = $!"); # get out

    } elsif ($nfound > 0) {

        if (vec($rmask, fileno($handle), 1) == 1) {

            $my_log->write_log_level('T', 50, "handle is ready for input");
            my $Bite = 4096;        # How much data to read at a time
            my $buf;
            my $bufsize = sysread($handle, $buf, $Bite);
            if ( $bufsize ) {

                $my_log->write_log_level('T', 15, 'R', $buf);
                $ret = $buf;

            } else {

                $my_log->write_log_level('T', 0, "Target closed the connection on handle - $!");
                shutdown($handle, 2);


            }

        } elsif (vec($emask, fileno($handle), 1) == 1) {

            $my_log->write_log_level('F', 0, "Exception on read_handle $!");

        }

    } else {

        $my_log->write_log_level('T', 75, "No response from target.");

    }
    return $ret;
}
0
 
hon67Author Commented:
Answer accepted
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

  • 4
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now