Initial basic messaging server.
This commit is contained in:
commit
efd17b030e
4 changed files with 216 additions and 0 deletions
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
.cache
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
cmake_install.cmake
|
||||
compile_commands.json
|
||||
.dir-locals.el
|
||||
Makefile
|
||||
Urchin-*
|
||||
28
CMakeLists.txt
Normal file
28
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
project(Urchin
|
||||
VERSION 0
|
||||
DESCRIPTION "Simple Mud Experiment in C"
|
||||
HOMEPAGE_URL "https://git.warwick-new.co.uk/"
|
||||
LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 90)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CMAKE_C_CLANG_TIDY)
|
||||
|
||||
# Compile Server
|
||||
file(GLOB_RECURSE SERVER_SOURCE_FILES
|
||||
${CMAKE_SOURCE_DIR}/src/server/*.c)
|
||||
|
||||
file(GLOB_RECURSE SERVER_HEADER_FILES
|
||||
${CMAKE_SOURCE_DIR}/src/server/*.h)
|
||||
|
||||
add_executable(${PROJECT_NAME}-server ${SERVER_HEADER_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
# Compile Client
|
||||
file(GLOB_RECURSE CLIENT_SOURCE_FILES
|
||||
${CMAKE_SOURCE_DIR}/src/client/*.c)
|
||||
|
||||
file(GLOB_RECURSE CLIENT_HEADER_FILES
|
||||
${CMAKE_SOURCE_DIR}/src/client/*.h)
|
||||
|
||||
add_executable(${PROJECT_NAME}-client ${CLIENT_HEADER_FILES} ${CLIENT_SOURCE_FILES})
|
||||
79
src/client/main.c
Normal file
79
src/client/main.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// Sorry in advance for all the comments. This project is also a way for me to
|
||||
// learn C.
|
||||
|
||||
#include <netdb.h> // Contains host structure
|
||||
#include <netinet/in.h> //sockaddr_in
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // Keeping for conversion functions
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/socket.h> // sockaddr
|
||||
#include <sys/types.h>
|
||||
|
||||
void error_crash(const char *msg) {
|
||||
fprintf(stderr, "error crash: %s\n", msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void error_warn(const char *msg) { fprintf(stderr, "warning: %s\n", msg); }
|
||||
|
||||
// TODO: Save the logs somewhere
|
||||
void error_log(const char *msg) { fprintf(stderr, "log: %s\n", msg); }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Set up containers for file descriptor id's
|
||||
int sockfd, portno, errflag;
|
||||
struct sockaddr_in serv_addr;
|
||||
bzero((char *)&serv_addr, sizeof(serv_addr));
|
||||
struct hostent *server;
|
||||
char msgbuffer[255];
|
||||
|
||||
if (argc < 2) {
|
||||
error_crash("Not enough server info has been provided");
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
portno = atoi(argv[2]);
|
||||
} else {
|
||||
portno = 3940;
|
||||
}
|
||||
|
||||
// Create socket
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
error_crash("Can't open socket.");
|
||||
|
||||
server = gethostbyname(argv[1]);
|
||||
if (server == NULL)
|
||||
error_crash("No such host exists :(");
|
||||
|
||||
serv_addr.sin_family = AF_INET;
|
||||
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,
|
||||
server->h_length);
|
||||
serv_addr.sin_port = htons(portno);
|
||||
errflag = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||
if (errflag < 0)
|
||||
error_crash("Failed to connect to host");
|
||||
|
||||
while (1) {
|
||||
bzero(msgbuffer, sizeof msgbuffer);
|
||||
fgets(msgbuffer, sizeof msgbuffer, stdin);
|
||||
errflag = write(sockfd, msgbuffer, strlen(msgbuffer));
|
||||
if (errflag < 0)
|
||||
error_crash("Failed to write message");
|
||||
|
||||
bzero(msgbuffer, sizeof msgbuffer);
|
||||
errflag = read(sockfd, msgbuffer, sizeof msgbuffer);
|
||||
if (errflag < 0)
|
||||
error_crash("Failed to read message");
|
||||
|
||||
printf("Server: %s", msgbuffer);
|
||||
|
||||
int cmp = strncmp("Bye", msgbuffer, 3);
|
||||
if (cmp == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
101
src/server/main.c
Normal file
101
src/server/main.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// Sorry in advance for all the comments. This project is also a way for me to
|
||||
// learn C.
|
||||
|
||||
#include <netinet/in.h> //sockaddr_in
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // Keeping for conversion functions
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/socket.h> // sockaddr
|
||||
#include <sys/types.h>
|
||||
|
||||
void error_crash(const char *msg) {
|
||||
fprintf(stderr, "error crash: %s\n", msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void error_warn(const char *msg) { fprintf(stderr, "warning: %s\n", msg); }
|
||||
|
||||
// TODO: Save the logs somewhere
|
||||
void error_log(const char *msg) { fprintf(stderr, "log: %s\n", msg); }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Set up containers for file descriptor id's
|
||||
int sockfd, clientsockfd, portno, errflag;
|
||||
char msgbuffer[255];
|
||||
|
||||
// Set port number.
|
||||
if (argc > 1) {
|
||||
portno = atoi(argv[1]);
|
||||
} else {
|
||||
portno = 3940;
|
||||
}
|
||||
|
||||
// Socket address info
|
||||
struct sockaddr_in serv_addr, cli_addr;
|
||||
socklen_t clilen = sizeof cli_addr; // We can do this here as cli_addr isn't
|
||||
// touched until it's used
|
||||
|
||||
// Create socket
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
error_crash("Can't open socket.");
|
||||
}
|
||||
|
||||
// Make sure there is no junk data in serve_addr
|
||||
bzero((char *)&serv_addr, sizeof serv_addr);
|
||||
|
||||
// Tell the connection to use ipv4 and port number
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
|
||||
// Bind Socket
|
||||
errflag = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
||||
if (errflag < 0) {
|
||||
error_crash("Can't bind socket");
|
||||
}
|
||||
|
||||
errflag = listen(sockfd, 5);
|
||||
if (errflag < 0) {
|
||||
error_crash("Can't listen for connections");
|
||||
}
|
||||
|
||||
char portstr[5]; // Buffer to store string version of port
|
||||
snprintf(portstr, sizeof portstr, "%d", portno);
|
||||
printf("Server Listening on port: %s\n", portstr);
|
||||
|
||||
clientsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
|
||||
if (clientsockfd < 0) {
|
||||
error_crash("Can't accept connection");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
// Empty message buffer
|
||||
bzero(msgbuffer, sizeof msgbuffer);
|
||||
|
||||
errflag = read(clientsockfd, msgbuffer, sizeof msgbuffer);
|
||||
if (errflag < 0) {
|
||||
error_crash("Didn't recieve message from connection");
|
||||
}
|
||||
printf("Client: %s\n", msgbuffer);
|
||||
|
||||
// clear buffer for writing
|
||||
bzero(msgbuffer, sizeof msgbuffer);
|
||||
fgets(msgbuffer, sizeof msgbuffer, stdin);
|
||||
|
||||
errflag = write(clientsockfd, msgbuffer, strlen(msgbuffer));
|
||||
if (errflag < 0) {
|
||||
error_crash("Couldn't write response message");
|
||||
}
|
||||
|
||||
int cmp = strncmp("Bye", msgbuffer, 3);
|
||||
if (cmp == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
close(clientsockfd);
|
||||
close(sockfd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
Reference in a new issue