Coldforce ist eine in C geschriebene Bibliothek, die verschiedene Netzwerkprotokolle unterstützt. Mit der asynchronen API dieser Bibliothek können Sie problemlos ereignisgesteuerte Netzwerkanwendungen entwickeln. Die derzeit unterstützten Protokolle sind wie folgt. Alle unterstützen Clients und Server (Multi-Client, C10K).
C99 oder höher
Verwenden Sie -pthread
-lm
OpenSSL oder wolfSSL (nur bei Verwendung von TLS, https und wss)
wolfSSL-Build-Optionen
IDE
#define OPENSSL_EXTRA
#define OPENSSL_ALL
#define HAVE_ALPN
#define HAVE_SNI
#define WOLFSSL_SYS_CA_CERTS
#define WOLFSSL_DTLS
#define WOLFSSL_DTLS13
mkdir inc/wolfssl
copy your user_settings.h to inc/wolfssl/.
configure
--enable-opensslextra --enable-opensslall --enable-alpn --enable-sni --enable-sys-ca-certs --enable-dtls --enable-dtls13
co_core.dll
/ libco_core.a
co_net.dll
/ libco_net.a
co_tls.dll
/ libco_tls.a
co_http.dll
/ libco_http.a
co_http2.dll
/ libco_http2.a
co_ws.dll
, co_ws_http2.dll
/ libco_ws.a
, libco_ws_http2.a
Windows Visual Studio (prj/msvc/coldforce.sln)
für wolfSSL Fügen Sie CO_USE_WOLFSSL
zu C/C++ Preprocessor Definitions
sowohl in co_tls als auch in Ihrer Projekteigenschaft hinzu.
Linux cmake
cd build
cmake ..
make
für wolfSSL
...
cmake .. -DTLS_LIB=wolfssl
...
macOS cmake (auf die gleiche Weise wie Linux)
WebSocket-Client
# include < coldforce.h >
# include < stdio.h >
# include < stdlib.h >
# include < string.h >
typedef struct {
co_app_t base_app;
co_ws_client_t * ws_client;
co_url_st* url;
} app_st;
void
app_on_ws_receive_frame (
app_st* self,
co_ws_client_t * ws_client,
const co_ws_frame_t * frame,
int error_code
)
{
if (error_code == 0 )
{
bool fin = co_ws_frame_get_fin (frame);
uint8_t opcode = co_ws_frame_get_opcode (frame);
size_t data_size = ( size_t ) co_ws_frame_get_payload_size (frame);
const uint8_t * data = co_ws_frame_get_payload_data (frame);
switch (opcode)
{
case CO_WS_OPCODE_TEXT:
{
printf ( " receive text(%d): %*.*s n " , fin,
( int )data_size, ( int )data_size, ( char *)data);
break ;
}
case CO_WS_OPCODE_BINARY:
{
printf ( " receive binary(%d): %zu bytes n " ,
fin, data_size);
break ;
}
case CO_WS_OPCODE_CONTINUATION:
{
printf ( " receive continuation(%d): %zu bytes n " ,
fin, data_size);
break ;
}
default :
{
co_ws_default_handler (ws_client, frame);
break ;
}
}
}
else
{
co_ws_client_destroy (ws_client);
self-> ws_client = NULL ;
}
}
void
app_on_ws_close (
app_st* self,
co_ws_client_t * ws_client
)
{
co_ws_client_destroy (ws_client);
self-> ws_client = NULL ;
co_app_stop ();
}
void
app_on_ws_upgrade (
app_st* self,
co_ws_client_t * ws_client,
const co_http_response_t * response,
int error_code
)
{
if (error_code == 0 )
{
co_ws_send_text (ws_client, " hello " );
}
else
{
co_ws_client_destroy (ws_client);
self-> ws_client = NULL ;
co_app_stop ();
}
}
void
app_on_ws_connect (
app_st* self,
co_ws_client_t * ws_client,
int error_code
)
{
if (error_code == 0 )
{
co_http_request_t * request =
co_http_request_create_ws_upgrade (self-> url -> path_and_query , NULL , NULL );
co_ws_send_upgrade_request (self-> ws_client , request);
}
else
{
co_ws_client_destroy (ws_client);
self-> ws_client = NULL ;
co_app_stop ();
}
}
bool
app_on_create (
app_st* self
)
{
self-> url = co_url_create ( " ws://127.0.0.1:8080/ " );
co_net_addr_t local_net_addr = { 0 };
co_net_addr_set_family (&local_net_addr, CO_NET_ADDR_FAMILY_IPV4);
self-> ws_client = co_ws_client_create (self-> url -> origin , &local_net_addr, NULL );
if (self-> ws_client == NULL )
{
return false ;
}
co_ws_callbacks_st* callbacks = co_ws_get_callbacks (self-> ws_client );
callbacks-> on_connect = (co_ws_connect_fn)app_on_ws_connect;
callbacks-> on_upgrade = (co_ws_upgrade_fn)app_on_ws_upgrade;
callbacks-> on_receive_frame = (co_ws_receive_frame_fn)app_on_ws_receive_frame;
callbacks-> on_close = (co_ws_close_fn)app_on_ws_close;
co_ws_start_connect (self-> ws_client );
return true ;
}
void
app_on_destroy (
app_st* self
)
{
co_ws_client_destroy (self-> ws_client );
co_url_destroy (self-> url );
}
int
main (
int argc,
char * argv[]
)
{
app_st self = { 0 };
return co_net_app_start (
( co_app_t *)&self, " ws-client-app " ,
(co_app_create_fn)app_on_create,
(co_app_destroy_fn)app_on_destroy,
argc, argv);
}
WebSocket-Echoserver -> ws://127.0.0.1:8080
# include < coldforce.h >
typedef struct {
co_app_t base_app;
co_tcp_server_t * tcp_server;
co_list_t * ws_clients;
} app_st;
void
app_on_ws_receive_frame (
app_st* self,
co_ws_client_t * ws_client,
const co_ws_frame_t * frame,
int error_code
)
{
if (error_code == 0 )
{
bool fin = co_ws_frame_get_fin (frame);
uint8_t opcode = co_ws_frame_get_opcode (frame);
size_t data_size = ( size_t ) co_ws_frame_get_payload_size (frame);
const uint8_t * data = co_ws_frame_get_payload_data (frame);
switch (opcode)
{
case CO_WS_OPCODE_TEXT:
case CO_WS_OPCODE_BINARY:
case CO_WS_OPCODE_CONTINUATION:
{
co_ws_send (ws_client, fin, opcode, data, data_size);
break ;
}
default :
{
co_ws_default_handler (ws_client, frame);
break ;
}
}
}
else
{
co_list_remove (self-> ws_clients , ws_client);
}
}
void
app_on_ws_close (
app_st* self,
co_ws_client_t * ws_client
)
{
co_list_remove (self-> ws_clients , ws_client);
}
void
app_on_ws_upgrade (
app_st* self,
co_ws_client_t * ws_client,
const co_http_request_t * http_request,
int error_code
)
{
if (error_code == 0 )
{
co_http_response_t * http_response =
co_http_response_create_ws_upgrade (http_request, NULL , NULL );
co_http_connection_send_response (
( co_http_connection_t *)ws_client, http_response);
co_http_response_destroy (http_response);
}
else
{
co_list_remove (self-> ws_clients , ws_client);
}
}
void
app_on_tcp_accept (
app_st* self,
co_tcp_server_t * tcp_server,
co_tcp_client_t * tcp_client
)
{
co_tcp_accept (( co_thread_t *)self, tcp_client);
co_ws_client_t * ws_client = co_tcp_upgrade_to_ws (tcp_client, NULL );
co_ws_callbacks_st* callbacks = co_ws_get_callbacks (ws_client);
callbacks-> on_upgrade = (co_ws_upgrade_fn)app_on_ws_upgrade;
callbacks-> on_receive_frame = (co_ws_receive_frame_fn)app_on_ws_receive_frame;
callbacks-> on_close = (co_ws_close_fn)app_on_ws_close;
co_list_add_tail (self-> ws_clients , ws_client);
}
bool
app_on_create (
app_st* self
)
{
uint16_t port = 8080 ;
co_list_ctx_st list_ctx = { 0 };
list_ctx. destroy_value = (co_item_destroy_fn)co_ws_client_destroy;
self-> ws_clients = co_list_create (&list_ctx);
co_net_addr_t local_net_addr = { 0 };
co_net_addr_set_family (&local_net_addr, CO_NET_ADDR_FAMILY_IPV4);
co_net_addr_set_port (&local_net_addr, port);
self-> tcp_server = co_tcp_server_create (&local_net_addr);
co_socket_option_set_reuse_addr (
co_tcp_server_get_socket (self-> tcp_server ), true );
co_tcp_server_callbacks_st* callbacks =
co_tcp_server_get_callbacks (self-> tcp_server );
callbacks-> on_accept = (co_tcp_accept_fn)app_on_tcp_accept;
return co_tcp_server_start (self-> tcp_server , SOMAXCONN);
}
void
app_on_destroy (
app_st* self
)
{
co_tcp_server_destroy (self-> tcp_server );
co_list_destroy (self-> ws_clients );
}
int
main (
int argc,
char * argv[]
)
{
app_st self = { 0 };
return co_net_app_start (
( co_app_t *)&self, " ws-server-app " ,
(co_app_create_fn)app_on_create,
(co_app_destroy_fn)app_on_destroy,
argc, argv);
}
weitere Beispiele hier