C语言:为什么我不能将文件从服务器传输到客户端?

时间:2010-04-05 08:26:54

标签: c client-server

我想问一下,为什么我不能将文件从服务器传输到客户端?

当我开始从服务器发送文件时,客户端程序出现问题。所以,我花了一些时间来检查代码,但我仍然无法找到问题

有人可以为我指出问题吗?

PS。感谢administarator首先修复代码。

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 个答案:

答案 0 :(得分:1)

您是否尝试在客户端和服务器端的调试器下运行程序以查看它挂起的位置?我先检查是否发送了任何字节,然后从那里开始工作。

我注意到代码中存在一些可能会或可能不会触发此行为的问题:

  • 您正在使用write()向套接字发送数据。正确的套接字函数是send(),而不是write()。请记住,send()可能发送的字节数比您要求的少,因此您可能需要检查并循环以获取整个缓冲区。
  • 同样适用于客户,您希望使用recv()而不是read()
  • 如果出现任何问题,send()recv()都会返回-1。您需要处理这种情况,最好还要检查实际错误是什么。

套接字编程与使用普通文件不同,由于网络通常比普通文件系统更加不稳定,因此还存在一些陷阱。

答案 1 :(得分:1)

您还在使用close()关闭套接字,而不是在客户端关闭套接字()。