Bladeren bron

Рабочая версия с CMake

Mikhail Zaytsev 1 jaar geleden
bovenliggende
commit
3061c26368
11 gewijzigde bestanden met toevoegingen van 296 en 309 verwijderingen
  1. 2 0
      .gitignore
  2. 0 31
      .vscode/launch.json
  3. 0 28
      .vscode/tasks.json
  4. 5 0
      CMakeLists.txt
  5. 17 0
      CMakePresets.json
  6. BIN
      client
  7. 0 249
      client.c
  8. 128 1
      command.c
  9. 41 0
      command.h
  10. 103 0
      main.c
  11. 0 0
      main.h

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+# Specify filepatterns you want git to ignore.
+out/

+ 0 - 31
.vscode/launch.json

@@ -1,31 +0,0 @@
-{
-    "configurations": [
-        {
-            "name": "C/C++: gcc-11 build and debug active file",
-            "type": "cppdbg",
-            "request": "launch",
-            "program": "${fileDirname}/${fileBasenameNoExtension}",
-            "args": ["127.0.0.1"],
-            "stopAtEntry": false,
-            "cwd": "${fileDirname}",
-            "environment": [],
-            "externalConsole": false,
-            "MIMode": "gdb",
-            "setupCommands": [
-                {
-                    "description": "Enable pretty-printing for gdb",
-                    "text": "-enable-pretty-printing",
-                    "ignoreFailures": true
-                },
-                {
-                    "description": "Set Disassembly Flavor to Intel",
-                    "text": "-gdb-set disassembly-flavor intel",
-                    "ignoreFailures": true
-                }
-            ],
-            "preLaunchTask": "C/C++: gcc-11 build active file",
-            "miDebuggerPath": "/usr/bin/gdb"
-        }
-    ],
-    "version": "2.0.0"
-}

+ 0 - 28
.vscode/tasks.json

@@ -1,28 +0,0 @@
-{
-    "tasks": [
-        {
-            "type": "cppbuild",
-            "label": "C/C++: gcc-11 build active file",
-            "command": "/usr/bin/gcc-11",
-            "args": [
-                "-fdiagnostics-color=always",
-                "-g",
-                "${file}",
-                "-o",
-                "${fileDirname}/${fileBasenameNoExtension}"
-            ],
-            "options": {
-                "cwd": "${fileDirname}"
-            },
-            "problemMatcher": [
-                "$gcc"
-            ],
-            "group": {
-                "kind": "build",
-                "isDefault": true
-            },
-            "detail": "Task generated by Debugger."
-        }
-    ],
-    "version": "2.0.0"
-}

+ 5 - 0
CMakeLists.txt

@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.5.0)
+project(client VERSION 0.1.0 LANGUAGES C CXX)
+
+add_executable(client command.c main.c)
+

+ 17 - 0
CMakePresets.json

@@ -0,0 +1,17 @@
+{
+    "version": 8,
+    "configurePresets": [
+        {
+            "name": "gcc-client",
+            "displayName": "GCC 11.4.0 x86_64-linux-gnu",
+            "description": "Using compilers: C = /usr/bin/gcc, CXX = /usr/bin/g++",
+            "binaryDir": "${sourceDir}/out/build/${presetName}",
+            "cacheVariables": {
+                "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
+                "CMAKE_C_COMPILER": "/usr/bin/gcc",
+                "CMAKE_CXX_COMPILER": "/usr/bin/g++",
+                "CMAKE_BUILD_TYPE": "Debug"
+            }
+        }
+    ]
+}

BIN
client


+ 0 - 249
client.c

@@ -1,249 +0,0 @@
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <arpa/inet.h> 
-#include <inttypes.h>
-#include <signal.h>
-
-volatile int sockfd = 0;
-
-typedef void (*CommandHandler)(char*);
-
-// Определяем тип функции преобразования
-typedef void (*ConvertFunc)(char *str, void *output);
-
-void handleCloseSignal(int signal);
-void handleFreqCmd(char* recvBuff);
-void handleLdCmd(char* recvBuff);
-void handlePowCmd(char* recvBuff);
-void handleArmCmd(char* recvBuff);
-void handleAttCmd(char* recvBuff);
-void handleIdnCmd(char* recvBuff);
-void processCommand(char* recvBuff);
-void convertToUInt16(char *str, void *output);
-void convertToUint64(char *str, void *output);
-void convertToDouble(char *str, void *output);
-void splitLexeme(uint8_t *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc);
-
-//Обработчик ошибок
-void error(const char *msg)
-{
-	perror(msg);
-
-	if (sockfd != 0) 
-	{
-		close(sockfd);
-	}
-
-	exit(1);
-} 
-
-//Обработчик сигнала SIGINT завершения программы при нажатии Ctrl+C
-void handleCloseSignal(int signal)
-{
-	if (signal == SIGINT) 
-	{
-		printf("\nCaught signal %d, closing socket and exiting...\n", signal);
-		if (sockfd != 0) 
-		{
-			close(sockfd);
-		}
-		exit(0);
-	}
-}
-
-//handleXXXXCmd - обработчики команд
-void handleFreqCmd(char* recvBuff)
-{
-	printf("\nTMSG44:FREQ\n");
-	uint64_t freq[1] = {0};
-
-	splitLexeme(recvBuff, freq, sizeof(freq[0]), convertToUint64);
-
-	printf("%" PRId64 "\n", freq[0]);
-}
-
-void handleLdCmd(char* recvBuff)
-{
-	printf("\nTMSG44:LD?\n");
-}
-
-void handlePowCmd(char* recvBuff)
-{
-	printf("\nTMSG44:POW\n");
-	double pow[1] = {0};
-
-	splitLexeme(recvBuff, pow, sizeof(pow[0]), convertToDouble);
-	printf("%f\n", pow[0]);
-}
-
-void handleArmCmd(char* recvBuff)
-{
-	printf("\nTMSG44:ARM\n");
-	uint16_t armCode[1] = {0};
-
-	splitLexeme(recvBuff, armCode, sizeof(armCode[0]), convertToUInt16);
-	printf("\n%u\n", armCode[0]);
-}
-
-void handleAttCmd(char* recvBuff)
-{
-	printf("\nTMSG44:ATT\n");
-	uint16_t attCode[1] = {0};
-
-	splitLexeme(recvBuff, attCode, sizeof(attCode[0]), convertToUInt16);
-	printf("\n%u\n", attCode[0]);
-}
-
-void handleIdnCmd(char* recvBuff)
-{
-	printf("\n*IDN?\n");
-}
-
-typedef struct {
-	const char* command;
-	CommandHandler handler;
-} Command;
-
-//Массив структур Command, который связывает строки команд с соответствующими функциями.
-Command commands[] = {
-	{"TMSG44:FREQ ", 	handleFreqCmd},
-	{"TMSG44:LD?", 		handleLdCmd},
-	{"TMSG44:POW ", 	handlePowCmd},
-	{"TMSG44:ARM ", 	handleArmCmd},
-	{"TMSG44:ATT ", 	handleAttCmd},
-	{"*IDN?", 			handleIdnCmd},
-	{NULL, NULL} // Завершающий элемент для обозначения конца массива
-};
-
-//Проходим по массиву команд и ищем команду, которая совпадает с началом строки recvBuff. 
-//Если команда найдена, вызывается соответствующая функция-обработчик
-void processCommand(char* recvBuff) 
-{
-	for (int i = 0; commands[i].command != NULL; i++) 
-	{
-		if (!strncasecmp(recvBuff, commands[i].command, strlen(commands[i].command))) 
-		{
-			commands[i].handler(recvBuff);
-			return;
-		}
-	}
-	printf("\nUnknown command: %s\n", recvBuff);
-}
-
-//=========================================================//
-
-// Преобразование строки в uint16_t
-void convertToUInt16(char *str, void *output) 
-{
-	*(uint16_t *)output = (uint16_t)strtoul(str, NULL, 10);
-}
-
-// Преобразование строки в unsigned long long int
-void convertToUint64(char *str, void *output) 
-{
-	*(uint64_t *)output = (uint64_t)strtoull(str, NULL, 10);
-}
-
-// Преобразование строки в double
-void convertToDouble(char *str, void *output) 
-{
-	*(double *)output = strtod(str, NULL);
-}
-
-// Универсальная функция для разделения строки на лексемы
-void splitLexeme(uint8_t *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc) 
-{
-	uint8_t counter = 0;
-
-	// Разделители лексем
-	char charSeparator[3] = {' ', '\n', '\\'};
-	char *ptrLexeme = NULL;
-
-	// Инициализируем функцию
-	ptrLexeme = strtok((char *)ptrSCPI, charSeparator);
-
-	// Ищем лексемы разделенные разделителем
-	ptrLexeme = strtok(NULL, charSeparator);
-
-	// Ищем лексемы строки
-	while (ptrLexeme) {
-		// Проверяем, является ли первый символ лексемы числом
-		if(('0' <= ptrLexeme[0]) && (ptrLexeme[0] <= '9')) {
-			// Преобразуем строку с числом в число
-			convertFunc(ptrLexeme, (uint8_t *)numOutAndValue + counter * elementSize);
-			counter++;
-		}
-		// Ищем лексемы разделенные разделителем
-		ptrLexeme = strtok(NULL, charSeparator);
-	}
-}
-//====================================================//
-
-int main(int argc, char *argv[])
-{
-	//argv[1] = "127.0.0.1";
-	int n = 0;
-	char recvBuff[1024];
-	struct sockaddr_in serv_addr;
-
-	// Установка обработчика сигналов
-	signal(SIGINT, handleCloseSignal);
-
-	if(argc != 2)
-	{
-		printf("\n Usage: %s <ip of server> \n",argv[0]);
-		return 1;
-	} 
-
-	memset(recvBuff, '0',sizeof(recvBuff));
-	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-	{
-		error("Error : Could not create socket");
-	} 
-
-	memset(&serv_addr, '0', sizeof(serv_addr)); 
-
-	serv_addr.sin_family = AF_INET;
-	serv_addr.sin_port = htons(5000); 
-
-	if (inet_pton(AF_INET, argv[1], &serv_addr.sin_addr) <= 0)
-	{
-		error("inet_pton error occured");
-	} 
-
-	if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
-	{
-	   error("Error : Connect Failed");
-	}
-
-	while ((n = read(sockfd, recvBuff, sizeof(recvBuff) - 1)) > 0)
-	{
-		recvBuff[n] = 0;
-		if(fputs(recvBuff, stdout) == EOF)
-		{
-			printf("\n Error : Fputs error\n");
-			break;
-		}
-		//Запуск парсера команд
-		processCommand(recvBuff);
-	} 
-
-	if (n == 0)
-	{
-		// Соединение закрыто сервером
-		printf("\n Server closed the connection\n");
-	}
-	else if (n < 0)
-	{
-		error("Read error");
-	} 
-
-	close(sockfd);
-	return 0;
-}

+ 128 - 1
command.c

@@ -1 +1,128 @@
-111
+#include "command.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <strings.h>
+#include <string.h>
+
+//Массив структур Command, который связывает строки команд с соответствующими функциями.
+Command commands[] = {
+	{"TMSG44:FREQ ", 	handleFreqCmd},
+	{"TMSG44:LD?", 		handleLdCmd},
+	{"TMSG44:POW ", 	handlePowCmd},
+	{"TMSG44:ARM ", 	handleArmCmd},
+	{"TMSG44:ATT ", 	handleAttCmd},
+	{"*IDN?", 			handleIdnCmd},
+	{NULL, NULL} // Завершающий элемент для обозначения конца массива
+};
+
+//handleXXXXCmd - обработчики команд
+void handleFreqCmd(char* recvBuff)
+{
+	printf("\nTMSG44:FREQ\n");
+	uint64_t freq[1] = {0};
+
+	splitLexeme(recvBuff, freq, sizeof(freq[0]), convertToUint64);
+
+	printf("%" PRId64 "\n", freq[0]);
+}
+
+void handleLdCmd(char* recvBuff)
+{
+	printf("\nTMSG44:LD?\n");
+}
+
+void handlePowCmd(char* recvBuff)
+{
+	printf("\nTMSG44:POW\n");
+	double pow[1] = {0};
+
+	splitLexeme(recvBuff, pow, sizeof(pow[0]), convertToDouble);
+	printf("%f\n", pow[0]);
+}
+
+void handleArmCmd(char* recvBuff)
+{
+	printf("\nTMSG44:ARM\n");
+	uint16_t armCode[1] = {0};
+
+	splitLexeme(recvBuff, armCode, sizeof(armCode[0]), convertToUInt16);
+	printf("\n%u\n", armCode[0]);
+}
+
+void handleAttCmd(char* recvBuff)
+{
+	printf("\nTMSG44:ATT\n");
+	uint16_t attCode[1] = {0};
+
+	splitLexeme(recvBuff, attCode, sizeof(attCode[0]), convertToUInt16);
+	printf("\n%u\n", attCode[0]);
+}
+
+void handleIdnCmd(char* recvBuff)
+{
+	printf("\n*IDN?\n");
+}
+
+//Проходим по массиву команд и ищем команду, которая совпадает с началом строки recvBuff. 
+//Если команда найдена, вызывается соответствующая функция-обработчик
+void processCommand(char* recvBuff) 
+{
+	for (int i = 0; commands[i].command != NULL; i++) 
+	{
+		if (!strncasecmp(recvBuff, commands[i].command, strlen(commands[i].command))) 
+		{
+			commands[i].handler(recvBuff);
+			return;
+		}
+	}
+	printf("\nUnknown command: %s\n", recvBuff);
+}
+
+// Преобразование строки в uint16_t
+void convertToUInt16(char *str, void *output) 
+{
+	*(uint16_t *)output = (uint16_t)strtoul(str, NULL, 10);
+}
+
+// Преобразование строки в unsigned long long int
+void convertToUint64(char *str, void *output) 
+{
+	*(uint64_t *)output = (uint64_t)strtoull(str, NULL, 10);
+}
+
+// Преобразование строки в double
+void convertToDouble(char *str, void *output) 
+{
+	*(double *)output = strtod(str, NULL);
+}
+
+// Универсальная функция для разделения строки на лексемы
+void splitLexeme(uint8_t *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc) 
+{
+	uint8_t counter = 0;
+
+	// Разделители лексем
+	char charSeparator[3] = {' ', '\n', '\\'};
+	char *ptrLexeme = NULL;
+
+	// Инициализируем функцию
+	ptrLexeme = strtok((char *)ptrSCPI, charSeparator);
+
+	// Ищем лексемы разделенные разделителем
+	ptrLexeme = strtok(NULL, charSeparator);
+
+	// Ищем лексемы строки
+	while (ptrLexeme) {
+		// Проверяем, является ли первый символ лексемы числом
+		if(('0' <= ptrLexeme[0]) && (ptrLexeme[0] <= '9')) {
+			// Преобразуем строку с числом в число
+			convertFunc(ptrLexeme, (uint8_t *)numOutAndValue + counter * elementSize);
+			counter++;
+		}
+		// Ищем лексемы разделенные разделителем
+		ptrLexeme = strtok(NULL, charSeparator);
+	}
+}

+ 41 - 0
command.h

@@ -0,0 +1,41 @@
+#ifndef COMMAND_H
+#define COMMAND_H
+
+// Включение необходимых стандартных библиотек
+#include <stdint.h>
+#include <stddef.h>
+
+// Определение констант
+
+
+// Определение макросов
+
+
+// Объявление глобальных переменных
+
+typedef void (*CommandHandler)(char*);
+
+// Объявление структур
+typedef struct {
+	const char* command;
+	CommandHandler handler;
+} Command;
+
+// Определяем тип функции преобразования
+typedef void (*ConvertFunc)(char *str, void *output);
+
+// Прототипы функций
+void handleCloseSignal(int signal);
+void handleFreqCmd(char* recvBuff);
+void handleLdCmd(char* recvBuff);
+void handlePowCmd(char* recvBuff);
+void handleArmCmd(char* recvBuff);
+void handleAttCmd(char* recvBuff);
+void handleIdnCmd(char* recvBuff);
+void processCommand(char* recvBuff);
+void convertToUInt16(char *str, void *output);
+void convertToUint64(char *str, void *output);
+void convertToDouble(char *str, void *output);
+void splitLexeme(uint8_t *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc);
+
+#endif /* COMMAND_H */

+ 103 - 0
main.c

@@ -0,0 +1,103 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <arpa/inet.h> 
+#include <signal.h>
+
+#include "command.h"
+
+volatile int sockfd = 0;
+
+//Обработчик ошибок
+void error(const char *msg)
+{
+	perror(msg);
+
+	if (sockfd != 0) 
+	{
+		close(sockfd);
+	}
+
+	exit(1);
+} 
+
+//Обработчик сигнала SIGINT завершения программы при нажатии Ctrl+C
+void handleCloseSignal(int signal)
+{
+	if (signal == SIGINT) 
+	{
+		printf("\nCaught signal %d, closing socket and exiting...\n", signal);
+		if (sockfd != 0) 
+		{
+			close(sockfd);
+		}
+		exit(0);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	//argv[1] = "127.0.0.1";
+	int n = 0;
+	char recvBuff[1024];
+	struct sockaddr_in serv_addr;
+
+	// Установка обработчика сигналов
+	signal(SIGINT, handleCloseSignal);
+
+	if(argc != 2)
+	{
+		printf("\n Usage: %s <ip of server> \n",argv[0]);
+		return 1;
+	} 
+
+	memset(recvBuff, '0',sizeof(recvBuff));
+	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+	{
+		error("Error : Could not create socket!");
+	} 
+
+	memset(&serv_addr, '0', sizeof(serv_addr)); 
+
+	serv_addr.sin_family = AF_INET;
+	serv_addr.sin_port = htons(5000); 
+
+	if (inet_pton(AF_INET, argv[1], &serv_addr.sin_addr) <= 0)
+	{
+		error("inet_pton error occured");
+	} 
+
+	if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
+	{
+	   error("Error : Connect Failed");
+	}
+
+	while ((n = read(sockfd, recvBuff, sizeof(recvBuff) - 1)) > 0)
+	{
+		recvBuff[n] = 0;
+		if(fputs(recvBuff, stdout) == EOF)
+		{
+			printf("\n Error : Fputs error\n");
+			break;
+		}
+		//Запуск парсера команд
+		processCommand(recvBuff);
+	} 
+
+	if (n == 0)
+	{
+		// Соединение закрыто сервером
+		printf("\n Server closed the connection\n");
+	}
+	else if (n < 0)
+	{
+		error("Read error");
+	} 
+
+	close(sockfd);
+	return 0;
+}

+ 0 - 0
main.h