Reputation: 13
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:
This is the Terminal:
I try this code on a Windows machine.
Please help me to fix this problem.
Upvotes: 1
Views: 100
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:
WSAStartup()
, obviously.int
instead of SOCKET
for socket descriptors.SOCKET_ERROR
or INVALID_SOCKET
, etc.<unistd.h>
header.These practices are common on other platforms, such as 'Nix systems for instance. But not on Windows.
Upvotes: 0
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:
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
stdin
read in the end of the main()
functionBefore 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