Как использовать C socket API для подключения к серверу на моем собственном компьютере? - PullRequest
0 голосов
/ 15 марта 2019

У меня есть программа на C, которая отправляет имя файла на сервер. Этот сервер отправляет файл обратно в программу, которая сохраняет этот файл на диск. Я хочу проверить свою программу и попытаться передать файл.

Эта программа должна быть запущена как:

./a.out server_ip port_number filename

Комбинация ip сервера и номера порта сообщает этой программе, где искать сервер. Номер порта фиксированный и он мне известен. Тем не менее, я не знаю, как на самом деле подключиться к серверу. Что я должен ввести в качестве ip сервера? Этот сервер находится на моем компьютере, на котором я занимаюсь разработкой этой программы. Для отправки этой программы мне предоставит server_ip мой профессор, но мне нужно проверить, что мой код работает, прежде чем делать.

Вот код моей программы:

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

//#define SERVER_PORT "5432"
#define MAX_LINE 256

/*
 * Lookup a host IP address and connect to it using service. Arguments match the first two
 * arguments to getaddrinfo(3).
 *
 * Returns a connected socket descriptor or -1 on error. Caller is responsible for closing
 * the returned socket.
 */
int lookup_and_connect( const char *host, const char *service );


int main( int argc, char *argv[] ) {
    char *host;
    char buf[MAX_LINE];
    int s;
    int len;
    char* server_port;
    char* file_name;

    if(argc == 4)
    {
        host = argv[1];
        server_port = argv[2];
        file_name = argv[3];
    }
    else
    {
        fprintf(stderr, "Usage:\n %s server port_number filename\n", argv[0]);
        exit( EXIT_FAILURE );
    }


    /* Lookup IP and connect to server */
    if ( ( s = lookup_and_connect( host, server_port ) ) < 0 ) 
    {
        // Since you can't concatenate a string literal and a char*,
        // we have to create our own error string to be passed to perror()
        char* message = "Client Error: Unable to find host ";
        size_t len1 = strlen(host);
        size_t len2 = strlen(message);
        char* error_string = (char*) malloc( len1 + len2 + 1 );
        strncpy(error_string, message, len2);
        strncpy(error_string + len2, host, len1);
        error_string[len1 + len2] = '\0';
        perror(error_string);
        free(error_string);  // deallocate the memory for the string

        exit( EXIT_FAILURE );
    }

    //sends file name to server
    len = strlen(file_name) + 1;
    if(send(s, file_name, len, 0 ) == -1)
    {
        perror("Client Error: send");
        close(s);
        exit( EXIT_FAILURE );
    }

    //get response from server
    FILE *file = NULL; 
    int num_recv;
    char *err_str  = "<error>";
    char *good_str = "<goodf>";
    const int header_len = 7;
    while (1) 
    {
        num_recv = recv(s, buf, MAX_LINE-1,0);
        if(num_recv == -1)
        {
            perror("Client Error: recv");
            close(s);
            if (file != NULL) {
                fclose(file);
            }
            exit( EXIT_FAILURE );
        }
        else if(num_recv== 0)
        {
            break;
        }
        else
        {
            /* This will only be true the first time. */
            if (file == NULL) // creates file and write once if good
            {
                if (strncmp(err_str, buf, header_len) == 0) // check error
                {
                    fprintf(stderr, "Server Error: file %s not found\n", file_name);
                    close(s);
                    exit( EXIT_FAILURE );
                }
                else if (strncmp(good_str, buf, header_len) == 0) // check good file
                {
                    file = fopen(file_name, "wb");
                    if (file == NULL)
                    {
                        perror("Client Error: fopen");
                        close(s);
                        exit( EXIT_FAILURE );
                    }
                    fwrite(buf, sizeof(char), num_recv, file);
                }
                else  // Server sent something else.
                {
                    fprintf(stderr, "Server Error: sent garbage data\n");
                    close(s);
                    exit( EXIT_FAILURE );

                }
            }
            else // writes to file
            {
                fwrite(buf, sizeof(char), num_recv, file);
            }
        }

    }

    // tries to close the file
    if (fclose(file) == EOF) {
        perror("Client Error: fclose");
    }

    close( s );

    return 0;
}

int lookup_and_connect( const char *host, const char *service ) {
    struct addrinfo hints;
    struct addrinfo *rp, *result;
    int s;

    /* Translate host name into peer's IP address */
    memset( &hints, 0, sizeof( hints ) );
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0;
    hints.ai_protocol = 0;

    if ( ( s = getaddrinfo( host, service, &hints, &result ) ) != 0 ) {
        fprintf( stderr, "Client Error: stream-talk-client: getaddrinfo: %s\n", gai_strerror( s ) );
        return -1;
    }

    /* Iterate through the address list and try to connect */
    for ( rp = result; rp != NULL; rp = rp->ai_next ) {
        if ( ( s = socket( rp->ai_family, rp->ai_socktype, rp->ai_protocol ) ) == -1 ) {
            continue;
        }

        if ( connect( s, rp->ai_addr, rp->ai_addrlen ) != -1 ) {
            break;
        }

        close( s );
    }
    if ( rp == NULL ) {
        perror( "Client Error: stream-talk-client: connect" );
        return -1;
    }
    freeaddrinfo( result );

    return s;
}

1 Ответ

0 голосов
/ 15 марта 2019

Вы можете использовать имя сервера «localhost» (которое всегда разрешается в вашей системе) или IPv4-адрес «127.0.0.1».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...