У меня есть программа на 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;
}