Язык C: Почему я не могу передать файл с сервера на клиент? - PullRequest
1 голос
/ 05 апреля 2010

Я хочу спросить, почему я не могу передать файл с сервера на клиент?

Когда я начинаю отправлять файл с сервера, у программы на стороне клиента возникает проблема. Поэтому я провожу несколько раз, чтобы проверить код, но все еще не могу найти проблему

Кто-нибудь может указать на проблему для меня?

пс. Спасибо администратору за исправление кода.

ps2. Я тоже хочу узнать в чем ошибка Когда я выполняю программу, клиентская программа «зависает», не сообщая причину.

Мне сложно отследить ошибку ...

Большое спасибо!

код клиента

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <winsock2.h>
#include <direct.h>
#define SA struct sockaddr
#define S_PORT 5678
#define MAXLEN 1000
#define true 1

void errexit(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    WSACleanup();
    exit(1);
}

int main(int argc, char *argv [])
{
    WSADATA wsadata;
    SOCKET sockfd;
    int number,message;
    char outbuff[MAXLEN],inbuff[MAXLEN];
    char PWD_buffer[_MAX_PATH];
    struct sockaddr_in servaddr;
    FILE *fp;
    int numbytes;   
    char buf[2048];

    if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0)
        errexit("WSAStartup failed\n");

    if (argc != 2)
        errexit("client IPaddress");

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET )
        errexit("socket error: error number %d\n", WSAGetLastError());

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(S_PORT);
    if ( (servaddr.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE)
        errexit("inet_addr error: error number %d\n", WSAGetLastError());
    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == SOCKET_ERROR)
        errexit("connect error: error number %d\n", WSAGetLastError());

    if ( (fp = fopen("C:\\users\\pc\\desktop\\COPY.c", "wb")) == NULL){
        perror("fopen");
        exit(1);
    }
    printf("Still NO PROBLEM!\n");

    //Receive file from server
    while(1){
        numbytes = read(sockfd, buf, sizeof(buf));
        printf("read %d bytes, ", numbytes);

        if(numbytes == 0){
            printf("\n");
            break;
        }
        numbytes = fwrite(buf, sizeof(char), numbytes, fp);
        printf("fwrite %d bytes\n", numbytes);
    }

    fclose(fp);
    close(sockfd);  
    return 0;
}

серверный код

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <winsock2.h>
#include <direct.h>
#include <io.h>
#define SA struct sockaddr
#define S_PORT 5678
#define MAXLEN 1000

void errexit(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    WSACleanup();
    exit(1);
}

int main(int argc, char *argv [])
{
    WSADATA wsadata;
    SOCKET listenfd, connfd;
    int number, message, numbytes;
    int h, i, j, alen;
    int nread;
    struct sockaddr_in servaddr, cliaddr;
    FILE *in_file, *out_file, *fp;
    char buf[4096];

    if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0)
        errexit("WSAStartup failed\n");

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == INVALID_SOCKET)
        errexit("cannot create socket: error number %d\n", WSAGetLastError());

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(S_PORT);

    if (bind(listenfd, (SA *) &servaddr, sizeof(servaddr)) == SOCKET_ERROR)
        errexit("can't bind to port %d: error number %d\n", S_PORT, WSAGetLastError());

    if (listen(listenfd, 5) == SOCKET_ERROR)
        errexit("can't listen on port %d: error number %d\n", S_PORT, WSAGetLastError());


    alen = sizeof(SA);
    connfd = accept(listenfd, (SA *) &cliaddr, &alen);

    if (connfd == INVALID_SOCKET)
        errexit("accept failed: error number %d\n", WSAGetLastError());

    printf("accept one client from %s!\n", inet_ntoa(cliaddr.sin_addr));

    fp = fopen ("client.c", "rb"); // open file stored in server

    if (fp == NULL) {
        printf("\nfile NOT exist");
    }

    //Sending file
    while(!feof(fp)){
        numbytes = fread(buf, sizeof(char), sizeof(buf), fp);
        printf("fread %d bytes, ", numbytes);
        numbytes = write(connfd, buf, numbytes);
        printf("Sending %d bytes\n",numbytes);
    }

    fclose (fp);    
    closesocket(listenfd);
    closesocket(connfd);
    return 0;
}

Ответы [ 2 ]

1 голос
/ 05 апреля 2010

Вы также закрываете сокет, используя close (), а не closesocket () в клиенте.

1 голос
/ 05 апреля 2010

Вы пытались запустить программу под отладчиком на стороне клиента и сервера, чтобы увидеть, где она зависает? Сначала я проверил бы, отправлены ли какие-либо байты, а затем работал бы.

Я заметил несколько проблем с кодом, которые могут вызывать или не вызывать такое поведение:

  • Вы используете write() для отправки данных по сокету. Правильная функция сокета будет send(), а не write(). Имейте в виду, что send() может отправлять меньше байтов, чем вы просили, поэтому вам, возможно, придется проверять и зацикливаться, чтобы получить весь отправленный буфер.
  • То же самое касается клиента, вы хотите использовать recv(), а не read().
  • И send(), и recv() возвращают -1, если возникла какая-либо проблема. Вам необходимо разобраться с этим условием и, желательно, также проверить, какая была фактическая ошибка.

Программирование в сокете отличается от использования простых файлов, и есть еще несколько ловушек из-за того, что сеть обычно немного более ненадежна, чем ваша средняя файловая система.

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