如何在自己的电脑上使用C socket API连接服务器?

How to use C socket API to connect to server on my own computer?

我有一个 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] = '[=12=]';
        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;
}

您可以使用服务器名称 "localhost"(始终解析为您的系统)或 IPv4 地址“127.0.0.1”。