Solved

Send a number to a server and return a 'fortune' like the command and print it out

Posted on 2004-04-05
9
215 Views
Last Modified: 2010-04-15
Hi,
First of all, Yes, this is a class assignment.  I'm looking for back-up help if I cannot finish this in time.  I'm not a C programming expert and have little experience with the library.  Well, Im trying to create this program that sends a number to the Wisdom Server and writes to the standard output the wisdom returned.

I know I have to creat a socket and bind it  to the server on the port using gethostbyname() to get IP.  Then I think I have to connect() the send() then recv(), right?  Then, I have to write out what is returned to stdout.

Im getting the error:  : Transport endpoint is not connected

Also, we have been recently told that this server was built to be unstable.  Therefore, we must handle all problems that could occur. (disconnects/timeouts/etc)

I have just started and here is what I have.  I hope you are willing to help and give me some help with the library and functions.  Full details are at http://www.ccs.neu.edu/course/csu480/prog_getwis.html
Anyone who helps to successfully complete this will recieve an 'A' grade
thanks--

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


#define WISDOM_SERVER   "alshain.ccs.neu.edu"
#define WISDOM_PORT     7607    /* Wisdom servers listen here */
#define BUFF_SIZE 100

main(int argc,char* argv[]){

        int aSocket, connect, aNumber, send_bytes, send_len, recv_len, get_recv;                                // socket descriptor
        struct sockaddr_in serveraddr;          //struct will hold server IP and port
        struct hostent *hostPtr = NULL;
        char *string;
        char buffer[BUFF_SIZE];


        if(argc<2){
          fprintf(stderr,"usage: int\n");
        }

        string = argv[1];

        printf("The number entered is %s\n",string);

        // Create Socket and get Socket descriptot
        aSocket = socket(AF_INET,SOCK_STREAM,0);
        if(aSocket<0){
                perror("Socket\n");
                exit(1);
        }

        hostPtr= gethostbyname(WISDOM_SERVER);
        if(hostPtr == NULL){
          perror("gethostbyname");
          exit(1);
 }

        // Assign Variables in serveraddr values
        serveraddr.sin_family = AF_INET;                        //Adress Family Internet
        serveraddr.sin_port = htons(WISDOM_PORT);               //Host to Networ Short  has to be in network order
        serveraddr.sin_addr = *((struct in_addr *)hostPtr->h_addr); // get Ip and convert it
        memset(&(serveraddr.sin_zero),'\0',8);                  // zero the rest of the struct

        // Bind aSocket to the Struct
        //aBind = bind(aSocket, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr));
        //if(aBind<0){
        //perror("Bind\n");
        //exit(1);
        //}

        connect = (aSocket,(struct sockaddr *)&serveraddr, sizeof(serveraddr));
        if(connect<0){
          perror("Connect\n");
          exit(1);
        }
        send_len = strlen(string);
        send_bytes = send(aSocket,string,send_len,0);
        if(send_bytes <0){
          perror("Send\n");
          exit(1);
        }

        get_recv = (aSocket,buffer,BUFF_SIZE-1,0 );
        if(get_recv < 0){
          perror("recv()");
          exit(1);
        }

        buffer[get_recv]='\0';
        printf("Received %s ",buffer);
        close(aSocket);

}
 }

        // Assign Variables in serveraddr values
        serveraddr.sin_family = AF_INET;                        //Adress Family Internet
        serveraddr.sin_port = htons(WISDOM_PORT);               //Host to Networ Short  has to be in network order
        serveraddr.sin_addr = *((struct in_addr *)hostPtr->h_addr); // get Ip and convert it
        memset(&(serveraddr.sin_zero),'\0',8);                  // zero the rest of the struct

        // Bind aSocket to the Struct
        //aBind = bind(aSocket, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr));
        //if(aBind<0){
        //perror("Bind\n");
        //exit(1);
        //}

        connect = (aSocket,(struct sockaddr *)&serveraddr, sizeof(serveraddr));
        if(connect<0){
          perror("Connect\n");
          exit(1);
        }
        send_len = strlen(string);
        send_bytes = send(aSocket,string,send_len,0);
        if(send_bytes <0){
          perror("Send\n");
          exit(1);
        }

        get_recv = (aSocket,buffer,BUFF_SIZE-1,0 );
        if(get_recv < 0){
          perror("recv()");
          exit(1);
        }

        buffer[get_recv]='\0';
        printf("Received %s ",buffer);
        close(aSocket);

}
0
Comment
Question by:brianjv99
[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
  • 4
  • 4
9 Comments
 
LVL 45

Expert Comment

by:sunnycoder
ID: 10763157
Why are you connecting twice ?

You can use the same connection to communicate with the server ...

Also, it is nice if you point out the lines which are generating the error message
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 10763170
>Also, we have been recently told that this server was built to be unstable.  Therefore, we must handle all problems that
>could occur. (disconnects/timeouts/etc)

You are using TCP for connecting to the server ... TCP will handle timeouts and disconnects for you ... it is a reliable protocol ... However, if it cannot recover from the error, say sever is down and data cannot be sent, the system calls which you used will return error code ... e.g. send will return a -ve value ....

You need to build appropriate error handling in your program ... e.g.

if  ( send (...) < 1 ) { //recover from error by reconnecting or atleast print an error message
0
 
LVL 1

Assisted Solution

by:while_true
while_true earned 150 total points
ID: 10763857
You are not connected, when you are not calling the connect() function:

       connect = (aSocket,(struct sockaddr *)&serveraddr, sizeof(serveraddr));
        if(connect<0){
          perror("Connect\n");
          exit(1);
        }
 
Never use variables with the same name than functions !
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:brianjv99
ID: 10770218
Hi, Im now getting the message that the Wisdom server recieved som invalid input (some non- digits).  Im trying to find out if it only takes an int or what.  Thanks for the help so far -- youve been great.
Here is the bottom ahlf of the updated code:


 if(connect(aSocket,(struct sockaddr *)&serveraddr, sizeof(serveraddr))<0){
          perror("Connect\n");
          exit(1);
        }
        send_len = strlen(string);
        //      i = atoi(string);
        printf("stringVar=%s %d  ", string);

        send_bytes = send(aSocket,string,send_len,0);
        if(send_bytes <0){
          perror("Send\n");
          exit(1);
        }

        get_recv = recv(aSocket,buffer,BUFF_SIZE-1,0 );
        if(get_recv < 0){
          perror("recv()");
          exit(1);
        }

        buffer[get_recv]='\0';
        printf("Received %s ",buffer);
        close(aSocket);
0
 

Author Comment

by:brianjv99
ID: 10770963
Hello,
In this line:
send_bytes = send(aSocket,string,send_len,0);

I need the send_len to be the length of data in bytes.  That is a priority Item that I know is wrong right now.

for example, if I do

> getwis 17

i am not sending '17'  I am sending all these extra characters on the end like : '17&(^%&'

thanks
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 10771975
       string = argv[1];

        send_len = strlen(string);
       printf("stringVar=%s %d  ", string);   <<< two format specifiers and one argument ...
use       printf("stringVar=%s %d  ", string,send_len);
        send_bytes = send(aSocket,string,send_len,0);

rest looks OK to me ...
0
 

Author Comment

by:brianjv99
ID: 10779461
The only way I got it to work is to change this

send_bytes = send(aSocket,string,send_len,0);

to this

send_bytes = send(aSocket,string,send_len+6,0);

since it wants the length of the message in bytes...?  I dont know...
0
 
LVL 45

Accepted Solution

by:
sunnycoder earned 200 total points
ID: 10781053
Yes it wants the length of the message in bytes ... I guess you problem was this

consider string "17" ... it is stored as '1' '7' '\0'

strlen will return 2 ... send will send 2 characters ... '1' and '7'

at the receiving end, the buffer may be uninitialized and will simply store '1' '7' without the terminating '\0'

try sending strlen(string) + 1 bytes ... does it work then ?
0
 

Author Comment

by:brianjv99
ID: 10806608
yeah, the +1 works.
I added for timeouts and null messages recieved

Im splitting points here.  I think While_true made a very good correctionwhile sunny stuck with me for the haul.

thanks
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
First character of input string truncated with scanf 3 117
An API detour question 7 109
Bitwise and to sum elements 2 54
.NET Core supports which cell phone platforms? 3 38
Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

752 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