简体   繁体   中英

connect() function taking too long

When I type in to the terminal:

echo "GET /" | ./<executable name> www.google.com <port number, usually 80>

the terminal just sits there like it's waiting for input or it's stuck in an infinite loop. What is happening is that connection is taking too long I think.

  /*Creating socket*/
  int sock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
  if (sock < 0) {
    printf("error creating socket\n");
    exit(1);
  }
  printf("1\n");
  /*Establish connection to the echo server*/
  int r = connect(sock, addrList->ai_addr, addrList->ai_addrlen);
  printf("1.5\n");
  if (r < 0) {
    perror("Connection failed\n");
    exit(1);
  }
  printf("2\n");

Here, the 1 prints out, but the 1.5 right after the connect doesn't print out and the terminal just sits.

This problem didn't happen before and I used to get the page's source code back instantly. But now this problem is occurring.

It started occurring after I typed in to the terminal: netstat -an -A inet | grep :2525 netstat -an -A inet | grep :2525

so this may have had an effect.

Here is the entire code:

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

int main(int argc, char *argv[]) {
  if (argc != 3) {
    printf("Invalid arguments\n");
    exit(1);
  }

  char *serverIP = argv[1]; /*Server hostname*/
  char *portNumber = argv[2]; /*Port Number*/
  void *numericAddress;
  char addrBuffer[INET6_ADDRSTRLEN];
  in_port_t port;
  char buffer_stdin[65535];
  char buffer_stdout[65535];
  int bytes_read = 0;
  int bytes_written = 0;

  /*getting integral number of string representation of port number*/
  in_port_t servPort = atoi(argv[2]);

  /*------------------get binary number of hostname-----------------*/
  struct addrinfo addrCriteria;
  memset(&addrCriteria, 0, sizeof(addrCriteria));
  addrCriteria.ai_family = AF_INET;
  addrCriteria.ai_socktype = SOCK_STREAM;
  addrCriteria.ai_protocol = IPPROTO_TCP;

  struct addrinfo *addrList;

  int rtnVal = getaddrinfo(serverIP, portNumber, &addrCriteria, &addrList);
  if (rtnVal != 0) {
    printf("getaddrinfo() failed\n");
    exit(1);
  }

  numericAddress = &((struct sockaddr_in *) (addrList->ai_addr))->sin_addr;
  /*Converting port to binary*/
  ((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htonl(servPort);
  /*----------------------------------------------------------------*/

  inet_ntop(addrList->ai_addr->sa_family, numericAddress, addrBuffer, sizeof(addrBuffer));
  printf("IP ADDRESS: %s\n", addrBuffer);

  /*Creating socket*/
  int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sock < 0) {
    printf("error creating socket\n");
    exit(1);
  }
  /*printf("1\n");*/
  /*Establish connection to the echo server*/
  int r = connect(sock, addrList->ai_addr, addrList->ai_addrlen);
  printf("%d\n", r);
  if (r < 0) {
    perror("Connection failed\n");
    exit(1);
  }
  printf("2\n");
  /*Reading from stdin and writing to socket until stdin ends
    bytes_read = read(0, buffer_stdin, sizeof(buffer_stdin));
    write(sock, buffer_stdin, bytes_read);*/

  while ((bytes_read = read(0, buffer_stdin, sizeof(buffer_stdin)-1)) > 0) {
    write(sock, buffer_stdin, bytes_read);
  }

  /*Shutting down write end of socket*/
  int r_shutdown = shutdown(sock, SHUT_WR);
  if (r_shutdown < 0) {
    printf("Shutting down write end of socket failed\n");
    exit(1);
  }

  /*Reading from socket and writing to stdout until socket ends*/
  while ((bytes_read = read(sock, buffer_stdout, sizeof(buffer_stdout)-1)) > 0) {
    write(1, buffer_stdout, bytes_read);
  }

  close(sock);
  exit(0);
}

The correct way to do it is :

struct sockaddr_in address;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if(sockfd!=-1)
  {
          perror("socket :");
          printf("sockfd = %d\n", sockfd);
  }
  else
  {
          perror("socket");
          exit(EXIT_FAILURE);
  }

  address.sin_family = AF_INET;
  address.sin_addr.s_addr = inet_addr("127.0.0.1");
  address.sin_port = htons(9734);
  len = sizeof(struct sockaddr_in);

  result = connect(sockfd, (struct sockaddr *)&address, len);

Nvm I figured it out.

Apparently I had to take into account big endian vs little endian, and so in this line:

((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htonl(servPort);

the htonl should've been htons, so:

((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htons(servPort);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM