2014-09-12 77 views
1

当我到终端上键入:connect()函数时间太长

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

终端只是坐在那里像它等待输入,或者它停留在一个无限循环。正在发生的事情是,我认为这种连接时间太长。

/*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"); 

这里,1个打印出,但连接之后的1.5不打印出来,终端只是坐在。

这个问题在之前没有发生过,我曾经立即拿回页面的源代码。但是现在这个问题正在发生。

它开始发生我输入到终端后:netstat -an -A inet | grep :2525

所以这可能有作用。

这里是整个代码:

#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); 
} 
+0

的netstat不会有效果。它显示统计信息,不会改变事物。 – sbhatla 2014-09-12 20:00:23

+0

我没有看到代码有什么问题,你可以发布整个事情吗? – mickael9 2014-09-12 20:11:48

+0

很难说出为什么系统调用阻塞这么久。你有没有像在wireshark或TCPdump那样监视你PC的流量?如果在调用系统调用时发送实际的SYN数据包,以及接收到的SYN,ACK和系统调用返回之间是否存在延迟,那将是一件好事。 addrList的一些上下文也会帮助 – midor 2014-09-12 21:01:00

回答

0

NVM我想通了。

显然,我不得不考虑大尾数VS小尾数,因此,在这一行:

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

的htonl应该已经htons,所以:

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

servPort已经提供给getaddrinfo,所以它应该已经填入地址字段。 – mickael9 2014-09-14 18:54:17

0

正确的方法来做到这一点是:

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);