【问题标题】:C Language: Why I cannot transfer file from server to client?C 语言:为什么我不能将文件从服务器传输到客户端?
【发布时间】:2010-04-05 08:26:53
【问题描述】:

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

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

谁能帮我指出问题?

ps。感谢管理员先修复代码。

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;
}

【问题讨论】:

  • 请告诉我们报告了什么错误。
  • 不要尝试使用 HTML 标记格式化您的代码 - 使用文本输入区域上方的 1010 按钮。
  • 请格式化代码以提高可读性。按照尼尔建议的方式去做。

标签: c client-server


【解决方案1】:

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

我注意到代码中可能会或可能不会触发此行为的几个问题:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-12
      • 2016-12-27
      • 2010-10-17
      • 2017-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多