페이지 선택

MXOS Socket APIs

mxos provides three socket-related APIs: TCP/UDP, TCP TLS/SLL, and TCP/IP communication.

 

§ MXCHIP MXOS API Site 참조한다.

⊕ mxos-demos SDK를 참조한다.

 

 

 

 

 

1. TCP/UDP communication

 

TCP/UDP Comm. API Description
socket Create a communication terminal
setsockopt Set socket option
getsockopt Get socket option
bind Bind a name to the socket
connect Initialize a socket connection
listen Listening for a socket connection
accept Accept a socket connection
select Monitor multiple file descriptors
send Send a message on a socket
write Send a message on the socket
sendto Send a message from the socket to the destination address
recv Receive a message from a socket
read Read a message from a socket
recvfrom Receive a message from a socket and get the source address
close Close a file descriptor
inet_addr Convert network host addresses, from IPv4 numbers and dot symbols, to network byte order binary data
inet_ntoa Convert the network host address to an IPv4 dotted decimal string according to the network byte order

 

 

 

 

2. TCP TLS/SSL communication

 

TCP TLS/SSL Comm. API Descriptiontion
ssl_set_cert Create a certificate and private key for an SSL server by being used by the SSL server
ssl_connect SSL client creates an SSL connection
ssl_accept SSL server accepts an SSL connection
ssl_send SSL sending data
ssl_recv SSL receiving data
ssl_close Turn off SSL and release resources

 

 

 

3. TCP/IP communication

 

TCP/IP Comm. API Description
gethostbyname Obtain an IP address from the host name
set_tcp_keepalive Set the TCP keep-alive mechanism parameters
get_tcp_keepalive Get TCP keep-alive mechanism parameters

 

 

 

 

4. Example

 

 

tcp_client.c

 

In this example, a TCP Client client is created.

After the network is successfully deployed, the specified TCP server is actively connected.

When the server sends string data, the client will return data to the TCP server.

 

#include "mxos.h"
#include "SocketUtils.h"

#define tcp_client_log(M, ...) custom_log("TCP", M, ##__VA_ARGS__)

static char tcp_remote_ip[16] = "192.168.3.53"; /*remote ip address*/
static int tcp_remote_port = 6000; /*remote port*/
static mxos_semaphore_t wait_sem = NULL;

static void mxosNotify_WifiStatusHandler( WiFiEvent status, void* const inContext )
{
    switch ( status )
    {
        case NOTIFY_STATION_UP:
            mxos_rtos_set_semaphore( &wait_sem );
            break;
        case NOTIFY_STATION_DOWN:
        case NOTIFY_AP_UP:
        case NOTIFY_AP_DOWN:
            break;
    }
}

/*when client connected wlan success,create socket*/
void tcp_client_thread( mxos_thread_arg_t arg )
{
    UNUSED_PARAMETER( arg );

    OSStatus err;
    struct sockaddr_in addr;
    struct timeval t;
    fd_set readfds;
    int tcp_fd = -1, len;
    char *buf = NULL;

    buf = (char*) malloc( 1024 );
    require_action( buf, exit, err = kNoMemoryErr );

    tcp_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    require_action( IsValidSocket( tcp_fd ), exit, err = kNoResourcesErr );

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr( tcp_remote_ip );
    addr.sin_port = htons(tcp_remote_port);

    tcp_client_log( "Connecting to server: ip=%s  port=%d!", tcp_remote_ip,tcp_remote_port );
    err = connect( tcp_fd, (struct sockaddr *)&addr, sizeof(addr) );
    require_noerr( err, exit );
    tcp_client_log( "Connect success!" );

    t.tv_sec = 2;
    t.tv_usec = 0;

    while ( 1 )
    {
        FD_ZERO( &readfds );
        FD_SET( tcp_fd, &readfds );

        require_action( select( tcp_fd + 1, &readfds, NULL, NULL, &t) >= 0, exit,
                        err = kConnectionErr );

        /* recv wlan data, and send back */
        if ( FD_ISSET( tcp_fd, &readfds ) )
        {
            len = recv( tcp_fd, buf, 1024, 0 );
            require_action( len >= 0, exit, err = kConnectionErr );

            if ( len == 0 )
            {
                tcp_client_log( "TCP Client is disconnected, fd: %d", tcp_fd );
                goto exit;
            }

            tcp_client_log("Client fd: %d, recv data %d", tcp_fd, len);
            len = send( tcp_fd, buf, len, 0 );
            tcp_client_log("Client fd: %d, send data %d", tcp_fd, len);
        }
    }

    exit:
    if ( err != kNoErr ) tcp_client_log( "TCP client thread exit with err: %d", err );
    if ( buf != NULL ) free( buf );
    SocketClose( &tcp_fd );
    mxos_rtos_delete_thread( NULL );
}

int application_start( void )
{
    OSStatus err = kNoErr;

    mxos_rtos_init_semaphore( &wait_sem, 1 );

    /*Register user function for mxos nitification: WiFi status changed */
    err = mxos_system_notify_register( mxos_notify_WIFI_STATUS_CHANGED,
                                       (void *) mxosNotify_WifiStatusHandler, NULL );
    require_noerr( err, exit );

    /* Start mxos system functions according to mxos_config.h */
    err = mxos_system_init( mxos_system_context_init( 0 ) );
    require_noerr( err, exit );

    /* Wait for wlan connection*/
    mxos_rtos_get_semaphore( &wait_sem, mxos_WAIT_FOREVER );
    tcp_client_log( "wifi connected successful" );

    /* Start TCP client thread */
    err = mxos_rtos_create_thread( NULL, mxos_APPLICATION_PRIORITY, "TCP_client", tcp_client_thread, 0x800, 0 );
    require_noerr_string( err, exit, "ERROR: Unable to start the tcp client thread." );

    exit:
    if ( wait_sem != NULL )
        mxos_rtos_deinit_semaphore( &wait_sem );
    mxos_rtos_delete_thread( NULL );
    return err;
}

 

 

 

tcp_server.c

 

In this example, a TCP server is created to wait for a TCP client connection.

When the client sends a character to the server, the TCP server returns the received character to the TCP client.

 

#include "mxos.h"
#include "SocketUtils.h"

#define tcp_server_log(M, ...) custom_log("TCP", M, ##__VA_ARGS__)

#define SERVER_PORT 20000 /*set up a tcp server,port at 20000*/

void mxosNotify_WifiStatusHandler( WiFiEvent event, void* const inContext )
{
    IPStatusTypedef para;
    switch ( event )
    {
        case NOTIFY_STATION_UP:
            mxosWlanGetIPStatus( &para, Station );
            tcp_server_log("Server established at ip: %s port: %d",para.ip, SERVER_PORT);
            break;
        case NOTIFY_STATION_DOWN:
            case NOTIFY_AP_UP:
            case NOTIFY_AP_DOWN:
            break;
    }
}

void tcp_client_thread( mxos_thread_arg_t arg )
{
    OSStatus err = kNoErr;
    int fd = (int) arg;
    int len = 0;
    fd_set readfds;
    char *buf = NULL;
    struct timeval t;

    buf = (char*) malloc( 1024 );
    require_action( buf, exit, err = kNoMemoryErr );

    t.tv_sec = 5;
    t.tv_usec = 0;

    while ( 1 )
    {
        FD_ZERO( &readfds );
        FD_SET( fd, &readfds );

        require_action( select( fd+1, &readfds, NULL, NULL, &t) >= 0, exit, err = kConnectionErr );

        if ( FD_ISSET( fd, &readfds ) ) /*one client has data*/
        {
            len = recv( fd, buf, 1024, 0 );
            require_action( len >= 0, exit, err = kConnectionErr );

            if ( len == 0 )
            {
                tcp_server_log( "TCP Client is disconnected, fd: %d", fd );
                goto exit;
            }

            tcp_server_log("fd: %d, recv data %d from client", fd, len);
            len = send( fd, buf, len, 0 );
            tcp_server_log("fd: %d, send data %d to client", fd, len);
        }
    }
    exit:
    if ( err != kNoErr ) tcp_server_log( "TCP client thread exit with err: %d", err );
    if ( buf != NULL ) free( buf );
    SocketClose( &fd );
    mxos_rtos_delete_thread( NULL );
}

/* TCP server listener thread */
void tcp_server_thread( mxos_thread_arg_t arg )
{
    UNUSED_PARAMETER( arg );
    OSStatus err = kNoErr;
    struct sockaddr_in server_addr, client_addr;
    socklen_t sockaddr_t_size = sizeof(client_addr);
    char client_ip_str[16];
    int tcp_listen_fd = -1, client_fd = -1;
    fd_set readfds;

    tcp_listen_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    require_action( IsValidSocket( tcp_listen_fd ), exit, err = kNoResourcesErr );

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;/* Accept conenction request on all network interface */
    server_addr.sin_port = htons( SERVER_PORT );/* Server listen on port: 20000 */

    err = bind( tcp_listen_fd, (struct sockaddr *) &server_addr, sizeof(server_addr) );
    require_noerr( err, exit );

    err = listen( tcp_listen_fd, 0 );
    require_noerr( err, exit );

    while ( 1 )
    {
        FD_ZERO( &readfds );
        FD_SET( tcp_listen_fd, &readfds );

        require( select( tcp_listen_fd + 1, &readfds, NULL, NULL, NULL) >= 0, exit );

        if ( FD_ISSET( tcp_listen_fd, &readfds ) )
        {
            client_fd = accept( tcp_listen_fd, (struct sockaddr *) &client_addr, &sockaddr_t_size );
            if ( IsValidSocket( client_fd ) )
            {
//                inet_ntoa( client_ip_str, client_addr.s_ip );
                strcpy( client_ip_str, inet_ntoa( client_addr.sin_addr ) );
                tcp_server_log( "TCP Client %s:%d connected, fd: %d", client_ip_str, client_addr.sin_port, client_fd );
                if ( kNoErr
                     != mxos_rtos_create_thread( NULL, mxos_APPLICATION_PRIORITY, "TCP Clients",
                                                 tcp_client_thread,
                                                 0x800, client_fd ) )
                    SocketClose( &client_fd );
            }
        }
    }
    exit:
    if ( err != kNoErr ) tcp_server_log( "Server listerner thread exit with err: %d", err );
    SocketClose( &tcp_listen_fd );
    mxos_rtos_delete_thread( NULL );
}

int application_start( void )
{
    OSStatus err = kNoErr;

    /*Register user function for mxos nitification: WiFi status changed */
    err = mxos_system_notify_register( mxos_notify_WIFI_STATUS_CHANGED,
                                       (void *) mxosNotify_WifiStatusHandler,
                                       NULL );
    require_noerr( err, exit );

    /* Start mxos system functions according to mxos_config.h */
    err = mxos_system_init( mxos_system_context_init( 0 ) );
    require_noerr( err, exit );

    /* Start TCP server listener thread*/
    err = mxos_rtos_create_thread( NULL, mxos_APPLICATION_PRIORITY, "TCP_server", tcp_server_thread,
                                   0x800,
                                   0 );
    require_noerr_string( err, exit, "ERROR: Unable to start the tcp server thread." );

    exit:
    mxos_rtos_delete_thread( NULL );
    return err;
}

 

 

 

udp_broadcast.c

 

This example is implemented by starting the UDP broadcast service

and communicating with the same port number of the host with a different IP address under the same gateway.

 

#include "mxos.h"

#define udp_broadcast_log(M, ...) custom_log("UDP", M, ##__VA_ARGS__)

#define LOCAL_UDP_PORT 20000
#define REMOTE_UDP_PORT 20001

char* data = "UDP broadcast data";

/*create udp socket*/
void udp_broadcast_thread( mxos_thread_arg_t arg )
{
    UNUSED_PARAMETER( arg );

    OSStatus err;
    struct sockaddr_in addr;
    int udp_fd = -1;

    /*Establish a UDP port to receive any data sent to this port*/
    udp_fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
    require_action( IsValidSocket( udp_fd ), exit, err = kNoResourcesErr );

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons( LOCAL_UDP_PORT );

    err = bind( udp_fd, (struct sockaddr *) &addr, sizeof(addr) );
    require_noerr( err, exit );

    udp_broadcast_log("Start UDP broadcast mode, local port: %d, remote port: %d", LOCAL_UDP_PORT, REMOTE_UDP_PORT);

    while ( 1 )
    {
        udp_broadcast_log( "broadcast now!" );

        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = INADDR_BROADCAST;
        addr.sin_port = htons( REMOTE_UDP_PORT );
        /*the receiver should bind at port=20000*/
        sendto( udp_fd, data, strlen( data ), 0, (struct sockaddr *) &addr, sizeof(addr) );

        mxos_thread_sleep( 2 );
    }

    exit:
    if ( err != kNoErr )
        udp_broadcast_log("UDP thread exit with err: %d", err);
    mxos_rtos_delete_thread( NULL );
}

int application_start( void )
{
    OSStatus err = kNoErr;

    /* Start mxos system functions according to mxos_config.h */
    err = mxos_system_init( mxos_system_context_init( 0 ) );
    require_noerr( err, exit );

    err = mxos_rtos_create_thread( NULL, mxos_APPLICATION_PRIORITY, "udp_broadcast", udp_broadcast_thread, 0x800, 0 );
    require_noerr_string( err, exit, "ERROR: Unable to start the UDP thread." );

    exit:
    if ( err != kNoErr )
        udp_broadcast_log("Thread exit with err: %d", err);
    mxos_rtos_delete_thread( NULL );
    return err;
}

 

 

 

udp_unicast.c

 

This example implementation starts the udp unicast service and communicates data with the host port number of the specified IP address.

 

#include "mxos.h"

#define udp_unicast_log(M, ...) custom_log("UDP", M, ##__VA_ARGS__)

#define LOCAL_UDP_PORT 20000

void mxosNotify_WifiStatusHandler( WiFiEvent event, void* const inContext )
{
    IPStatusTypedef para;
    switch ( event )
    {
        case NOTIFY_STATION_UP:
            mxosWlanGetIPStatus( &para, Station );
            udp_unicast_log( "Wlan connected, Local ip address: %s", para.ip );
            break;
        case NOTIFY_STATION_DOWN:
        case NOTIFY_AP_UP:
        case NOTIFY_AP_DOWN:
            break;
    }
}

/*create udp socket*/
void udp_unicast_thread( void *arg )
{
    UNUSED_PARAMETER( arg );

    OSStatus err;
    struct sockaddr_in addr;
    fd_set readfds;
    socklen_t addrLen = sizeof(addr);
    int udp_fd = -1, len;
    char ip_address[16];
    uint8_t *buf = NULL;

    buf = malloc( 1024 );
    require_action( buf, exit, err = kNoMemoryErr );

    /*Establish a UDP port to receive any data sent to this port*/
    udp_fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
    require_action( IsValidSocket( udp_fd ), exit, err = kNoResourcesErr );

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(LOCAL_UDP_PORT);
    err = bind( udp_fd, (struct sockaddr *)&addr, sizeof(addr) );
    require_noerr( err, exit );

    udp_unicast_log("Open local UDP port %d", LOCAL_UDP_PORT);

    while ( 1 )
    {
        FD_ZERO( &readfds );
        FD_SET( udp_fd, &readfds );

        require_action( select(udp_fd + 1, &readfds, NULL, NULL, NULL) >= 0, exit,
                        err = kConnectionErr );

        /*Read data from udp and send data back */
        if ( FD_ISSET( udp_fd, &readfds ) )
        {
            len = recvfrom( udp_fd, buf, 1024, 0, (struct sockaddr *)&addr, &addrLen );
            require_action( len >= 0, exit, err = kConnectionErr );

            strcpy(ip_address, inet_ntoa(addr.sin_addr));
            udp_unicast_log( "udp recv from %s:%d, len:%d", ip_address,addr.sin_port, len );
            sendto( udp_fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in) );
        }
    }

    exit:
    if ( err != kNoErr )
        udp_unicast_log("UDP thread exit with err: %d", err);
    if ( buf != NULL ) free( buf );
    mxos_rtos_delete_thread( NULL );
}

int application_start( void )
{
    OSStatus err = kNoErr;

    /*Register user function for mxos nitification: WiFi status changed */
    err = mxos_system_notify_register( mxos_notify_WIFI_STATUS_CHANGED,
                                       (void *) mxosNotify_WifiStatusHandler, NULL );
    require_noerr( err, exit );

    /* Start mxos system functions according to mxos_config.h */
    err = mxos_system_init( mxos_system_context_init( 0 ) );
    require_noerr( err, exit );

    err = mxos_rtos_create_thread( NULL, mxos_APPLICATION_PRIORITY, "udp_unicast",
                                   (mxos_thread_function_t)udp_unicast_thread, 0x800, 0 );
    require_noerr_string( err, exit, "ERROR: Unable to start the UDP thread." );

    exit:
    if ( err != kNoErr )
        udp_unicast_log("Thread exit with err: %d", err);
    mxos_rtos_delete_thread( NULL );
    return err;
}

 

 

 

이상 끝 ~~~

 

 

 

 

 

 

Viewed Page List