initial commit
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
*.o
|
||||
.vscode
|
||||
.cache
|
||||
.idea
|
||||
build
|
||||
builddir
|
||||
speedtest
|
||||
*.swp
|
||||
*.log
|
||||
.proxy.sh
|
||||
.no-proxy.sh
|
||||
@@ -0,0 +1,25 @@
|
||||
cmake_minimum_required (VERSION 3.6)
|
||||
project(speedtest LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CMAKE_C_FLAGS "-ffunction-sections -fdata-sections")
|
||||
if (APPLE)
|
||||
elseif (UNIX)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections")
|
||||
endif()
|
||||
|
||||
include_directories(./src/lib/ ./src)
|
||||
|
||||
FILE(GLOB SOURCES src/*.c src/lib/*.c src/file_db/*.c src/config/*.c src/api/*.c src/database/*.c src/security/*.c src/utils/*.c)
|
||||
|
||||
option(USE_WERROR "Enable warnings as errors support" OFF)
|
||||
|
||||
if(USE_WERROR)
|
||||
add_definitions(-Werror)
|
||||
endif()
|
||||
|
||||
add_executable(
|
||||
speedtest
|
||||
${SOURCES}
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -g -std=gnu2x -ffunction-sections -fdata-sections
|
||||
LDFLAGS =
|
||||
INCLUDES = -I./src/lib -I./src
|
||||
SRCS = $(wildcard src/lib/*.c src/file_db/*.c src/*.c src/config/*.c src/database/*.c src/api/*.c src/security/*.c src/utils/*.c)
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
TARGET = speedtest
|
||||
BUILD_DIR=./build
|
||||
CROSS_COMPILE =
|
||||
LIBS =
|
||||
WERROR ?= 0
|
||||
|
||||
ifeq ($(shell uname), Linux)
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
endif
|
||||
|
||||
ifeq ($(WERROR), 1)
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CROSS_COMPILE)$(CC) $(LDFLAGS) $^ -o $@ $(LIBS)
|
||||
|
||||
%.o: %.c
|
||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET)
|
||||
|
||||
test: $(TARGET)
|
||||
bash ./tests.sh
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
project('speedtest', 'c', default_options: ['c_std=gnu2x'])
|
||||
include_dirs = include_directories('src')
|
||||
deps = []
|
||||
extra_c_args = ['-ffunction-sections', '-fdata-sections']
|
||||
extra_c_link_args = []
|
||||
system = host_machine.system()
|
||||
if system == 'linux'
|
||||
extra_c_link_args += ['-Wl,--gc-sections']
|
||||
endif
|
||||
|
||||
use_werror = get_option('use_werror')
|
||||
sources = ['src/main.c', 'src/client.c', 'src/server.c', 'src/utils.c']
|
||||
|
||||
if use_werror
|
||||
add_project_arguments('-Werror', language: 'c')
|
||||
endif
|
||||
|
||||
executable(
|
||||
'speedtest',
|
||||
sources,
|
||||
include_directories: include_dirs,
|
||||
dependencies: deps,
|
||||
c_args: extra_c_args,
|
||||
link_args: extra_c_link_args,
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
option('use_werror', type: 'boolean', value: false, description: 'Build with warning as errors')
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "client.h"
|
||||
#include "utils.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void run_client(const char *server_ip) {
|
||||
int sock;
|
||||
struct sockaddr_in serv_addr;
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
error("Ошибка создания сокета");
|
||||
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(PORT);
|
||||
|
||||
if (inet_pton(AF_INET, server_ip, &serv_addr.sin_addr) <= 0)
|
||||
error("Неверный адрес");
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
|
||||
error("Ошибка подключения");
|
||||
|
||||
// Отправка данных
|
||||
ssize_t total_sent = 0;
|
||||
double start = get_time_ms();
|
||||
|
||||
while (total_sent < TOTAL_DATA_SIZE) {
|
||||
ssize_t sent = send(sock, buffer, BUFFER_SIZE, 0);
|
||||
if (sent < 0) {
|
||||
error("Ошибка отправки");
|
||||
}
|
||||
total_sent += sent;
|
||||
}
|
||||
|
||||
double end = get_time_ms();
|
||||
double elapsed = end - start;
|
||||
|
||||
printf("Отправлено %.2f MB за %.2f ms\n", (double)total_sent / (1024 * 1024),
|
||||
elapsed);
|
||||
printf("Скорость: %.2f Mbps\n", (total_sent * 8) / (elapsed * 1000));
|
||||
|
||||
close(sock);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void run_client(const char *server_ip);
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#include "client.h"
|
||||
#include "server.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 2 && (!strcmp(argv[1], "server") || !strcmp(argv[1], "s"))) {
|
||||
run_server(false);
|
||||
} else if (argc == 3 && (!strcmp(argv[1], "client") || !strcmp(argv[1], "c"))) {
|
||||
run_client(argv[2]);
|
||||
} else if (argc == 3 && (!strcmp(argv[1], "server") || !strcmp(argv[1], "s"))) {
|
||||
run_server(true);
|
||||
} else {
|
||||
printf("Использование:\n");
|
||||
printf("Сервер: %s server|s\n", argv[0]);
|
||||
printf("Сервер: %s server|s <test>\n", argv[0]);
|
||||
printf("Клиент: %s client|c <IP сервера>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "server.h"
|
||||
#include "utils.h"
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void run_server(const bool testing) {
|
||||
int server_fd, client_fd;
|
||||
struct sockaddr_in address;
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
|
||||
error("Сокет не создан");
|
||||
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
address.sin_port = htons(PORT);
|
||||
|
||||
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) <
|
||||
0)
|
||||
error("Ошибка setsockopt");
|
||||
|
||||
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
|
||||
error("Ошибка bind");
|
||||
|
||||
if (listen(server_fd, 3) < 0)
|
||||
error("Ошибка listen");
|
||||
|
||||
printf("Сервер запущен на порту %d\n", PORT);
|
||||
|
||||
while (1) {
|
||||
socklen_t addrlen = sizeof(address);
|
||||
if ((client_fd = accept(server_fd, (struct sockaddr *)&address, &addrlen)) <
|
||||
0)
|
||||
error("Ошибка accept");
|
||||
|
||||
// Прием данных
|
||||
ssize_t total_received = 0;
|
||||
double start = get_time_ms();
|
||||
|
||||
while (total_received < TOTAL_DATA_SIZE) {
|
||||
ssize_t received = recv(client_fd, buffer, BUFFER_SIZE, 0);
|
||||
if (received < 0) {
|
||||
error("Ошибка приема");
|
||||
}
|
||||
total_received += received;
|
||||
}
|
||||
|
||||
double end = get_time_ms();
|
||||
double elapsed = end - start;
|
||||
|
||||
printf("Получено %.2f MB за %.2f ms\n",
|
||||
(double)total_received / (1024 * 1024), elapsed);
|
||||
printf("Скорость: %.2f Mbps\n", (total_received * 8) / (elapsed * 1000));
|
||||
|
||||
close(client_fd);
|
||||
if (testing) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(server_fd);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void run_server(const bool testing);
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#include "utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
void error(const char *msg) {
|
||||
perror(msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
double get_time_ms() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec * 1000.0) + (tv.tv_usec / 1000.0);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#define PORT 8080
|
||||
#define BUFFER_SIZE 1024
|
||||
#define TOTAL_DATA_SIZE (1024 * 1024 * 100) // 100 MB
|
||||
|
||||
void error(const char *msg);
|
||||
double get_time_ms();
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
(
|
||||
./speedtest s test
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
echo "Speedtest server successful"
|
||||
else
|
||||
echo "Speedtest server failed"
|
||||
exit 1
|
||||
fi
|
||||
) &
|
||||
sleep 0.3
|
||||
./speedtest c 127.0.0.1
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
echo "Speedtest client successful"
|
||||
else
|
||||
echo "Speedtest client failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wait
|
||||
exit 0
|
||||
Reference in New Issue
Block a user