0

I want to enter an IP address and a PORT number as positional arguments. Like this:

./client 127.0.0.1 12345

They pass, I check that they are correct (I solved this with two functions, whose arguments I passed as char *), and then I try to pass the IP address and PORT number to two variables. sin_port accepts the PORT number as a value, but s_addr doesn't accept the IP address (in principle). Like this:

int ret;
struct sockaddr_in servaddr;

servaddr.sin_addr.s_addr = inet_addr(argv[1]); //inet_addr accepts char*
servaddr.sin_port = htons (atoi(argv[2]));

// then

ret = connect (connSock, (struct sockaddr *) &servaddr, sizeof (servaddr));

And because of connect() the terminal don't do anything.

Any suggestions?

Thanks for answers!


Edit:

Here is the code of my client module:

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

// ./clientTest (távoli IP) (port)

#define MAX_BUFFER 1024
// #define MY_PORT_NUM 62324 /* This can be changed to suit the need and should be same in server and client */

int valid_digit(char *str)
{
    while (*str) {
        if (*str >= '0' && *str <= '9')
            ++str;
        else
            return 0;
    }
    return 1;
} // ha a string csak számokat tartalmaz, akkor a visszatérési érték TRUE, egyébként FALSE


int valid_ip(char *ip)
{
    int i, num, dots = 0;
    char *ptr;

    if (ip == NULL)
        return 0;

    ptr = strtok(ip, ".");

    if (ptr == NULL)
        return 0;

    while (ptr) {

        if (!valid_digit(ptr))
            return 0;

        num = atoi(ptr);

        if (num >= 0 && num <= 255) {
            ptr = strtok(NULL, ".");
            if (ptr != NULL)
                ++dots;
        } else
            return 0;
    }

    if (dots != 3)
        return 0;

    return 1;
}

int valid_port(char *port)
{

    int num;

    if (port == NULL)
    {
        return 0;
    }

    if (!valid_digit(port))
    {
        return 0;
    }

    num = atoi(port);

    if (num < 0 || num > 65535)
    {
        return 0;
    }
    return 1;
}

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

  if (argc > 1)
  {
    if (!valid_ip(argv[1]))
    {
      printf("HIBA: A megadott IP cím hibás!\n");
      return 0;
    }
    if (!valid_port(argv[2]))
    {
      printf("HIBA: A megadott PORT szám hibás!\n");
      return 0;
    }
  }



  int connSock, in, i, ret, flags;

  struct sockaddr_in servaddr;
  struct sctp_status status;

  char buffer[MAX_BUFFER + 1];
  int datalen = 0;

  connSock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);

  if (connSock == -1)
  {
      printf("Socket creation failed\n");
      perror("socket()");
      exit(1);
  }

  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons (atoi(argv[2]));
  if (inet_aton(argv[1], &servaddr.sin_addr) != 1)
  {
    fputs("Invalid IP address", stderr);
    return 1;
  }

  if ((connect(connSock, (struct sockaddr *) &servaddr, sizeof (servaddr))) == -1)
  {
    perror("ERROR connecting");
    close(connSock);
    return 1;
  }
  else
  {
    ret = connect(connSock, (struct sockaddr *) &servaddr, sizeof (servaddr));
  }

  if (ret == -1)
  {
      printf("Connection failed\n");
      perror("connect()");
      close(connSock);
      exit(1);
  }

  printf("Enter data to send: ");
  fgets(buffer, MAX_BUFFER, stdin);

  buffer[strcspn(buffer, "\r\n")] = 0;
  datalen = strlen(buffer);

  ret = sctp_sendmsg (connSock, (void *) buffer, (size_t) datalen,
        NULL, 0, 0, 0, 0, 0, 0);
  if(ret == -1 )
  {
    printf("Error in sctp_sendmsg\n");
    perror("sctp_sendmsg()");
  }
  else
      printf("Successfully sent %d bytes data to server\n", ret);

  close (connSock);

  return 0;
}

I drew a conslusion from information what Wireshark provided: it seems like the IP address argument doesn't pass correctly to the program. From Wireshark:

09 39.287070587 192.168.0.104 0.0.0.127 SCTP 82 INIT 3

Where 0.0.0.127 is the destination IP.

If you want my server code, then tell me.

4
  • It most certainly does do something. The connect call either succeeds or fails. With this code how can you possibly tell? Commented Mar 11, 2020 at 9:18
  • I edited my question. Commented Mar 11, 2020 at 14:24
  • run it through strace and inspect arguments and return codes there Commented Mar 11, 2020 at 14:53
  • From strace: socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP) = 3 connect(3, {sa_family=AF_INET, sin_port=htons(62324), sin_addr=inet_addr("0.0.0.127")}, 16 Commented Mar 11, 2020 at 15:38

2 Answers 2

1

You have to set sin_family, i.e.:

servaddr.sin_family = AF_INET;

Also, use inet_aton instead of inet_addr as it allows proper error handling:

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

int main (int argc, char* argv []) {
    if (argc < 3) {
        fprintf (stderr, "Usage: %s HOST PORT\n", argv [0]);
        return 1;
    }

    int connSock = socket(AF_INET, SOCK_STREAM, 0);
    if (connSock == -1) {
        perror ("Error creating TCP socket");
        return 1;
    }

    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;

    if(inet_aton(argv[1], &servaddr.sin_addr) != 1) {
        fputs ("Invalid IP address", stderr);
        return 1;
    }
    servaddr.sin_port = htons (atoi(argv[2]));

    if (connect (connSock, (struct sockaddr *) &servaddr, sizeof (servaddr)) == -1) {
        perror ("Error connecting");
        close (connSock);
        return 1;
    }

    puts ("Connection successful.");

    close (connSock);
    return 0;
}
Sign up to request clarification or add additional context in comments.

8 Comments

My code right now: bzero((void *) &servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; if(inet_aton(argv[1], &servaddr.sin_addr) != 1) { { fputs ("Invalid IP address", stderr); return 1; } servaddr.sin_port = htons (atoi(argv[2])); ret = connect (connSock, (struct sockaddr *) &servaddr, sizeof (servaddr)); But still nothing. Sorry for bad formatting.
Check the return value of connect, print an error message using errno. Wait until the connect timeout elapses and check the error. Use wireshark to see whether the initial connection packets are sent. Use nc (netcat) to check whether your computer can initiate that connection at all (firewalls etc).
1. errno gave Connection timeout() 2. From Wireshark: 109 39.287070587 192.168.0.104 0.0.0.127 SCTP 82 INIT 3. When I'm using servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); it works well.
I updated the code to a complete example including inet_aton, which works for me...
I checked arguments with strace and they are correct, but when it writes Connection refused and it gives an Error 37. And in order to when I merge my code (above) with your code, in strace the IP argument is messed up again.
|
0

Your valid_ip() functions alters argv[1] so that "127.0.0.1" becomes "127":

    ptr = strtok(ip, ".");

Use a prototype with const modifiers (e.g. int valid_port(char const *port)) and implement it so that it compiles without errors.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.