错误:尝试接受来自客户端的连接时参数无效

时间:2014-07-01 16:49:14

标签: c tcp

我正在尝试使用TCP将客户端连接到服务器。我想我的客户端正确地完成了他的工作,但服务器无法接受连接。 这是我的代码:

SERVER:

int main(int argc, char *argv[])
{
    int port, sock, newsock, thread_pool_size, queue_size;
    struct sockaddr_in server, client;
    struct sockaddr *serverptr = ( struct sockaddr * )&server;
    struct sockaddr *clientptr = ( struct sockaddr * )&client;
    struct hostent *rem;
    socklen_t clientlen;
    pthread_t thr;
    int i, err, status;

    if(argc != 7)
    {
        printf("Usage: ./dataServer -p <port> -s <thread_pool_size> -q <queue_size>\n");
        exit(1);
    }

    for(i=1; i<argc; i++)
    {
        if(strcmp(argv[i], "-p") == 0)
        {
            port = atoi(argv[++i]);
        }

        else if(strcmp(argv[i], "-s") == 0)
        {
            thread_pool_size = atoi(argv[++i]);
        }

        else if(strcmp(argv[i], "-q") == 0)
        {
            queue_size = atoi(argv[++i]);
        }

        else
        {
            printf("Wrong Input < %s >\n", argv[i]);
            exit(1);
        }
    }

    printf("%d %d %d\n", port, thread_pool_size, queue_size);

    /* Create socket */
    if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror_exit("socket");
    }

    server.sin_family = AF_INET;       /* Internet domain */
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);      /* The given port */

    /* Bind socket to address */
    if(bind(sock, serverptr, sizeof(server)) < 0)
    {
        perror_exit("bind");
    }

    /* Listen for connections */
    if(listen(sock, 5) < 0)
    {
        perror_exit("listen");
    }

    printf("Listening for connections to port %d\n", port);

    while(1)
    {
        /* accept connection */
        if((newsock = accept(sock, clientptr, &clientlen)) < 0)
        {
            //HERE IS THE PROBLEM
            perror_exit("accept");
        }

        if((rem = gethostbyaddr((char *) &client.sin_addr.s_addr, sizeof(client.sin_addr.s_addr), client.sin_family)) == NULL)
        {
            herror("gethostbyaddr");
            exit(1);
        }

        printf("Accepted connection from %s\n", rem->h_name);

        close(sock);

        if((err = pthread_create(&thr, NULL, (void*)thread_f, (int *)newsock)))
        {
            perror_exit("pthread_create");
            exit(1); 
        }

        if((err = pthread_join(thr, (void **) &status)))
        {
            perror_exit("pthread_join");
            exit(1); 
        }

        close(newsock);
    }

    return 0;
}

客户端:

int main(int argc, char *argv[])
{
    int port, sock, i;
    char buf[30];
    struct sockaddr_in server;
    struct sockaddr *serverptr = (struct sockaddr*)&server;
    struct hostent *rem;
    char server_ip[15];

    if(argc != 7)
    {
        printf("Usage: ./remoteClient -i <server_ip> -p <server_port> -d <directory>\n");
        exit(1);
    }

    for(i=1; i<argc; i++)
    {
        if(strcmp(argv[i], "-i") == 0)
        {
            strcpy(server_ip, argv[++i]);
        }

        else if(strcmp(argv[i], "-p") == 0)
        {
            port = atoi(argv[++i]);
        }

        else if(strcmp(argv[i], "-d") == 0)
        {
            strcpy(buf, argv[++i]);
        }

        else
        {
            printf("Wrong Input < %s >\n", argv[i]);
            exit(1);
        }
    }

    printf("%s %d %s\n", server_ip, port, buf);

    /* Create socket */
    if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror_exit("socket");
    }

    /* Find server address */
    if((rem = gethostbyname(server_ip)) == NULL)
    {   
        herror("gethostbyname"); exit(1);
    }

    server.sin_family = AF_INET;
    memcpy(&server.sin_addr, rem->h_addr, rem->h_length);
    server.sin_port = htons(port);

    /* Initiate connection */
    if(connect(sock, serverptr, sizeof(server)) < 0)
    {
        perror_exit("connect");
    }

    if (write(sock, buf, sizeof(buf)) < 0)
    {
        perror_exit("write");
    }

    close(sock);

    printf("ok\n");

    return 0;
}

如果你想运行它们:

./ dataServer -p 12500 -s 2 -q 2

./ remoteClient -i localhost -p 12500 -d ./dir/file_1

不介意我的其余代码。 你能帮我吗?提前谢谢!

1 个答案:

答案 0 :(得分:3)

来自accept man page(我的重点)

  

addrlen参数是一个value-result参数:调用者必须   初始化它以包含指向的结构的大小(以字节为单位)   通过addr ;返回时它将包含对等体的实际大小   地址。

你传入一个未初始化的变量。您需要对此进行初始化,以使缓冲区clientptr的大小指向

socklen_t clientlen = sizeof(client);

在此之后,你应该移动

close(sock);

超过while循环结束。您的下一个错误是由在已关闭的句柄上运行的循环的第二次迭代引起的。