Beefy Boxes and Bandwidth Generously Provided by pair Networks vroom
Just another Perl shrine
 
PerlMonks  

C Client / Perl Server incompatibility

by Magius_AR (Sexton)
on Dec 08, 2000 at 05:42 UTC ( #45667=perlquestion: print w/ replies, xml ) Need Help??
Magius_AR has asked for the wisdom of the Perl Monks concerning the following question:

I can't seem to get my Perl server to communicate with a given client. I'm using Socket.pm and the socket gets set up fine and it tells me that a connection is made. However, when trying to send an integer value to the C client from the Perl server, it chokes. Anybody had a problem like this? Incompatability between Perl server and C client?

Specifics:
C Client never gets past this line: len = read(sockfd,buffer,2);
Perl Server gets past this line: print $remote "$length\n";
and it locks on the next one: print $remote "$fortunes[$num]\n";

Help would be much appreciated,
Thanks, Magius_AR

Comment on C Client / Perl Server incompatibility
Select or Download Code
Re: C Client / Perl Server incompatibility
by rpc (Monk) on Dec 08, 2000 at 06:24 UTC
    In a network model, there are no compatability issues between programming languages, only protocols.

    Is any data transferred at all? You might also want to try changing the number of bytes to read() to 1, and putting it inside of a while() loop. Automatically print out received data. Maybe even set up a sniffer to see if the client is sending data, though that shouldn't be necessary. I don't believe your problem is in either the read() nor the print()..

Re: C Client / Perl Server incompatibility
by AgentM (Curate) on Dec 08, 2000 at 06:42 UTC
    Your problem has probably very little to do with a Perl/C conflict since Socket.pm must use C libs to access various protocols and functions. If you can, try testing both client and server on the same machine. What chokes? server or client? how do you know it chokes? Socket is a thoroughly-tested interface to the C libs, so I doubt your problem lies within. Double-check your protocol choice. The sample code you provide isn't very enlightening. If you like, you can /msg me and I can help you further with with sockets or buy "UNIX Network Programming" or "Perl Cookbook" to help you. In any case, you should be able to tell if the packet is going through at all at least by testing the server after blocked input (which you seem to be using).
    AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.
Re: C Client / Perl Server incompatibility
by Magius_AR (Sexton) on Dec 08, 2000 at 06:50 UTC
    ok, for the sake of frustration, I'll just post the whole damn thing. The client can _NOT_ be changed. The Perl server must somehow be altered so that the sockets will work.

    C Client

    #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> void error(char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n,len,len1; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } portno = atoi(argv[2]); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr) +) < 0) error("ERROR connecting"); printf("Welcome to Fortune Teller Client\n"); printf("Please enter a command GET or BYE: "); bzero(buffer,256); fgets(buffer,255,stdin); while ((buffer[0]=='G') &&(buffer[1]=='E') && (buffer[2]=='T')) { n = write(sockfd,"GET",strlen("GET")); if (n < 0) error("ERROR writing to socket"); bzero(buffer,256); len = read(sockfd,buffer,2);exit(0); if (len < 0) error("ERROR reading from socket"); printf("Welcome to Fortune Teller Client\n"); printf("Please enter a command GET or BYE: "); bzero(buffer,256); fgets(buffer,255,stdin); while ((buffer[0]=='G') &&(buffer[1]=='E') && (buffer[2]=='T')) { n = write(sockfd,"GET",strlen("GET")); if (n < 0) error("ERROR writing to socket"); bzero(buffer,256); len = read(sockfd,buffer,2);exit(0); if (len < 0) error("ERROR reading from socket"); sscanf(buffer,"%d",&len1); bzero(buffer,256); n = read(sockfd,buffer,len1); printf("Your Fortune from the Fortune Server is \n"); printf("%s\n",buffer); bzero(buffer,256); printf("Next Command Please: (GET or BYE)\n"); fgets(buffer,255,stdin); } write(sockfd,"BYE",3); return 0; }
    Perl Server
    #!/usr/bin/perl use IO::Socket; @ARGV == 1 || die "usage: $0 port\n"; if ($ARGV[0] < 1 || $ARGV[0] > 65535) { die "$ARGV[0] is not a valid p +ort\n"; } my ($port) = @ARGV; open(FILE,"fortunes"); while ($fortune = <FILE>) { chomp($fortune); push @fortunes,$fortune; $db_size++; } close(FILE); if (!$db_size) { die "fortunes file is empty\n"; } my $server = IO::Socket::INET->new( Listen => SOMAXCONN, LocalPort => $port, Reuse => 1, Proto => 'tcp' ) || die "can't open server socket connection: $!"; while (defined($remote = $server->accept)) { # accept multiple clients $remote->autoflush(1); $hostinfo = gethostbyaddr($remote->peeraddr, AF_INET); print STDERR "[Received connection from ", $hostinfo || $remote->p +eerhost," on $port]\n"; while (<$remote>) # listen on command channel { if (/GET/i) { srand; # seed the random numb +er function $num = int (rand $db_size); # get a random fortune $length = length($fortunes[$num]); if ($length < 10 || $length > 99) { $fortune = "Your f +ortune was not of valid length."; } print $remote "$length\n"; print $remote "$fortunes[$num]\n"; } elsif (/BYE/i) { close($remote); } } }

      You might try running the server and telnetting to the appropriate port to see if you get the output you're expecting. I just did so (under Win32) and was able to get fortunes... Looks like a closer look at what the C code is sending/expecting might be in order.

Re: C Client / Perl Server incompatibility
by dws (Chancellor) on Dec 08, 2000 at 07:02 UTC
    Are you sure you have the handshake right? After sending "GET", the client expects a 2 byte response ("\r\n"?), which it discards. Your server isn't sending one.
Re: C Client / Perl Server incompatibility
by Magius_AR (Sexton) on Dec 08, 2000 at 09:05 UTC
    the 2 byte response is the length, and yes it does send it.

    The problem (one of my friends found it out) is in buffering...had to switch the print statement to syswrite and the <$server> to sysread.

    Afterwards it worked beautifully. (wish I had known of those functions beforehand :)

    Thanx anyways.

Re: C Client / Perl Server incompatibility
by zigster (Hermit) on Dec 08, 2000 at 15:19 UTC
    The problems is because your C code is not sending a newline, yet in the perl server you are reading with '<>' the '<>' reads a line without the \n it keeps on reading. Change the server to use sysread rather than <>. You always send 3 chars so just sysread 3 chars. UPDATE: The c code looks 'odd' OK: You have two loops reading G E T within each other .. this cant be right. The outer loop does nothing? Other than cause the ip to be entered twice and print the greeting twice. There are a couple of lines: len = read(sockfd,buffer,2);exit(0); This aint perl toto that will read from the socket and exit at once. No unless or || here dude. Is this a cut and paste error? Removing the exits makes the c work after a fashion, but it will still print odd greetings. Sorry to break this to you but it looks like the C code is broken as well, although it does look like cut and paste problems.
    --

    Zigster

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://45667]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2014-04-17 02:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (437 votes), past polls