[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Trouble with sockets CGI program

Posted on 1999-01-07
4
Medium Priority
?
320 Views
Last Modified: 2013-12-26
I have written a rather simple C program to submit certain information to a CGI script. However, I have tried and the program fails to work properly... Are there any problems with the program which will affect its ability to send the information to the CGI script?
(The cgi script is located at: http://www-cgi.monash.edu.au/cgi-bin/cgiwrap/~tatjana/TestCGI, and all it does is print out the contents of the form passed to it, either GET or POST is supported. This program is meant to do exactly what the browser does, and send the information to the CGI script.)

Here is the program:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 80    /* the port client will be connecting to */

#define MAXDATASIZE 2000 /* max number of bytes we can get at once */

int main(int argc, char *argv[])
{
int sockfd, numbytes;
int len, bytes_sent, sent, total_sent = 0;
char buf[MAXDATASIZE];
struct hostent *he;
char *msg = "POST /cgi-bin/cgiwrap/~tatjana/TestAnswer HTTP/1.0\r\nContent_type:
application/x-www-form-urlencoded\r\nContent_length:52\r\n\r\nintlPrefix=%2B6100
4&TEL=%2B61000123454&Message=TEST2";
struct sockaddr_in their_addr; /* connector's address information */

if (argc != 2) {
     fprintf(stderr,"usage: client hostname\n");
     exit(1);
}

if ((he=gethostbyname(argv[1])) == NULL) {  /* get the host info */
      herror("gethostbyname");
      exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
      perror("socket");
      exit(1);
}

their_addr.sin_family = AF_INET;      /* host byte order */
their_addr.sin_port = htons(PORT);    /* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */

if (connect(sockfd, (struct sockaddr *)&their_addr, \
                             sizeof(struct sockaddr)) == -1) {
      perror("connect");
      exit(1);
}

len = strlen(msg);
bytes_sent = send(sockfd, msg, len, 0);
if (bytes_sent < len)
{
        total_sent += bytes_sent;
        sent = bytes_sent;
        do {
                len = strlen(msg);
                bytes_sent = send(sockfd, msg+sent, len, 0);
        } while (bytes_sent < len);
}
else
        total_sent = bytes_sent;
printf("\nBYTES SENT: %d", total_sent);
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
      perror("recv");
      exit(1);
}

buf[numbytes] = '\0';
printf("NUMBER OF BYTES RECEIVED: %d", numbytes);
printf("Received: %s",buf);
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
      perror("recv");
      exit(1);
}
close(sockfd);

return 0;
}

0
Comment
Question by:idek1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 2

Expert Comment

by:rdelfino
ID: 1295259

Instead of trying to receive all the response in one/two recv() call(s)
do the following to receive the server response

----8<----------

while ((numbytes = recv(sockfd, buf, MAXDATASIZE, 0)) > 0)
{
    /*
      do whatever you need with the buffer,
      I suggest you append the buffer to a file and procces the file
      after the loop ends
   */
}

close(sockfd);

----8<-----

this way you won't miss anything the server sends you.

I hope this helps

Reginaldo

0
 

Author Comment

by:idek1
ID: 1295260
rdelfino,
The code is appreciated, however, it only tunes up the receiving part of the program. I believe the problem must lie either in the sending part of the program or in the information being sent to the server...
At the moment, when the program is run, the server responds with "Bad Request, Your browser sent a query that this server could not understand."
When running the program I use command:
client www-cgi.monash.edu.au

0
 
LVL 2

Expert Comment

by:rdelfino
ID: 1295261

So the problem isn't a socket problem. It's a protocol error. The request you sent
to the server is not correct.

See RFC2068 for complete http1.1 specification. You can find it at

http://www.rfc-editor.org/

I hope now it helps

Reginaldo

0
 
LVL 3

Accepted Solution

by:
mliberi earned 400 total points
ID: 1295262
Yes, it is a protocol error.
You declared: char *msg=" ... Content_length:52 ..."

please replace the underscore with a minus.
So declare  : char *msg=" ... Content-length:52 ..."
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
Ready to get certified? Check out some courses that help you prepare for third-party exams.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question