multi-threaded TCP server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <direct.h> // For _mkdir
#define SERVERPORT 9000
#define BUFSIZE 512
void err_quit(const char *msg) {
fprintf(stderr, "%s\n", msg);
exit(1);
}
void err_display(const char *msg) {
fprintf(stderr, "%s\n", msg);
}
DWORD WINAPI client_handler(LPVOID lpParam) {
SOCKET client_sock = (SOCKET)lpParam;
char client_name[50] = {0};
int retval;
// Receive client name
retval = recv(client_sock, client_name, sizeof(client_name) - 1, 0);
if (retval <= 0) {
closesocket(client_sock);
return 0;
}
client_name[retval] = '\0';
printf(">>> Client connected, Client name: %s <<<\n", client_name);
// Handle communication
char buf[BUFSIZE + 1];
while (1) {
retval = recv(client_sock, buf, BUFSIZE, 0);
if (retval <= 0) break;
buf[retval] = '\0';
printf("[%s]: %s\n", client_name, buf);
if (strncmp(buf, "sendfile", 8) == 0) {
// Receive filename
char filename[256] = {0};
int index = 0;
while (1) {
int r = recv(client_sock, &filename[index], 1, 0);
if (r <= 0 || index >= 255) break;
if (filename[index] == '\0') break;
index++;
}
// Receive file size
long filesize;
int r = recv(client_sock, (char*)&filesize, sizeof(filesize), 0);
if (r <= 0) {
printf("Error receiving file size.\n");
closesocket(client_sock);
return 0;
}
// Ensure received directory exists
_mkdir("received");
// Create path for saving
char filepath[300];
sprintf(filepath, "received/%s", filename);
printf("Receiving file: %s (%ld bytes)\n", filepath, filesize);
FILE *file = fopen(filepath, "wb");
if (!file) {
printf("Error: Cannot create file %s\n", filepath);
break;
}
long received = 0;
while (received < filesize) {
int bytes = recv(client_sock, buf, BUFSIZE, 0);
if (bytes <= 0) break;
fwrite(buf, 1, bytes, file);
received += bytes;
}
fclose(file);
printf("File received and saved to: %s\n", filepath);
} else {
send(client_sock, buf, retval, 0); // Echo message
}
}
printf("Client %s disconnected.\n", client_name);
closesocket(client_sock);
return 0;
}
int main() {
int retval;
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return 1;
SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sock == INVALID_SOCKET) err_quit("socket()");
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(SERVERPORT);
retval = bind(listen_sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
if (retval == SOCKET_ERROR) err_quit("bind()");
retval = listen(listen_sock, SOMAXCONN);
if (retval == SOCKET_ERROR) err_quit("listen()");
printf(">>> Welcome to Kompong Thom Server Boy Smos SOTHEA <3 <<<\n");
printf("--> I'm Waiting Clients to Connect me -.- <--\n");
while (1) {
struct sockaddr_in clientaddr;
int addrlen = sizeof(clientaddr);
SOCKET client_sock = accept(listen_sock, (struct sockaddr *)&clientaddr, &addrlen);
if (client_sock == INVALID_SOCKET) {
err_display("accept()");
continue;
}
CreateThread(NULL, 0, client_handler, (LPVOID)client_sock, 0, NULL);
}
closesocket(listen_sock);
WSACleanup();
return 0;
}
0 Comments