Question

I am doing a tcp server,client file transfer program. The client will request a filename from server. The server will return the contents of the file. But when I give a filename that is not existing it is supposed to give an error that file doesnot exists. But the server simply hangs. It doesnot print anything. I tried the same program without using fork() system call and it worked. Please help me solve this.

Client program:

#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>

/* Server */
int main()
{
// Create the structure
struct sockaddr_in server;

// Create a socket
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// Initialize the structure
bzero(&server, sizeof(server));

server.sin_port = htons(7008);
server.sin_family = AF_INET;
inet_aton("127.0.0.1", &server.sin_addr);

// Connect to server
connect(sockfd, (struct sockaddr*)&server, sizeof(server));

char msg[256];      // 256 bytes of data

strcpy(msg, "myfile"); // Here if myfile is a file
                       // that doesnot exist 
                       // Server is supposed to return an error

// Send file name to file
send(sockfd, msg, strlen(msg) + 1, 0);
// Receive data
printf("Waiting for data: \n");
recv(sockfd, msg, 256, 0);
printf("%s", msg);
close(sockfd);
} 

Server Program:

#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>

/* Server */
int main()
{
    // Create the structure
    struct sockaddr_in server, client;

    // Create a socket
    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    // Initialize the structure
    bzero(&server, sizeof(server));

    server.sin_port = htons(7008);
    server.sin_family = AF_INET;
    inet_aton("127.0.0.1", &server.sin_addr);

    // Bind socket to port
    bind(sockfd, (struct sockaddr*)&server, sizeof(server));

    // Listen for connection
    listen(sockfd, 5);

    while(1)
    {
        int client_length = sizeof(client);
        int nsockfd = accept(sockfd, (struct sockaddr*)&client, &client_length);

        char msg[256];      // 256 bytes of data
        int len;

        // Create a child process
        if(fork() == 0)
        {

            len = recv(nsockfd, msg, 256, 0);
            printf("Received %s\n", msg);
            char filename[40];

            // Generate the filename
            strcpy(filename,"./files/");
            strcat(filename,msg);
            printf("File to open %s", filename);

            // File pointer
            FILE *fp;

                // Server should return "File not found"
                    // But it simply hangs there
                    // It doesnt show any response
            if(!(fp = fopen(filename, "r")))
            {
                printf("Error opening file");
                strcpy(msg, "File not found");
                send(sockfd, msg, strlen(msg) + 1, 0);
                strcpy(msg, "CLOSED");
                send(sockfd, msg, strlen(msg) + 1, 0);
            }
            else
            {
                // Read from the file
                fgets(msg, 256, fp);

                printf("%s", msg);
                send(nsockfd, msg, strlen(msg) + 1, 0);
                strcpy(msg, "CLOSED");
                send(nsockfd, msg, strlen(msg) + 1, 0);
                fclose(fp);
            }
            // Receive data
            close(nsockfd);
            break;

        }
    }
}
Was it helpful?

Solution

You're attempting to send to sockfd, which is the file descriptor for the bound (listening) socket. You should instead be sending to nsockfd, which is the file descriptor for the accepted (communicating) socket:

if(!(fp = fopen(filename, "r")))
{
    printf("Error opening file");
    strcpy(msg, "File not found");

/*  send(sockfd, msg, strlen(msg) + 1, 0);
         ^^^^^^--- wrong file descriptor
    strcpy(msg, "CLOSED");
    send(sockfd, msg, strlen(msg) + 1, 0);
         ^^^^^^--- wrong file descriptor    */

    // should instead be:
    send(nsockfd, msg, strlen(msg) + 1, 0);
    strcpy(msg, "CLOSED");
    send(nsockfd, msg, strlen(msg) + 1, 0);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top