C Language: Why I cannot transfer file from server to client?

I want to ask, why I cannot transfer file from server to client?

When I start to send the file from server, the client side program has a problem. So, I spend some times to check the code, but I still cannot find out the problem

Can anyone point out the problem for me?

ps. Thanks for the administarator fix the code first.

ps2. I also want to know what is the error When I execute the program, the client side program will "hang" without telling the reason.

It is difficult for me to trace the error...

thanks a lot!

client side code

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

server side code

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

Answers


Have you tried running the program under the debugger both on the client and server side to see where it hangs? I would check first if any bytes are sent and then work from there.

There are a couple of problems I noticed with the code that might or might not trigger this behaviour:

  • You're using write() to send data down a socket. The correct socket function would be send(), not write(). Keep in mind that send() might send fewer bytes than you asked it to so you might have to check and loop to get the whole buffer sent.
  • Same goes for the client, you want to use recv() and not read().
  • Both send() and recv() return -1 if there was any sort of problem. You need to handle this condition and preferably also check what the actual error was.

Socket programming is different from using plain files and there are a few more pitfalls due to the network generally being a little more flaky than your average file system.


You're also closing a socket using close(), not closesocket() in client.


Need Your Help

Cannot create working OpenGL 3.3 context with SDL2 on OSX 10.11 (MBP, GeForce 750M)

c++ macos opengl sdl-2

I have the following (working) setup code for OpenGL using SDL2:

Passing the url in a link not working

php

I'm trying to pass the id of a blogpost in an url. It works in the adminpanel (read blogpost) now I want to do the same on my frontpage, so that it says read more under every blogpost, but when I u...