1

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.

2
  • What is the output of both programs? How do "when I open the server.exe file, It open and suddenly close automatically" and "when I click on the server.exe, it doese not open." go together? Commented Dec 13, 2023 at 11:05
  • 1
    This is what a DEBUGGER is meant for! Get yourself a debugger and actually step through the code while it is running so you can see exactly what it is doing and where it is not doing what you expect. Commented Dec 14, 2023 at 0:56

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

2 Comments

"Before the return 0; line, add this line" - and also before each of the exit() lines, too.
Good catch, @RemyLebeau, I'm gonna edit it
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.