Working Server and Client

This commit is contained in:
2026-04-26 12:14:31 -04:00
parent 4cdda5c53a
commit 81488417d9
6 changed files with 248 additions and 25 deletions

3
.gitignore vendored
View File

@@ -1,3 +1,4 @@
*.o
netpong
netpong.dSYM/
netpong.dSYM/
netpong.c

View File

@@ -6,7 +6,7 @@
#include <stdlib.h>
#include <unistd.h>
void DrawWalls(struct GameData data)
void DrawWalls(GameData data)
{
for (int i = LEFT_COL; i <= RIGHT_COL; i++) {
move(TOP_ROW, i);
@@ -25,7 +25,7 @@ void DrawWalls(struct GameData data)
refresh();
}
void DrawHeader(struct GameData data)
void DrawHeader(GameData data)
{
move(TOP_ROW - 2, LEFT_COL);
addch('P');

9
game.h
View File

@@ -7,16 +7,17 @@
#define LEFT_COL 9
#define RIGHT_COL 70
struct GameData
typedef struct
{
int host;
int playerNumber;
char* domain;
int port;
};
} GameData;
void DrawWalls(struct GameData);
void DrawHeader(struct GameData);
void DrawWalls(GameData);
void DrawHeader(GameData);
#endif

143
main.c
View File

@@ -3,20 +3,24 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "network/networking.h"
/**
* Main Fucntion
*/
int main(int argc, char* argv[])
{
// Create GameData Object
struct GameData data;
GameData data = { false, 0, NULL, 0 };
// Detect Server or Client
switch (argc) {
case 2:
// Start Server
data.host = true;
data.playerNumber = 0;
data.port = atoi(argv[1]);
break;
@@ -34,27 +38,130 @@ int main(int argc, char* argv[])
return 1;
}
srand(getpid());
// srand(getpid());
// Setup Terminal
if (initscr() == NULL) {
perror("initscr failed");
exit(1);
}
noecho();
cbreak();
nodelay(stdscr, TRUE);
// // Setup Terminal
// if (initscr() == NULL) {
// perror("initscr failed");
// exit(1);
// }
// noecho();
// cbreak();
// nodelay(stdscr, TRUE);
DrawWalls(data);
DrawHeader(data);
int game_running = true;
int socket_fd = 0;
if (data.host) {
// Create Server
Server s = StartServer(data.port);
while (1) {
int ch = getch();
if (ch == 'q')
break;
printf("Server Started\n");
fd_set fds;
FD_ZERO(&fds);
FD_SET(s.server_fd, &fds);
struct timeval tv = { 0, 0 }; // non-blocking check
int updateChar = 0;
while (game_running) {
fd_set read_fds;
FD_ZERO(&read_fds);
// Add server socket
FD_SET(s.server_fd, &read_fds);
int max_fd = s.server_fd;
// Add client sockets
for (int i = 0; i < s.client_count; i++) {
int fd = s.clients[i];
FD_SET(fd, &read_fds);
if (fd > max_fd)
max_fd = fd;
}
// Small timeout (prevents 100% CPU usage)
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000; // 1ms
int ret = select(max_fd + 1, &read_fds, NULL, NULL, &tv);
if (ret < 0) {
perror("select");
break;
}
// New connection
if (FD_ISSET(s.server_fd, &read_fds)) {
int client_fd = accept(s.server_fd, NULL, NULL);
if (client_fd >= 0 && s.client_count < s.max_clients) {
s.clients[s.client_count++] = client_fd;
printf("New client connected: %d\n", client_fd);
}
}
// Handle client data
for (int i = 0; i < s.client_count; i++) {
int fd = s.clients[i];
if (FD_ISSET(fd, &read_fds)) {
char buffer[1024];
int bytes = recv(fd, buffer, sizeof(buffer) - 1, 0);
if (bytes > 0) {
buffer[bytes] = '\0';
printf("Client %d says: %s\n", fd, buffer);
// Example: echo back
send(fd, buffer, bytes, 0);
} else if (bytes == 0) {
printf("Client %d disconnected\n", fd);
RemoveClient(&s, i);
i--; // re-check swapped client
} else {
perror("recv");
RemoveClient(&s, i);
i--;
}
}
}
}
close(s.server_fd);
} else {
printf("Connecting to %s:%i\n", data.domain, data.port);
// Create Client
Client c = StartClient(data.domain, data.port);
char* msg = "Hello from client";
send(c.client_fd, msg, strlen(msg), 0);
{
char buffer[1024] = { 0 };
read(c.client_fd, buffer, sizeof(buffer));
printf("Server: %s\n", buffer);
}
sleep(10);
char* msg2 = "Ok I am leaving now";
send(c.client_fd, msg2, strlen(msg2), 0);
{
char buffer[1024] = { 0 };
read(c.client_fd, buffer, sizeof(buffer));
printf("Server: %s\n", buffer);
}
close(c.client_fd);
return 0;
}
endwin();
// endwin();
}

88
network/networking.c Normal file
View File

@@ -0,0 +1,88 @@
#include "networking.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
Server StartServer(int port) {
Server s = {2};
s.clientID = 0;
// Create Socket
if ((s.server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Set Address
s.address.sin_family = AF_INET;
s.address.sin_addr.s_addr = INADDR_ANY; // listen on all interfaces
s.address.sin_port = htons(port);
// Bind Port
if (bind(s.server_fd, (struct sockaddr *)&s.address, sizeof(s.address)) < 0) {
perror("bind failed");
close(s.server_fd);
exit(EXIT_FAILURE);
}
// Listen for incoming connections
if (listen(s.server_fd, 3) < 0) {
perror("listen");
close(s.server_fd);
exit(EXIT_FAILURE);
}
printf("Server listening on port %d...\n", port);
return s;
}
void RemoveClient(Server* s, int index) {
close(s->clients[index]);
s->clients[index] = s->clients[s->client_count - 1];
s->client_count--;
}
Client StartClient(char* host, int port) {
Client c;
// Create socket
if ((c.client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Set address info
c.address.sin_family = AF_INET;
c.address.sin_port = htons(port);
// Convert hostname/IP to binary form
if (inet_pton(AF_INET, host, &c.address.sin_addr) <= 0) {
// If not a direct IP, try resolving hostname
struct hostent* he = gethostbyname(host);
if (he == NULL) {
perror("gethostbyname failed");
close(c.client_fd);
exit(EXIT_FAILURE);
}
memcpy(&c.address.sin_addr, he->h_addr_list[0], he->h_length);
}
// Connect to server
if (connect(c.client_fd, (struct sockaddr*)&c.address, sizeof(c.address)) < 0) {
perror("connect failed");
close(c.client_fd);
exit(EXIT_FAILURE);
}
printf("Connected to %s:%d\n", host, port);
return c;
}

26
network/networking.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef GAME_NETWORKING_H
#define GAME_NETWORKING_H 1
#include <netinet/in.h>
typedef struct {
const int max_clients;
int server_fd;
struct sockaddr_in address;
int clients[2];
int clientID;
int client_count;
} Server;
Server StartServer(int port);
void RemoveClient(Server* s, int index);
typedef struct {
int client_fd;
struct sockaddr_in address;
} Client;
Client StartClient(char* host, int port);
#endif