Chandima Maduwantha
Chandima Maduwantha

Reputation: 13

Unable to run client/server socket programs on Windows, programs exit immediately

I compiled both client and server code using the following commands:

server : gcc server.c -o server.exe -lws2_32
client : gcc client.c -o client.exe -lws2_32

Both codes are successfully complied and generate the .exe files w.r.t the server.c and client.c files.

My problem is, when I run the server.exe file, it opens and suddenly closes automatically.

This is happening also with the client.exe.

Why is that?

server.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#define SIZE 1024
void write_file(int sockfd){
    int n;
    FILE *fp;
    char *filename = "file2.txt";
    char buffer[SIZE];
    fp = fopen(filename, "w");
    if(fp==NULL){
        perror("[-]Error in creating file.");
        exit(1);
    }while(1){
        n = recv(sockfd, buffer, SIZE, 0);
        if(n<=0){
            break;
            return;
        }
        fprintf(fp, "%s", buffer);
        memset(buffer, 0, SIZE);
    }
    return;
}

int main (){
    char *ip = "127.0.0.1";
    int port = 8080;
    int e;
    int sockfd, new_sock;
    struct sockaddr_in server_addr, new_addr;
    int addr_size;
    char buffer[SIZE];
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd<0){
        perror("[-]Error in socket");
        exit(1);
    }
     printf("[+]Server socket created. \n");
     server_addr.sin_family = AF_INET;
     server_addr.sin_port = port;
     server_addr.sin_addr.s_addr = inet_addr(ip);
     e = bind(sockfd,(struct sockaddr*)&server_addr, sizeof(server_addr));
     if(e<0){
         perror("[-]Error in Binding");
         exit(1);
     }
     printf("[+]Binding Successful.\n");
     e = listen(sockfd, 10);
     if(e==0){
         printf("[+]Listening...\n");
     }
     else{
         perror("[-]Error in Binding");
         exit(1);
     }
     addr_size = sizeof(new_addr);
     new_sock = accept(sockfd,(struct sockaddr*)&new_addr, &addr_size);
     write_file(new_sock);
     printf("[+]Data written in the text file ");
     return 0;
}

client.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <winsock2.h>
#define SIZE 1024
void send_file(FILE *fp, int sockfd){
    char data[SIZE] = {0};
    while(fgets(data, SIZE, fp)!=NULL){
        if(send(sockfd, data, sizeof(data), 0)== -1){
            perror("[-] Error in sending data");
            exit(1);
        }
        memset(data, 0, SIZE);
    }
}
int main(){
    char *ip = "127.0.0.1";
    int port = 8080;
    int e;
    int sockfd;
    struct sockaddr_in server_addr;
    FILE *fp;
    char *filename = "file.txt";
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd<0){
        perror("[-]Error in socket");
        exit(1);
    }
     printf("[+]Server socket created. \n");
     server_addr.sin_family = AF_INET;
     server_addr.sin_port = port;
     server_addr.sin_addr.s_addr = inet_addr(ip);
     e = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
     if(e == -1){
         perror("[-]Error in Connecting");
         exit(1);
     }
     printf("[+]Connected to server.\n");
     fp = fopen(filename, "r");
     if(fp == NULL){
         perror("[-]Error in reading file.");
         exit(1);
     }
     send_file(fp,sockfd);
     printf("[+] File data send successfully. \n");
     close(sockfd);
     printf("[+]Disconnected from the server. \n");
     return 0;
}

Output files:

image

This is the Terminal:

image

I try this code on a Windows machine.

Please help me to fix this problem.

Upvotes: 1

Views: 100

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 597906

Both client and server are failing immediately because you are not initializing the Winsock library before you call socket(). On Windows, you must call WSAStartup() first! Without that, socket() will fail with a WSANOTINITIALISED (10093) error code:

Return value

If no error occurs, socket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error code Meaning
WSANOTINITIALISED A successful WSAStartup call must occur before using this function.

This requirement only exists on Windows, other platforms do not have an initialization function for their socket libraries. And this code is definitely not written with Windows in mind - as evident by a number of factors in the code:

  • the lack of WSAStartup(), obviously.
  • using int instead of SOCKET for socket descriptors.
  • checking Winsock library return values for less-than 0 rather than equal-to SOCKET_ERROR or INVALID_SOCKET, etc.
  • using the <unistd.h> header.
  • etc...

These practices are common on other platforms, such as 'Nix systems for instance. But not on Windows.

Upvotes: 0

&#193;gatha
&#193;gatha

Reputation: 127

From what I can see in your question, you stated that you're opening it by clicking on the .exe file, right?

The problem here seems like you would not be able to see if any of the steps in the way fail, because when you click a non-GUI program in Windows it opens on a temporary terminal, and it gets closed when the program ends. So if the program encounter any error on the way and the socket fails to listen, the program won't block and it'll end without leaving you any trace at all.

To overcome this, you can try two alternative approaches:

Run it from the command-line

I am no Windows expert and don't have a Windows machine to test this alternative, but you should be able to just type something like:

PS C:\Users\ASUS\Desktop\Socket Program> server.exe

Add a stdin read in the end of the main() function

Before the return 0; line and each exit() line, add this line:

scanf("%d\n", &port);

The port variable was chosen to ease the editing, it seems ugly, but it's practical.

Upvotes: 0

Related Questions