-1

This is my C client code. Somehow it is not working. It worked when I tried with argument passing.
I want the program to ask user to give hostname then it will ask for portname and then the message to send:

Enter hostname: localhost
Enter portname: 56456
Enter message : Hi user
Enter message : What's up
Enter message : How are you

And once the host and port given it should not ask for again (until restart the program). I tried with do while loop, but it is not working. On server it will display the sent message

Here is my code:

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

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

//int main(int argc, char *argv[])
int main()
{
    char *argv[256];
    int argc;
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    printf("\n\nEnter Hostname\n\n");
    fgets(argv[0],256,stdin);
    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("Please enter the message: ");
    bzero(buffer,256);
    //buffer = tempFunc();
    fgets(buffer,255,stdin);
    printf("\n\nHere Goes the output\n%s",buffer);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    close(sockfd);
    return 0;

}
n0p
  • 3,399
  • 2
  • 29
  • 50
ninja.stop
  • 410
  • 1
  • 10
  • 24
  • The code does not match the given output. Where is the `do while` loop ? – n0p Sep 02 '14 at 12:12
  • I deleted this, if you want I will add it – ninja.stop Sep 02 '14 at 12:13
  • Have you try using a multiplexor like select, poll or epoll. You should read about that, because simplifies this task a lot. – Mauro Bilotti Sep 02 '14 at 12:16
  • @MauroBilotti Don't know about these things. can you please give me some tutorial so that I can try out :) – ninja.stop Sep 02 '14 at 12:21
  • You don't want to re-declare `argc` and `argv` within your main, plus `argv` type is not what you want: you should use `char buffer[256]` to get the hostname – n0p Sep 02 '14 at 12:22
  • You are aware that you are declaring argv as an array of 256 pointers to char, not a pointer to a 256-element char array right? This issue has been on stackoverflow before, but I don't want to create an answer just for this, so I'll repeat: char *argv[256] is an array of 256 char pointers, char (*argv)[256] is a pointer to a 256-element char array. The way you declare it, argv[0] should be a char pointer to a random location. – midor Sep 02 '14 at 12:25
  • @Coconop I did `//char *argv[256]; //int argc;` and did `printf("\n\nEnter Hostname\n\n"); fgets(buffer,256,stdin);` Error: `client.c -o client client.c: In function ‘main’: client.c:28:9: error: ‘argc’ undeclared (first use in this function) if (argc < 3) { ^ client.c:28:9: note: each undeclared identifier is reported only once for each function it appears in client.c:29:51: error: ‘argv’ undeclared (first use in this function) fprintf(stderr,"usage %s hostname port\n", argv[0]); ` – ninja.stop Sep 02 '14 at 12:30
  • this is the bible of socket programming. It requieres some effort but is very good explained. http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html – Mauro Bilotti Sep 02 '14 at 12:35
  • When reading from and/or writing to a TCP stream **always** check the result of `read()`/`write()` `recv()`/`send()`! Those functions do **not** necessarily transfer the amount of bytes the where told to! – alk Sep 02 '14 at 16:35

4 Answers4

2

Let's fix some basic things first.
Your argv was an array of pointers, pointing to some arbitrary place in memory, here your program could crash.
Next thing is, when you're reading input with fgets, you are reading the \n, too. So localhost\n isn't a valid hostname. Overwrite the last character with an binary zero, to remove the \n.

int main()
{

    char hostname[256];
    char port[16];
    char buffer[256];
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    printf("\n\nEnter Hostname\n\n");
    fgets(hostname, 256,stdin);

    hostname[ strlen(hostname) - 1 ] = '\0';
    fgets(port, 16, stdin);
    port[ strlen(port) - 1] = '\0';

    portno = atoi(port);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(hostname);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
    exit(0);
    //...
}
robin.koch
  • 1,223
  • 1
  • 13
  • 20
2

First, do not use char * argv[256]

char buffer[256];
printf("\n\nEnter Hostname\n\n");
fgets(buffer,256,stdin);

Then check Removing trailing newline character from fgets() input to deal with fgets.

For an infinite loop, don't do

int a=2; // Useless declaration
do
{
    // Your code
}while(a=2) // I guess you wanted (a == 2)

use:

while(1)
{
    // Your code
}

Or

for(;;)
{
    // Your code
}

It seems that you need a little bit of training, try some tutorials, look for good practices in C, enable warning flags on compilation and learn to use a debugger like gdb.

P.S:

Community
  • 1
  • 1
n0p
  • 3,399
  • 2
  • 29
  • 50
0

For command line argument you should not declare argc and argv again! Try this-

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

void error(const char *msg)
{
        perror(msg);
        exit(0);
}

int main(int argc, char *argv[])
{
        int sockfd, portno, n;
        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("Please enter the message: ");
        bzero(buffer,256);
        //buffer = tempFunc();
        fgets(buffer,255,stdin);
        printf("\n\nHere Goes the output\n%s",buffer);
        n = write(sockfd,buffer,strlen(buffer));
        if (n < 0)
                error("ERROR writing to socket");
        bzero(buffer,256);
        n = read(sockfd,buffer,255);
        if (n < 0)
                error("ERROR reading from socket");
        printf("%s\n",buffer);
        close(sockfd);
        return 0;

}

and add the do while loop where you want!

Sathish
  • 3,740
  • 1
  • 17
  • 28
-1

Here is the code that works with loop. Thanks to @Coconop

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

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main()
{

    char hostname[256];
    char port[16];
    char buffer[256];
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    printf("\n\nEnter Hostname\n\n");
    fgets(hostname, 256,stdin);

    hostname[ strlen(hostname) - 1 ] = '\0';
    fgets(port, 16, stdin);
    port[ strlen(port) - 1] = '\0';

    portno = atoi(port);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(hostname);
    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");
int a=2;
do {
    printf("Please enter the message: ");
    bzero(buffer,256);
    //buffer = tempFunc();
    fgets(buffer,255,stdin);
    printf("\n\nHere Goes the output\n%s",buffer);
    n = write(sockfd,buffer,strlen(buffer));
}while(a=2);
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    close(sockfd);
    return 0;

}

ninja.stop
  • 410
  • 1
  • 10
  • 24
  • If it solved your issue you should accept a proposed answer and delete this one. Also note that the `do while` loop is useless as `a` is not modified within the loop – n0p Sep 02 '14 at 13:00
  • @Coconop I want an infinite loop for that reason I did this and the desired output is correct – ninja.stop Sep 02 '14 at 13:04
  • 1
    Anyway, you should not post your own answer if it is based on someone's answer, only if it brings something new. To add precision about your question you can `edit` your post. Upvote all the answers that helped you solve your problem and accept the more useful. – n0p Sep 02 '14 at 13:16
  • @Coconop I have thanked you upvoted you, mentioned you as helping me to do this. Even in my answer and comment I said what I added. I posted it to show as complete answer so that anyone might want it will get it. I didn't edit my problem, and why should I? rather posted as a solution. It is not that I rejected your answer and posted mine as if I am the sole owner of this. I am not getting really logic behind this comment. – ninja.stop Sep 02 '14 at 17:05
  • 1
    Don't get me wrong, I just want to explain you how StackOverflow works. I am grateful you thanked and cited me but on this site you express that by upvote and/or accept, people don't post their fixed code as an answer and they edit their question to precise the problem. I'm glad we fixed yours and I wish you the best on this site :) – n0p Sep 02 '14 at 22:47
  • @Coconop Anyways, I just felt I should contribute back to the community from where I got help :) – ninja.stop Sep 03 '14 at 05:41