Implemented unux sockets.

This commit is contained in:
Max 2022-12-05 20:45:26 +01:00
parent 47bff933b7
commit b020bcaa4e
10 changed files with 314 additions and 0 deletions

23
CMakeLists.txt Normal file
View File

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.15)
project(ctest LANGUAGES C)
add_compile_options(-pthread)
set(PROJ_BUILD_DIR ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJ_BUILD_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJ_BUILD_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJ_BUILD_DIR}/bin)
set(PROJ_REL_BUILD_DIR ${CMAKE_BINARY_DIR}/release)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJ_REL_BUILD_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJ_REL_BUILD_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJ_REL_BUILD_DIR}/bin)
set(PROJ_DEB_BUILD_DIR ${CMAKE_BINARY_DIR}/debug)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJ_DEB_BUILD_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJ_DEB_BUILD_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJ_DEB_BUILD_DIR}/bin)
add_subdirectory(src)

6
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
add_executable(ctest
"main.c"
"sockets.h")
add_subdirectory(sockets)

36
src/main.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include "sockets.h"
static void sig_handler();
int main(int argc, char *argv[])
{
signal(SIGINT, sig_handler);
if (argc == 2)
{
if (strcmp(argv[1], "server") == 0)
{
return start_server();
}
if (strcmp(argv[1], "client") == 0)
{
clientstart();
return 0;
}
}
printf("None or too much arguments passed!\n");
return 0;
}
// Handle the signal to exit the app!
static void sig_handler()
{
stop_server();
exit(0);
}

23
src/sockets.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef SOCKETS_H
#define SOCKETS_H
#include <stdio.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT_NUM 42069
struct net_data
{
char sName[100];
};
void clientstart();
int start_server();
int stop_server();
int writeToSock(int fd, void* data, ssize_t size);
int readFromSock(int fd, void* buff, ssize_t size);
#endif

View File

@ -0,0 +1,7 @@
target_sources(ctest PRIVATE
"client.c"
"sock_helper.c"
"server.c"
"thread_manager.c"
"thread_manager.h")

53
src/sockets/client.c Normal file
View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "../sockets.h"
void clientstart()
{
int client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in client_sockaddr;
client_sockaddr.sin_family = AF_INET;
client_sockaddr.sin_port = htons(PORT_NUM);
client_sockaddr.sin_addr.s_addr = INADDR_ANY;
int connection_status = connect(client_sockfd, (struct sockaddr*) &client_sockaddr, sizeof(client_sockaddr));
if (connection_status != 0)
{
printf("ERROR: Could not connect!\n");
return;
}
ssize_t nextRecSize = 0;
ssize_t recvRead = readFromSock(client_sockfd, &nextRecSize, sizeof(uint32_t));
if (recvRead == -1)
{
printf("ERROR: Failed to receive data!\nErrno: %i", errno);
return;
}
nextRecSize = ntohl(nextRecSize);
char serverName[64];
recvRead = readFromSock(client_sockfd, &serverName, nextRecSize);
if (recvRead == -1)
return;
if (recvRead == 0)
{
printf("No data received!\n");
}
printf("Connected with: %s\n", serverName);
for (;;)
{
char c = getchar();
if (c == 'q')
return;
}
}

108
src/sockets/server.c Normal file
View File

@ -0,0 +1,108 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "../sockets.h"
#include "thread_manager.h"
int server_sockfd;
struct sockaddr_in server_sockaddr;
bool b_listen = true;
char sName[64] = "Test server Linux\0";
struct net_data server_data;
void* thread_client_handler(void* arg);
int start_server()
{
// Set up data struct that will be send to the client.
//char sName[11] = "Server net";
//strcpy(server_data.sName, sName);
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (server_sockfd < 0)
{
printf("ERROR: Could not create server socket!\n");
return -1;
}
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT_NUM);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
int bind_result = bind(server_sockfd, (struct sockaddr *) &server_sockaddr, sizeof(server_sockaddr));
if (bind_result != 0)
{
printf("ERROR: Cannot bind to socket!\n");
return -1;
}
while (b_listen)
{
printf("Waiting for a connection...\n");
int listen_result = listen(server_sockfd, 1);
if (listen_result == -1)
{
printf("ERROR: Could not listen. code: %i", errno);
return -1;
}
int clientfd = accept(server_sockfd, NULL, NULL);
if (clientfd == -1)
{
printf("ERROR: Could not accept client!");
continue;
}
if (init_thread(&clientfd, thread_client_handler) == -1)
printf("Warning: Could not establish connection with client!");
}
return 0;
}
int stop_server()
{
return 0;
}
// Function used in thread to handle the connected client.
//TODO: Return a type with status, with message on why a value is returned.
void* thread_client_handler(void* arg)
{
int client_fd = *(int*)arg;
// Send data size to client.
ssize_t sNameSize = sizeof(sName);
uint32_t sDataSize = htonl(sNameSize);
int sendResult = writeToSock(client_fd, &sDataSize, sizeof(uint32_t));
if (sendResult == -1)// If we are not be able to send data, return so the thread can exit.
return NULL;
//char buff_recv[10];
sendResult = writeToSock(client_fd, &sName, sNameSize);
if (sendResult == -1)
return NULL;
char buff[50];
// Wait for command data from client.
for(;;)
{
printf("Listening to client for data!\n");
int rec_result;
rec_result = recv(client_fd, buff, sizeof(buff), 0);
if (rec_result == -1)
{
printf("Warning: could not recieve data from client!\n");
continue;
}
if (rec_result == 0)
{
printf("Client disconnected!\n");
break;
}
}
int close_result = close(client_fd);
printf("Close network result: %i\n", close_result);
return NULL;
}

34
src/sockets/sock_helper.c Normal file
View File

@ -0,0 +1,34 @@
#include "../sockets.h"
int writeToSock(int fd, void* data, ssize_t size)
{
ssize_t dataSizeSend = 0;
//dataSizeSend += send(fd, data, size, 0);
while (dataSizeSend < size)
{
dataSizeSend += send(fd, (char*)data + dataSizeSend, size - dataSizeSend, 0);
if (dataSizeSend == -1)
{
printf("Warning: Cannot send data!\n");
return -1;
}
}
return dataSizeSend;
}
// Do not check for buffer size!
int readFromSock(int fd, void* buff, ssize_t size)
{
ssize_t dataRecv = 0;
//dataRecv = recv(fd, buff, size, 0);
while (dataRecv < size)
{
dataRecv += recv(fd, (char*)buff + dataRecv, size - dataRecv, 0);
if (dataRecv == -1)
{
printf("Warning: Cannot receive data!\n");
return -1;
}
}
return dataRecv;
}

View File

@ -0,0 +1,16 @@
#include <stdio.h>
#include "thread_manager.h"
int init_thread(int* clientfd, void *(*func) (void *))
{
pthread_t thread;
int thread_create_result = pthread_create(&thread, NULL, func, clientfd);
if (thread_create_result == -1)
{
printf("ERROR: Could not create thread!\n");
return thread_create_result;
}
printf("Init thread: %lu\n", thread);
return 0;
}

View File

@ -0,0 +1,8 @@
#ifndef THREAD_MANAGER_H
#define THREAD_MANAGER_H
#include <pthread.h>
#include "../sockets.h"
int init_thread(int* clientfd, void *(*func) (void *));
#endif