Skip to content
Snippets Groups Projects
Commit dfa0952c authored by Votre Nom's avatar Votre Nom
Browse files

Simplify network communication. Fix a big problem with blc_network.py

parent 716c73a2
No related branches found
No related tags found
No related merge requests found
Showing
with 205 additions and 525 deletions
...@@ -7,11 +7,11 @@ find_package(PNG) ...@@ -7,11 +7,11 @@ find_package(PNG)
add_library(objlib OBJECT add_library(objlib OBJECT
src/channel/blc_channel.cpp src/channel/channel_file.cpp src/channel/blc_channel.cpp src/channel/channel_file.cpp
src/core/blc_array.cpp src/core/blc_mem.cpp src/core/blc_realtime.cpp src/core/blc_text.cpp src/core/blc_tools.cpp src/core/blc_array.cpp src/core/c_blc_array.cpp src/core/blc_mem.cpp src/core/blc_realtime.cpp src/core/blc_text.cpp src/core/blc_tools.cpp
src/image/blc_image.cpp src/image/jpeg_tools.cpp src/image/blc_image.cpp src/image/jpeg_tools.cpp
src/network/blc_array_tcp4_client.cpp src/network/blc_array_tcp4_server.cpp src/network/blc_array_network.cpp src/network/blc_network.cpp src/network/blc_array_tcp4_client.cpp src/network/blc_array_tcp4_server.cpp src/network/c_blc_array_tcp4_server.cpp
src/process/blc_process.cpp src/process/blc_process.cpp
src/program/blc_command.cpp src/program/blc_loop.cpp src/program/blc_program.cpp src/program/blc_command.cpp src/program/blc_loop.cpp src/program/blc_program.cpp
) )
add_library(blc SHARED $<TARGET_OBJECTS:objlib>) add_library(blc SHARED $<TARGET_OBJECTS:objlib>)
...@@ -28,19 +28,17 @@ target_include_directories(objlib PUBLIC ...@@ -28,19 +28,17 @@ target_include_directories(objlib PUBLIC
) )
if (JPEG_FOUND) if (JPEG_FOUND)
target_include_directories(objlib PRIVATE ${JPEG_INCLUDE_DIRS}) target_include_directories(objlib PRIVATE ${JPEG_INCLUDE_DIRS})
target_link_libraries(blc PRIVATE ${JPEG_LIBRARY}) target_link_libraries(blc PRIVATE ${JPEG_LIBRARY})
else() else()
message("Without libjpeg") message("Without libjpeg")
target_compile_definitions(blc PRIVATE -DWITHOUT_JPEG) target_compile_definitions(blc PRIVATE -DWITHOUT_JPEG)
endif() endif()
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
target_link_libraries(blc PRIVATE rt) target_link_libraries(blc PRIVATE rt)
endif() endif()
#Both version of librairies will have the same name only the extension will change. #Both version of librairies will have the same name only the extension will change.
set_target_properties(static_blc PROPERTIES OUTPUT_NAME blc) set_target_properties(static_blc PROPERTIES OUTPUT_NAME blc)
...@@ -50,11 +48,8 @@ install(TARGETS blc static_blc ...@@ -50,11 +48,8 @@ install(TARGETS blc static_blc
INCLUDES DESTINATION include/blc INCLUDES DESTINATION include/blc
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
) )
install(DIRECTORY include/ DESTINATION include/blc) install(DIRECTORY include/ DESTINATION include/blc)
install(DIRECTORY python/ DESTINATION lib/blc_python) install(DIRECTORY python/ DESTINATION lib/blc_python)
install(EXPORT blc-config DESTINATION share/blc ) install(EXPORT blc-config DESTINATION share/blc )
...@@ -89,25 +89,21 @@ typedef struct blc_array ...@@ -89,25 +89,21 @@ typedef struct blc_array
/* Modifying the properties of the array /* Modifying the properties of the array
======================================*/ ======================================*/
void set_dims(uint32_t type, std::vector<size_t> const &lengths);
/**Add one dimention to the definition of the blc_array. You have to manage eventual **memory reallocation** yourself.*/ /**Add one dimention to the definition of the blc_array. You have to manage eventual **memory reallocation** yourself.*/
void add_dim(size_t length, size_t step); void add_dim(size_t length, size_t step);
/**Add one dimension ti the definition of the blc_array. The step is infered from the type of the data and the size of the previous dimension. You have to manage the eventual **memory reallocation** yourself.*/ /**Add one dimension ti the definition of the blc_array. The step is infered from the type of the data and the size of the previous dimension. You have to manage the eventual **memory reallocation** yourself.*/
void add_dim(size_t length); void add_dim(size_t length);
/** Set all the dims of the array*/
void set_dims(int dims_nb, size_t length0, ...); //Should use vector<size_t> instead of ...
/**Set all dims by reading the properties from the string (i.e. "3x800x600" ). You have to manage eventual **memory reallocation** yourself. */ /**Set all dims by reading the properties from the string (i.e. "3x800x600" ). You have to manage eventual **memory reallocation** yourself. */
int sscan_dims(char const* string); int sscan_dims(char const* string);
/**Set all dims by reading the properties from the file (i.e. "3x800x600" ). You have to manage eventual **memory reallocation** yourself. */ /**Set all dims by reading the properties from the file (i.e. "3x800x600" ). You have to manage eventual **memory reallocation** yourself. */
void fscan_dims(FILE *file); void fscan_dims(FILE *file);
/**Set the dims of the arrray*/
void set_dims(uint32_t type, std::vector<size_t> const &lengths);
/**Set all properties by reading the properties from the string (i.e. "UIN8 RGB3 3x800x600" ). You have to manage eventual **memory reallocation** yourself. */ /**Set all properties by reading the properties from the string (i.e. "UIN8 RGB3 3x800x600" ). You have to manage eventual **memory reallocation** yourself. */
void sscan_properties(char const *string); void sscan_properties(char const *string);
/**Set all properties by reading the properties from the file (i.e. "UIN8 RGB3 3x800x600" ). You have to manage eventual **memory reallocation** yourself. */ /**Set all properties by reading the properties from the file (i.e. "UIN8 RGB3 3x800x600" ). You have to manage eventual **memory reallocation** yourself. */
void fscan_properties(FILE *file); void fscan_properties(FILE *file);
// size_t get_minimum_size();
/*Reading data from files /*Reading data from files
======================*/ ======================*/
......
//
// blc_array_network.h
// blc
//
// Created by Arnaud Blanchard on 10/11/2020.
//
#ifndef blc_array_network_h
#define blc_array_network_h
#include "blc_array.h"
typedef struct blc_array_network
#ifdef __cplusplus
:blc_array{
~blc_array_network();
virtual int recv_data()=0;
virtual int send_data()=0;
#else
blc_array array;
#endif
int socket_fd;
}blc_array_network;
#endif /* blc_array_network_h */
#ifndef BLC_ARRAY_TCP4_CLIENT_H #ifndef BLC_ARRAY_TCP4_CLIENT_H
#define BLC_ARRAY_TCP4_CLIENT_H #define BLC_ARRAY_TCP4_CLIENT_H
#include"blc_array_network.h" #include"blc_array.h"
#ifdef __cplusplus #ifdef __cplusplus
#include <string> #include <string>
...@@ -10,11 +10,13 @@ ...@@ -10,11 +10,13 @@
typedef struct blc_array_tcp4_client typedef struct blc_array_tcp4_client
#ifdef __cplusplus #ifdef __cplusplus
:blc_array_network { :blc_array{
blc_array_tcp4_client(std::string const &address, std::string const &port_name); blc_array_tcp4_client(std::string const &address, std::string const &port_name);
blc_array_tcp4_client(std::string const &address, std::string const &port_name, uint32_t type, uint32_t format, std::vector<size_t> const &lengths); blc_array_tcp4_client(std::string const &address, std::string const &port_name, uint32_t type, uint32_t format, std::vector<size_t> const &lengths);
~blc_array_tcp4_client();
void read_properties(); void read_properties();
// void server_manager(); // void server_manager();
int recv_data(); int recv_data();
int bytes_to_read(); int bytes_to_read();
...@@ -22,6 +24,7 @@ typedef struct blc_array_tcp4_client ...@@ -22,6 +24,7 @@ typedef struct blc_array_tcp4_client
#else #else
{ blc_array array;// Not beautiful but makes it easy to convert C++ heritage of "class" in C struct inclusion. { blc_array array;// Not beautiful but makes it easy to convert C++ heritage of "class" in C struct inclusion.
#endif #endif
int socket_fd;
}blc_array_tcp4_client; }blc_array_tcp4_client;
START_EXTERN_C START_EXTERN_C
......
#ifndef BLC_ARRAY_TCP4_SERVER_HPP #ifndef BLC_ARRAY_TCP4_SERVER_HPP
#define BLC_ARRAY_TCP4_SERVER_HPP #define BLC_ARRAY_TCP4_SERVER_HPP
#include"blc_array_network.h" #include"blc_array.h"
#include <string> #include <string>
#include <thread> //#include <thread>
typedef struct blc_array_tcp4_server typedef struct blc_array_tcp4_server
#ifdef __cplusplus #ifdef __cplusplus
:blc_array_network { :blc_array {
blc_array_tcp4_server(std::string const &port_name); blc_array_tcp4_server(std::string const &port_name);
blc_array_tcp4_server(std::string const &port_name, blc_array &array); blc_array_tcp4_server(std::string const &port_name, blc_array &array);
blc_array_tcp4_server(std::string const &port_name, uint32_t type, uint32_t format, std::vector<size_t> const &lengths); blc_array_tcp4_server(std::string const &port_name, uint32_t type, uint32_t format, std::vector<size_t> const &lengths);
~blc_array_tcp4_server();
void read_properties(); void read_properties();
void send_properties(); void send_properties();
...@@ -22,7 +22,8 @@ typedef struct blc_array_tcp4_server ...@@ -22,7 +22,8 @@ typedef struct blc_array_tcp4_server
#else #else
blc_array *array; blc_array *array;
#endif #endif
int client_socket; //We suppose only on client int socket_fd; //server socket
int client_socket; //We suppose we have only one client
}blc_array_tcp4_server; }blc_array_tcp4_server;
START_EXTERN_C START_EXTERN_C
......
//
// blc_network.h
// network
//
// Created by Arnaud Blanchard on 30/05/2015.
//
//
/**
@defgroup blc_network network
Few functions helping for pseudo realtime applications.
@{*/
#ifndef BLC_NETWORK_H
#define BLC_NETWORK_H
#include "blc_network_base.h"
#include "blc_array_tcp4_client.h"
#include "blc_array_tcp4_server.h"
#endif
///@}
...@@ -25,8 +25,8 @@ class BlcArray: ...@@ -25,8 +25,8 @@ class BlcArray:
lib.blc_array_get_dims.argtypes = [ c_void_p ] lib.blc_array_get_dims.argtypes = [ c_void_p ]
lib.blc_array_get_data.argtypes = [ c_void_p ] lib.blc_array_get_data.argtypes = [ c_void_p ]
lib.blc_array_get_data.restype = c_void_p lib.blc_array_get_data.restype = c_void_p
lib.blc_array_delete.argtypes = [ c_void_p ] lib.blc_array_delete.argtypes = [ c_void_p ]
types={ 'UIN8': c_uint8, 'INT8': c_int8, 'UI16': c_uint16, 'IN16': c_int16, 'UI32': c_uint32, 'IN32': c_int32, 'UI64': c_uint64, 'IN64': c_int64, 'FL32': c_float, 'FL64': c_double} types={ 'UIN8': c_uint8, 'INT8': c_int8, 'UI16': c_uint16, 'IN16': c_int16, 'UI32': c_uint32, 'IN32': c_int32, 'UI64': c_uint64, 'IN64': c_int64, 'FL32': c_float, 'FL64': c_double}
def __init__(self, data_type=None, format_type=None, dims=None): def __init__(self, data_type=None, format_type=None, dims=None):
...@@ -36,12 +36,11 @@ class BlcArray: ...@@ -36,12 +36,11 @@ class BlcArray:
if (dims): #Creates if (dims): #Creates
dim_types = [c_size_t] * len(dims) dim_types = [c_size_t] * len(dims)
print(len(dims), *dims);
lib.blc_array_new.argtypes = [c_uint32, c_uint32, c_int, *dim_types ] lib.blc_array_new.argtypes = [c_uint32, c_uint32, c_int, *dim_types ]
# Create a new array # Create a new array
self.pointer = lib.blc_array_new(int.from_bytes(data_type.encode(), "big"), int.from_bytes(format_type.encode(), "big"), len(dims), *dims) self.pointer = lib.blc_array_new(int.from_bytes(data_type.encode(), "big"), int.from_bytes(format_type.encode(), "big"), len(dims), *dims)
total_length = lib.blc_array_get_total_length(self.pointer) total_length = lib.blc_array_get_total_length(self.pointer)
# Specify types for array # Specify types for array
...@@ -51,16 +50,12 @@ class BlcArray: ...@@ -51,16 +50,12 @@ class BlcArray:
self.data = cast(lib.blc_array_get_data(self.pointer), POINTER(self.ctype*total_length)).contents self.data = cast(lib.blc_array_get_data(self.pointer), POINTER(self.ctype*total_length)).contents
else: else:
self.pointer = lib.blc_array_new_void() self.pointer = lib.blc_array_new_void()
# lib.blc_array_get_dims.restype = POINTER(BlcDim * dims_nb)
# blc_dims=BlcChannel.lib.blc_channel_get_dims(self.channel)
# self.dims=[]
# for i in range(self.dims_nb):
# self.dims.append(blc_dims[0][i].length)
def get_def(self): def get_def(self):
self.type=lib.blc_array_get_type(self.pointer).to_bytes(4, "big").decode() self.type=lib.blc_array_get_type(self.pointer).to_bytes(4, "big").decode()
self.ctype = BlcArray.types[self.type] self.ctype = BlcArray.types[self.type]
self.format=lib.blc_array_get_format(self.pointer).to_bytes(4, "big").decode() self.format=lib.blc_array_get_format(self.pointer)
dims_nb=lib.blc_array_get_dims_nb(self.pointer) dims_nb=lib.blc_array_get_dims_nb(self.pointer)
lib.blc_array_get_dims.restype = POINTER(BlcDim * dims_nb) lib.blc_array_get_dims.restype = POINTER(BlcDim * dims_nb)
...@@ -69,8 +64,8 @@ class BlcArray: ...@@ -69,8 +64,8 @@ class BlcArray:
for i in range(dims_nb): for i in range(dims_nb):
self.dims.append(blc_dims[0][i].length) self.dims.append(blc_dims[0][i].length)
total_length = lib.blc_array_get_total_length(self.pointer) self.total_length = lib.blc_array_get_total_length(self.pointer)
self.data = cast(lib.blc_array_get_data(self.pointer), POINTER(self.ctype*total_length)).contents self.data = cast(lib.blc_array_get_data(self.pointer), POINTER(self.ctype*self.total_length)).contents
def __del__(self): def __del__(self):
lib.blc_array_delete(self.pointer) lib.blc_array_delete(self.pointer)
...@@ -80,8 +75,8 @@ if __name__ == "__main__": ...@@ -80,8 +75,8 @@ if __name__ == "__main__":
undef_array = BlcArray() undef_array = BlcArray()
array = BlcArray('UIN8', 'TEXT', [16, 3]) array = BlcArray('UIN8', 'TEXT', [16, 3])
#array.get_def() #Useless here, only for testing the function array.get_def() #Useless here, only for testing the function
#print("type",array.type, "format", array.format, "length", len(array.data)) print("type",array.type, "format", array.format, "length", len(array.data))
# print(array.data[:array.total_length]) print(array.data[:array.total_length])
...@@ -3,12 +3,13 @@ from ctypes import * ...@@ -3,12 +3,13 @@ from ctypes import *
from ctypes.util import find_library from ctypes.util import find_library
from blc_array import BlcArray from blc_array import BlcArray
path=find_library("blc")
lib = CDLL(name=path)
# Bind blc network methods
lib_path = find_library("blc")
lib = CDLL(lib_path)
class BlcArrayTCP4Server(BlcArray): class BlcArrayTCP4Server(BlcArray):
lib.blc_array_get_type.argtypes = [ c_void_p ]
lib.blc_array_get_type.restype = c_uint32
lib.blc_array_tcp4_server_new_void.restype = c_void_p lib.blc_array_tcp4_server_new_void.restype = c_void_p
lib.blc_array_tcp4_server_new_void.argtypes = [ c_char_p ] lib.blc_array_tcp4_server_new_void.argtypes = [ c_char_p ]
lib.blc_array_tcp4_server_new.restype = c_void_p lib.blc_array_tcp4_server_new.restype = c_void_p
...@@ -24,14 +25,14 @@ class BlcArrayTCP4Server(BlcArray): ...@@ -24,14 +25,14 @@ class BlcArrayTCP4Server(BlcArray):
if (dims): if (dims):
dim_types = [c_size_t] * len(dims) dim_types = [c_size_t] * len(dims)
lib.blc_array_tcp4_server_new.argtypes = [ c_char_p, c_uint32, c_uint32, c_int, *dim_types ] lib.blc_array_tcp4_server_new.argtypes = [ c_char_p, c_uint32, c_uint32, c_int, *dim_types ]
self.pointer = lib.blc_array_tcp4_server_new(port.encode(), int.from_bytes(data_type.encode(), "big"), int.from_bytes(format_type.encode(), "big"), len(dims), *dims ) type_int = int.from_bytes(data_type.encode(), "big")
format_int = int.from_bytes(format_type.encode(), "big")
self.pointer = lib.blc_array_tcp4_server_new(port.encode(), type_int, format_int, len(dims), *dims )
mtype=lib.blc_array_get_type(self.pointer)
else: else:
self.pointer = lib.blc_array_tcp4_server_new_void(port.encode()) self.pointer = lib.blc_array_tcp4_server_new_void(port.encode())
self.get_def() self.get_def()
print(self.data[:])
def send_data(self): def send_data(self):
lib.blc_array_tcp4_server_send_data(self.pointer) lib.blc_array_tcp4_server_send_data(self.pointer)
...@@ -93,7 +94,6 @@ class BlcArrayTCP4Client(BlcArray): ...@@ -93,7 +94,6 @@ class BlcArrayTCP4Client(BlcArray):
if __name__ == "__main__": if __name__ == "__main__":
import threading import threading
''' '''
This thread is only for example, it is supposed to be executed in another process ( the server ) This thread is only for example, it is supposed to be executed in another process ( the server )
''' '''
...@@ -101,10 +101,9 @@ if __name__ == "__main__": ...@@ -101,10 +101,9 @@ if __name__ == "__main__":
class ServerThread (threading.Thread): class ServerThread (threading.Thread):
def run(self): def run(self):
server = BlcArrayTCP4Server( "31440", 'UIN8', 'TEXT', [5]) server = BlcArrayTCP4Server( "31440", 'UIN8', 'TEXT', [5])
print("server data:", server.data[:]) print("server data before change:", server.data[:])
server.data[3]=7 #Change values to check if the data will be received server.data[3]=7 #Change values to check if the data will be received
print("server data:", server.data[:]) print("server data after change:", server.data[:])
print("Server has started, waiting for connection\n") print("Server has started, waiting for connection\n")
server.wait_connection() server.wait_connection()
print("Client connected") print("Client connected")
...@@ -115,11 +114,9 @@ if __name__ == "__main__": ...@@ -115,11 +114,9 @@ if __name__ == "__main__":
thread.start() thread.start()
'''Client part''' '''Client part'''
client = BlcArrayTCP4Client("localhost", "31440") client = BlcArrayTCP4Client("localhost", "31440")
print("type", client.type, "format", client.format, "length", len(client.data)) print("type", client.type, "format", client.format, "length", len(client.data))
print("Values before receiving the data") print("Values before receiving the data")
print(client.data[:]) print(client.data[:])
client.recv_data() client.recv_data()
......
# Set the minimum version of cmake required to build this project
cmake_minimum_required(VERSION 2.6)
set(channel_sources blc_channel.cpp channel_file.cpp)
...@@ -61,8 +61,8 @@ void blc_array::def_array(uint32_t type, uint32_t format, char const *dims_strin ...@@ -61,8 +61,8 @@ void blc_array::def_array(uint32_t type, uint32_t format, char const *dims_strin
} }
void blc_array::set_dims(uint32_t type, vector<size_t> const &lengths){ void blc_array::set_dims(uint32_t type, vector<size_t> const &lengths){
if (dims_nb>BLC_ARRAY_DIMS_MAX) throw length_error("too many dims max");
dims_nb=lengths.size(); dims_nb=lengths.size();
if (dims_nb>BLC_ARRAY_DIMS_MAX) throw length_error("too many dims. Max:" STRINGIFY(BLC_ARRAY_DIMS_MAX));
size=blc_get_type_size(type); size=blc_get_type_size(type);
size_t length; size_t length;
for (int i=0; i!=dims_nb; i++){ for (int i=0; i!=dims_nb; i++){
...@@ -73,29 +73,7 @@ void blc_array::set_dims(uint32_t type, vector<size_t> const &lengths){ ...@@ -73,29 +73,7 @@ void blc_array::set_dims(uint32_t type, vector<size_t> const &lengths){
} }
total_length=size/get_type_size(); total_length=size/get_type_size();
} }
/*
void blc_array::init(char const *properties){
sscan_properties(properties);
allocate();
}
void blc_array::vinit(uint32_t type, uint32_t format, int dims_nb, int length, va_list arguments){
vdef_array(type, format, dims_nb, length, arguments);
allocate();
}
void blc_array::init(uint32_t type, uint32_t format, int dims_nb, int length, ...){
va_list arguments;
va_start(arguments, length);
vinit(type, format, dims_nb, length, arguments);
va_end(arguments);
}
*/
void blc_array::add_dim(size_t length, size_t step){ void blc_array::add_dim(size_t length, size_t step){
assert(dims_nb<=BLC_ARRAY_DIMS_MAX); assert(dims_nb<=BLC_ARRAY_DIMS_MAX);
dims[dims_nb].length=length; dims[dims_nb].length=length;
...@@ -110,23 +88,6 @@ void blc_array::add_dim(size_t length){ ...@@ -110,23 +88,6 @@ void blc_array::add_dim(size_t length){
else add_dim(length, dims[dims_nb-1].length*dims[dims_nb-1].step); else add_dim(length, dims[dims_nb-1].length*dims[dims_nb-1].step);
} }
void blc_array::set_dims(int dims_nb, size_t length, ...){
blc_dim *dim;
va_list args;
this->dims_nb=dims_nb;
size=get_type_size();
va_start(args, length);
FOR_EACH(dim, dims, dims_nb)
{
size*=length;
dim->step=1;
dim->length=length;
length=va_arg(args, size_t);
}
va_end(args);
total_length=size/get_type_size();
}
int blc_array::get_type_size(){ int blc_array::get_type_size(){
return blc_get_type_size(type); return blc_get_type_size(type);
...@@ -556,88 +517,3 @@ void blc_array::save_tsv_file(char const *filename)const{ ...@@ -556,88 +517,3 @@ void blc_array::save_tsv_file(char const *filename)const{
void blc_array::fprint_surface_uchars(FILE *file, int ansi_terminal)const{ void blc_array::fprint_surface_uchars(FILE *file, int ansi_terminal)const{
blc_fprint_3Darray(file, this->uchars, this->size, 0, 1, 1, dims[0].step, dims[0].length, dims[1].step, dims[1].length, ansi_terminal); blc_fprint_3Darray(file, this->uchars, this->size, 0, 1, 1, dims[0].step, dims[0].length, dims[1].step, dims[1].length, ansi_terminal);
} }
/* C wrapper */
START_EXTERN_C
/** Useful for binding with python*/
blc_array *blc_array_new_void(){
return new blc_array();
}
blc_array *blc_array_new( uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
return new blc_array(type, format, lengths);
}
void blc_array_delete(blc_array *array){
delete array;
}
uint32_t blc_array_get_type(blc_array *array){
return array->type;
}
uint32_t blc_array_get_format(blc_array *array){
return array->format;
}
int blc_array_get_dims_nb(blc_array *array){
return array->dims_nb;
}
blc_dim *blc_array_get_dims(blc_array *array){
return array->dims;
}
int blc_array_get_total_length(blc_array *array){
return array->total_length;
}
void *blc_array_get_data(blc_array *array){
return array->data;
}
void blc_array_def(blc_array *array, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
array->def_array(type, format,lengths);
}
void blc_array_init(blc_array *array, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
new(array)blc_array(type, format, lengths);
}
// Envoie un message d'erreur avec name_of_file, name_of_function, number_of_line et affiche le message formate avec les parametres variables. Puis exit le programme avec le parametre EXIT_FAILURE. To be used with EXIT_ON_ERROR.
void blc_array_fatal_error(blc_array const *array, const char *name_of_file, const char* name_of_function, int numero_of_line, const char *message, ...){
va_list arguments;
va_start(arguments, message);
fprintf(stderr, "\n%s: %s \t %s \t %i :\nError: ", blc_program_name, name_of_file, name_of_function, numero_of_line);
color_vfprintf(BLC_BRIGHT_RED, stderr, message, arguments);
va_end(arguments);
array->fprint_debug(stderr);
fprintf(stderr, "\n\n");
fflush(stderr);
raise(SIGABRT);
exit(EXIT_FAILURE);
}
void blc_array_destroy(blc_array *array){
array->~blc_array();
}
END_EXTERN_C
/* Basic Library for C/C++ (blclib)
Copyright ETIS — ENSEA, Université de Cergy-Pontoise, CNRS (2011 - 2014)
Author: A. Blanchard
This software is a computer program whose purpose is to simulate neural networks and control robots or simulations.
This software is governed by the CeCILL v2.1 license under French law and abiding by the rules of distribution of free software.
You can use, modify and/ or redistribute the software under the terms of the CeCILL v2.1 license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license,
users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors have only limited liability.
In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge.
Users are therefore encouraged to load and test the software's suitability as regards their requirements in conditions enabling the security of their systems and/or data to be ensured
and, more generally, to use and operate it in the same conditions as regards security.
The fact that you are presently reading this means that you have had knowledge of the CeCILL v2.1 license and that you accept its terms. */
//
// Created by Arnaud Blanchard on 17/06/2014.
//
#include "blc_array.h"
#include "blc_text.h"
#include <cstdarg>
START_EXTERN_C
/** Useful for binding with python*/
blc_array *blc_array_new_void(){
return new blc_array();
}
blc_array *blc_array_new( uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
return new blc_array(type, format, lengths);
}
void blc_array_delete(blc_array *array){
delete array;
}
uint32_t blc_array_get_type(blc_array *array){
return array->type;
}
uint32_t blc_array_get_format(blc_array *array){
return array->format;
}
int blc_array_get_dims_nb(blc_array *array){
return array->dims_nb;
}
blc_dim *blc_array_get_dims(blc_array *array){
return array->dims;
}
int blc_array_get_total_length(blc_array *array){
return array->total_length;
}
void *blc_array_get_data(blc_array *array){
return array->data;
}
void blc_array_def(blc_array *array, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
array->def_array(type, format,lengths);
}
void blc_array_init(blc_array *array, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
new(array)blc_array(type, format, lengths);
}
// Envoie un message d'erreur avec name_of_file, name_of_function, number_of_line et affiche le message formate avec les parametres variables. Puis exit le programme avec le parametre EXIT_FAILURE. To be used with EXIT_ON_ERROR.
void blc_array_fatal_error(blc_array const *array, const char *name_of_file, const char* name_of_function, int numero_of_line, const char *message, ...){
va_list arguments;
va_start(arguments, message);
fprintf(stderr, "\n%s: %s \t %s \t %i :\nError: ", blc_program_name, name_of_file, name_of_function, numero_of_line);
color_vfprintf(BLC_BRIGHT_RED, stderr, message, arguments);
va_end(arguments);
array->fprint_debug(stderr);
fprintf(stderr, "\n\n");
fflush(stderr);
raise(SIGABRT);
exit(EXIT_FAILURE);
}
void blc_array_destroy(blc_array *array){
array->~blc_array();
}
END_EXTERN_C
#include "blc_array_network.h"
#include <unistd.h>
blc_array_network::~blc_array_network(){
SYSTEM_ERROR_CHECK(close(socket_fd), -1, nullptr);
}
...@@ -43,6 +43,11 @@ blc_array_tcp4_client::blc_array_tcp4_client(string const &address, string const ...@@ -43,6 +43,11 @@ blc_array_tcp4_client::blc_array_tcp4_client(string const &address, string const
allocate(); allocate();
} }
blc_array_tcp4_client::~blc_array_tcp4_client(){
SYSTEM_ERROR_CHECK(close(socket_fd), -1, nullptr);
}
void blc_array_tcp4_client::read_properties(){ void blc_array_tcp4_client::read_properties(){
ssize_t ret; ssize_t ret;
vector<char> properties(1024); vector<char> properties(1024);
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <unistd.h> #include <unistd.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <vector> #include <vector>
#include <cstdarg>
using namespace std; using namespace std;
...@@ -93,44 +92,7 @@ int blc_array_tcp4_server::send_data(){ ...@@ -93,44 +92,7 @@ int blc_array_tcp4_server::send_data(){
else return 0; else return 0;
} }
START_EXTERN_C blc_array_tcp4_server::~blc_array_tcp4_server(){
blc_array_tcp4_server *blc_array_tcp4_server_new_void(char const*port_name){ SYSTEM_ERROR_CHECK(close(socket_fd), -1, nullptr);
return new blc_array_tcp4_server(port_name);
} }
blc_array_tcp4_server *blc_array_tcp4_server_new(char const*port_name, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
return new blc_array_tcp4_server(port_name, type, format, lengths);
}
void blc_array_tcp4_server_recv_data(blc_array_tcp4_server *server){
server->recv_data();
}
void blc_array_tcp4_server_send_data(blc_array_tcp4_server *server){
server->send_data();
}
int blc_array_tcp4_server_wait_connection(blc_array_tcp4_server *server){
return server->wait_connection();
}
void blc_array_tcp4_server_delete(blc_array_tcp4_server *server){
delete server;
}
END_EXTERN_C
/*
blc_array_tcp4_server_thread::blc_array_tcp4_server_thread(blc_array *array, string const &port_name):blc_array_tcp4_server(array, port_name){
server_thread=make_unique<thread>([this](){
while(1) read_data();
});
}
*/
//
// blc_network.cpp
// network
//
// Created by Arnaud Blanchard on 30/05/2015.
//
#include "blc_network.h"
#include "blc_mem.h"
#include "blc_realtime.h"
#include <unistd.h>
#include <pthread.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string>
#include <stdarg.h>
//using namespace std;
static int blc_vset_iovec(struct iovec *iov, void *data, size_t size, va_list arguments){
int len;
for(len=0; data != nullptr; len++)
{
iov[len].iov_base = data;
iov[len].iov_len = size;
data = va_arg(arguments, void*);
size = va_arg(arguments, double);
}
return len;
}
int blc_set_iovec(struct iovec *iovec, void *data, size_t size, ...)
{
int len;
va_list arguments;
va_start(arguments, size);
len = blc_vset_iovec(iovec, data, size, arguments);
va_end(arguments);
return len;
}
void blc_set_msghdr(struct msghdr *msghdr, void *data, size_t size, ...)
{
va_list arguments;
va_start(arguments, size);
msghdr->msg_iovlen=blc_vset_iovec(msghdr->msg_iov, data, size, arguments);
va_end(arguments);
}
void blc_network::create_ip4_socket(const char* address_name, const char *port_name, int socket_type){
struct addrinfo hints, *results;
int ret;
CLEAR(hints);
hints.ai_flags = AI_NUMERICSERV; //We use only port number not service name ( faster )
hints.ai_family = PF_INET;
hints.ai_socktype = socket_type;
ret=getaddrinfo(address_name, port_name, &hints, &results);
if (ret !=0) EXIT_ON_ERROR(gai_strerror(ret));
if(results->ai_next != NULL) EXIT_ON_ERROR("There is more than one possible address. It is not yet implemented.");
memcpy(&remote_address, (void*)results->ai_addr, results->ai_addrlen);
remote_address_length=results->ai_addrlen;
SYSTEM_ERROR_CHECK(socket_fd = socket(results->ai_family, results->ai_socktype, results->ai_protocol), -1, NULL); //We suppose there is only one result in 'results'
freeaddrinfo(results);
}
void blc_network::allocate_system_size_buffer(){
size_t system_buffer_size=0;
socklen_t len=sizeof(system_buffer_size);
SYSTEM_ERROR_CHECK(getsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, &system_buffer_size, &len), -1, nullptr);
allocate(system_buffer_size); //No need to free
}
void blc_network::get_remote_address(char *channel_name, socklen_t name_size, char *port_name, socklen_t port_name_size) const{
int ret;
ret=getnameinfo((const struct sockaddr *)&remote_address, remote_address_length, channel_name, name_size, port_name, port_name_size, NI_NUMERICSERV);
if (ret !=0) EXIT_ON_ERROR(gai_strerror(ret)); //, 0, "setting address: %s", address_name));
}
void blc_network::recv_buffer_block(void *buffer, size_t buffer_size){
ssize_t ret;
SYSTEM_ERROR_CHECK(ret=recvfrom(socket_fd, buffer, buffer_size, MSG_TRUNC, (struct sockaddr*)&remote_address, &remote_address_length), -1, "Socket '%d', data: '%p', size: '%lu'", socket_fd, data, size);
if ((size_t)ret > buffer_size) EXIT_ON_ERROR("Buffer too small '%lu' bytes with a buffer of '%lu' bytes", ret, size);
received_size=ret;
}
void blc_network::recv_block(){
recv_buffer_block(data, size);
}
bool blc_network::recv_buffer_timeout(void *buffer, size_t buffer_size, uint64_t us_timeout){
fd_set fdset={{0}};
ssize_t ret;
struct timeval timeout;
div_t result;
FD_SET(socket_fd, &fdset);
result=div(us_timeout, 1000000);
timeout.tv_sec=result.quot;
timeout.tv_usec=result.rem;
SYSTEM_ERROR_CHECK(ret=select(socket_fd+1, &fdset, NULL, NULL, &timeout), -1, "Waiting server channel data"); //It would be nice to check errorfds
if (ret==0) return false;
else{
SYSTEM_ERROR_CHECK(ret=recvfrom(socket_fd, buffer, buffer_size, MSG_TRUNC, (struct sockaddr*)&remote_address, &remote_address_length), -1, "Socket '%d', data: '%p', size: '%lu'", socket_fd, data, size);
if ((size_t)ret > size) EXIT_ON_ERROR("Buffer too small '%lu' bytes with a buffer of '%lu' bytes", ret, size);
}
return true;
}
bool blc_network::recv_timeout(uint64_t us_timeout){
return recv_buffer_timeout(data, size, us_timeout );
}
void blc_network::send_buffer(void const* buffer, size_t buffer_size){
ssize_t ret;
size_t system_buffer_size=0;
socklen_t len=sizeof(system_buffer_size);
ret=sendto(socket_fd, buffer, buffer_size, NO_FLAG, (struct sockaddr*)&remote_address, remote_address_length);
if (ret==-1){
SYSTEM_ERROR_CHECK(getsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, &system_buffer_size, &len), -1, nullptr);
if (errno==EMSGSIZE) EXIT_ON_SYSTEM_ERROR("socket_fd '%d', request size '%u' SNDBUFFER '%d'", socket_fd, buffer_size, system_buffer_size );
}
else if ((size_t)ret!=buffer_size) EXIT_ON_ERROR("Only '%l' bytes sent instead of '%lu'", ret, size);
}
void blc_network::send(ssize_t send_size){
if (this->data==NULL) EXIT_ON_ERROR("You have not allocated buffer.");
if (send_size==-1) send_size=size; //By default we send all
if ((size_t)send_size > this->size) EXIT_ON_ERROR("You try to send more '%ld' than the buffer size '%lu'", send_size, size);
send_buffer(this->data, send_size);
}
blc_network::~blc_network(){
close(socket_fd);
}
//
// blc_server.cpp
// network
//
// Created by Arnaud Blanchard on November 2018.
//
#include "blc_network.h"
#include "blc_mem.h"
#include "blc_realtime.h"
#include <unistd.h>
#include <pthread.h>
#include <netdb.h>
#include <sys/types.h>
//
// blc_tcp4.cpp
// blc_network
//
// Created by Arnaud Blanchard on 09/10/2020.
//
#include "blc_network.h"
#include "blc_mem.h"
#include "blc_realtime.h"
#include "blc_tcp4.h"
#include <unistd.h>
#include <pthread.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/tcp.h>
#include <thread>
using namespace std;
blc_tcp4_client::blc_tcp4_client( string const &address_name, string const &port_name, ssize_t buffer_size){
if (buffer_size==-1) allocate_system_size_buffer();
else if (buffer_size!=0) allocate(buffer_size);
create_ip4_socket(address_name.c_str(), port_name.c_str(), SOCK_STREAM);
int flags =1;
SYSTEM_ERROR_CHECK(setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)), -1, nullptr); //Disable Naggle algorithm. Packet are send even if they are small
SYSTEM_ERROR_CHECK(connect(socket_fd, (const struct sockaddr *)&remote_address, remote_address_length), -1, nullptr);
}
void blc_tcp4_client::send_buffer(void const* buffer, size_t buffer_size){
ssize_t ret;
size_t system_buffer_size=0;
socklen_t len=sizeof(system_buffer_size);
ret=::send(socket_fd, buffer, buffer_size, NO_FLAG);
if (ret==-1){
SYSTEM_ERROR_CHECK(getsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, &system_buffer_size, &len), -1, nullptr);
if (errno==EMSGSIZE) EXIT_ON_SYSTEM_ERROR("socket_fd '%d', request size '%u' SNDBUFFER '%d'", socket_fd, buffer_size, system_buffer_size );
}
else if ((size_t)ret!=buffer_size) EXIT_ON_ERROR("Only '%l' bytes sent instead of '%lu'", ret, size);
}
void blc_tcp4_server::server_manager(){
ssize_t ret;
int client_socket_fd;
if (data==NULL) EXIT_ON_ERROR("You have not allocated the receive buffer");
SYSTEM_ERROR_CHECK(client_socket_fd = accept(socket_fd, (struct sockaddr *)&remote_address, &remote_address_length), -1, nullptr);
while(1) //Il faudrait stopper en fonction d'une interruption sur le read
{
received_size=0;
while(received_size<=minimal_read){ // Maybe need timeout
SYSTEM_ERROR_CHECK(ret = read(client_socket_fd, chars +received_size , size-received_size), -1, "Error receiving data. fd '%d' buffer size '%lu'", socket_fd, size);
received_size+=ret;
}
callback(this);
}
}
blc_tcp4_server::blc_tcp4_server(string const &port_name, void(*on_receive_data)(blc_tcp4_server*), void *arg, ssize_t buffer_size, uint64_t minimal_read):callback(on_receive_data), callback_arg(arg), minimal_read(minimal_read){
if (buffer_size==-1) allocate_system_size_buffer();
else if (buffer_size!=0) allocate(buffer_size);
create_ip4_socket(nullptr, port_name.c_str(), SOCK_STREAM);
SYSTEM_ERROR_CHECK(bind(socket_fd, (const struct sockaddr *)&remote_address, remote_address_length), -1, "Socket %d", socket_fd);
SYSTEM_ERROR_CHECK(listen(socket_fd, 1), -1, "socket_fd", socket_fd); //1 connection at a time for now
thread_ptr=make_unique<thread>(&blc_tcp4_server::server_manager, this);
}
#include "blc_array_tcp4_server.h"
#include <cstdarg>
START_EXTERN_C
blc_array_tcp4_server *blc_array_tcp4_server_new_void(char const *port_name){
return new blc_array_tcp4_server(port_name);
}
blc_array_tcp4_server *blc_array_tcp4_server_new(char const*port_name, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
va_list arguments;
vector<size_t> lengths(dims_nb, length0);
va_start(arguments, length0);
for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
va_end(arguments);
return new blc_array_tcp4_server(port_name, type, format, lengths);;
}
void blc_array_tcp4_server_recv_data(blc_array_tcp4_server *server){
server->recv_data();
}
void blc_array_tcp4_server_send_data(blc_array_tcp4_server *server){
server->send_data();
}
int blc_array_tcp4_server_wait_connection(blc_array_tcp4_server *server){
return server->wait_connection();
}
void blc_array_tcp4_server_delete(blc_array_tcp4_server *server){
delete server;
}
END_EXTERN_C
/*
blc_array_tcp4_server_thread::blc_array_tcp4_server_thread(blc_array *array, string const &port_name):blc_array_tcp4_server(array, port_name){
server_thread=make_unique<thread>([this](){
while(1) read_data();
});
}
*/
...@@ -5,5 +5,6 @@ project(t_array_tcp4_server) ...@@ -5,5 +5,6 @@ project(t_array_tcp4_server)
find_package(blc REQUIRED) find_package(blc REQUIRED)
add_executable(t_array_tcp4_server t_array_tcp4_server.cpp) add_executable(t_array_tcp4_server t_array_tcp4_server.cpp)
target_compile_options(t_array_tcp4_server PRIVATE -Wno-multichar)
target_compile_features(t_array_tcp4_server PRIVATE cxx_std_14) target_compile_features(t_array_tcp4_server PRIVATE cxx_std_14)
target_link_libraries(t_array_tcp4_server PRIVATE blc) target_link_libraries(t_array_tcp4_server PRIVATE blc)
...@@ -3,9 +3,16 @@ ...@@ -3,9 +3,16 @@
int main(int argc, char**argv){ int main(int argc, char**argv){
blc_array_tcp4_server server("31440", 'UIN8', 'TEXT', {1024}); blc_array_tcp4_server server("31440", 'UIN8', 'TEXT', {1024});
fprintf(stderr, "%d\n", blc_array_get_type(&server));
fprintf(stderr, "waiting client\n"); fprintf(stderr, "waiting client\n");
server.wait_connection(); server.wait_connection();
fprintf(stderr, "connected\n"); fprintf(stderr, "connected\n");
do { do {
server.recv_data(); server.recv_data();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment