wss

2022/7/1 6:49:29

本文主要是介绍wss,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

最重要的是,windows的路径问题

 

/*
 * libwebsockets-test-client - libwebsockets test implementation
 *
 * Copyright (C) 2011-2017 Andy Green <andy@warmcat.com>
 *
 * This file is made available under the Creative Commons CC0 1.0
 * Universal Public Domain Dedication.
 *
 * The person who associated a work with this deed has dedicated
 * the work to the public domain by waiving all of his or her rights
 * to the work worldwide under copyright law, including all related
 * and neighboring rights, to the extent allowed by law. You can copy,
 * modify, distribute and perform the work, even for commercial purposes,
 * all without asking permission.
 *
 * The test apps are intended to be adapted for use in your code, which
 * may be proprietary.  So unlike the library itself, they are licensed
 * Public Domain.
 */

#include "lws_config.h"

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <signal.h>

#ifdef _WIN32
#define random rand
#include "gettimeofday.h"
#else
#include <syslog.h>
#include <sys/time.h>
#include <unistd.h>
#endif

#include <libwebsockets.h>

struct lws_poly_gen {
    uint32_t cyc[2];
};

#define block_size (3 * 4096)

static int deny_deflate, longlived, mirror_lifetime, test_post, once;
static struct lws *wsi_dumb, *wsi_mirror;
static struct lws *wsi_multi[3];
static volatile int force_exit;
static unsigned int opts, rl_multi[3];
static int flag_no_mirror_traffic, justmirror, flag_echo;
static uint32_t count_blocks = 1024, txb, rxb, rx_count, errs;
static struct lws_poly_gen tx = { { 0xabcde, 0x23456789 } },
               rx = { { 0xabcde, 0x23456789 } }
;

#if defined(LWS_WITH_TLS) && defined(LWS_HAVE_SSL_CTX_set1_param)
char crl_path[1024] = "";
#endif

/*
 * This demo shows how to connect multiple websockets simultaneously to a
 * websocket server (there is no restriction on their having to be the same
 * server just it simplifies the demo).
 *
 *  dumb-increment-protocol:  we connect to the server and print the number
 *                we are given
 *
 *  lws-mirror-protocol: draws random circles, which are mirrored on to every
 *                client (see them being drawn in every browser
 *                session also using the test server)
 */

enum demo_protocols {

    PROTOCOL_DUMB_INCREMENT,
    PROTOCOL_LWS_MIRROR,

    /* always last */
    DEMO_PROTOCOL_COUNT
};

static uint8_t
lws_poly_rand(struct lws_poly_gen *p)
{
    p->cyc[0] = (p->cyc[0] & 1) ? (p->cyc[0] >> 1) ^ 0xb4bcd35c :
                      p->cyc[0] >> 1;
    p->cyc[0] = (p->cyc[0] & 1) ? (p->cyc[0] >> 1) ^ 0xb4bcd35c :
                      p->cyc[0] >> 1;
    p->cyc[1] = (p->cyc[1] & 1) ? (p->cyc[1] >> 1) ^ 0x7a5bc2e3 :
                      p->cyc[1] >> 1;

    return p->cyc[0] ^ p->cyc[1];
}

/*
static void show_http_content(const char *p, size_t l)
{
    if (lwsl_visible(LLL_INFO)) {
        while (l--)
            if (*p < 0x7f)
                putchar(*p++);
            else
                putchar('.');
    }
}
*/

/*
 * dumb_increment protocol
 *
 * since this also happens to be protocols[0], some callbacks that are not
 * bound to a specific protocol also turn up here.
 */



/* lws-mirror_protocol */

int gCount = 0;

static int
callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
            void *user, void *in, size_t len)
{
    unsigned char buf[LWS_PRE + block_size], *p;
    unsigned int rands[4];
    int l = 0;
    int n;

    switch (reason) {
    case LWS_CALLBACK_CLIENT_ESTABLISHED:

        lwsl_notice("mirror: LWS_CALLBACK_CLIENT_ESTABLISHED\n");

        if (flag_echo) {
            rxb = txb = 0;
            rx.cyc[0] = tx.cyc[0] = 0xabcde;
            rx.cyc[1] = tx.cyc[1] = 0x23456789;

            lws_callback_on_writable(wsi);

            break;
        }

        lws_get_random(lws_get_context(wsi), rands, sizeof(rands[0]));
        mirror_lifetime = 16384 + (rands[0] & 65535);
        /* useful to test single connection stability */
        if (longlived)
            mirror_lifetime += 500000;

        lwsl_notice("opened mirror connection with "
              "%d lifetime\n", mirror_lifetime);

        /*
         * mirror_lifetime is decremented each send, when it reaches
         * zero the connection is closed in the send callback.
         * When the close callback comes, wsi_mirror is set to NULL
         * so a new connection will be opened
         *
         * start the ball rolling,
         * LWS_CALLBACK_CLIENT_WRITEABLE will come next service
         */
        if (!flag_no_mirror_traffic)
            lws_callback_on_writable(wsi);
        break;

    case LWS_CALLBACK_CLIENT_CLOSED:
        lwsl_notice("mirror: LWS_CALLBACK_CLOSED mirror_lifetime=%d, "
                "rxb %d, rx_count %d\n", mirror_lifetime, rxb,
                rx_count);
        wsi_mirror = NULL;
        if (flag_echo || once)
            force_exit = 1;
        break;

    case LWS_CALLBACK_CLIENT_WRITEABLE:
        lwsl_user("LWS_CALLBACK_CLIENT_WRITEABLE\n");
        if (flag_no_mirror_traffic)
            return 0;
/*
        if (flag_echo) {
            for (n = 0; n < (int)block_size; n++)
                buf[LWS_PRE + n] = lws_poly_rand(&tx);

            n = lws_write(wsi, &buf[LWS_PRE], block_size,
                      opts | LWS_WRITE_TEXT);
            if (n < 0) {
                lwsl_err("Error sending\n");
                return -1;
            }

            txb++;
            if (txb != count_blocks)
                lws_callback_on_writable(wsi);
            else {
                lwsl_notice("send completed: %d x %d\n",
                        count_blocks, block_size);
            }
            break;
        }

        for (n = 0; n < 1; n++) {
            lws_get_random(lws_get_context(wsi), rands,
                       sizeof(rands));
            l += sprintf((char *)&buf[LWS_PRE + l],
                    "c #%06X %u %u %u;",
                    rands[0] & 0xffffff,    
                    rands[1] & 511,    
                    rands[2] & 255,        
                    (rands[3] & 31) + 1);    
        }
*/
        char str[1024] ={0};
        //strcpy(str,"{\"jsonrpc\" : \"2.0\",\"id\" : \"327\",\"method\" : \"Init\",\"params\" : {\"protocolVersion\" : \"1.0\",\"mac\" : \"8c:68:c8:d4:30:b8\",");
        //strcat(str,"\"version\" : \"V2.0.1T1\",\"boot\": \"V2.0.1T1\",\"configuration\": \"V2.0.1T1\",\"type\" : \"E8820V2-SHDX\",");
        //strcat(str,"\"serialNumber\" : \"HN51N6KHBA02378\",\"odm\":\"1\",\"areaCode\":\"\"}}");
        strcpy(str,"{\"params\": {\"configuration\": \"V1.0.0.0B5-0000\", \"type\": \"ZXHN E3630-0000\", \"version\": \"V1.0.0.2B4.0000_O\", \"protocolVersion\": \"1.0\", \"reversion\": \"V1.0.0.2B4.0000\", \"odm\": \"5\", \"mac\": \"e0:19:54:7f:ff:91\", \"serialNumber\": \"HN5EN84KAC00056\", \"areaCode\": \"\"}, \"jsonrpc\": \"2.0\", \"id\": \"2\", \"method\": \"Init\"}");
        //strcpy(str,"{\"params\": {\"configuration\": \"V1.0.0.0B5-0000\", \"type\": \"ZXHN E3630-0000\", \"version\": \"V1.0.0.2B4.0000_O\", \"protocolVersion\": \"1.0\", \"reversion\": \"V1.0.0.2B4.0000\", \"odm\": \"5\", \"mac\": \"e0:19:54:7f:ff:91\", \"serialNumber\": \"HN5EN84KAC00056\", \"areaCode\": \"\"}, \"jsonrpc\": \"2.0\", \"id\": \"2\", \"method\": \"SearchAll\"}");
        //strcpy(str,"{\"params\": {\"type\": \"ZXHN E3630-0000\",\"version\": \"V1.0.0.2B6.0000\",},\"jsonrpc\": \"2.0\",\"id\": \"2\",\"method\": \"PullUpgrade\"}");
        printf(" ---%s--- \n",str);

        if(gCount++ > 3){
            break;
        }

        strcpy((char*)&buf[LWS_PRE],str);

        n = lws_write(wsi, &buf[LWS_PRE], (unsigned int)strlen(str),
                  opts | LWS_WRITE_TEXT);
        if (n < 0)
            return -1;
        if (n < l) {
            lwsl_err("Partial write LWS_CALLBACK_CLIENT_WRITEABLE\n");
            return -1;
        }
        if (!justmirror)
            mirror_lifetime--;
        if (!mirror_lifetime) {
            lwsl_notice("closing mirror session\n");
            return -1;
        }
        /* get notified as soon as we can write again */
        lws_callback_on_writable(wsi);

#if !defined(_WIN32) && !defined(WIN32)
        usleep(50);
#endif
        break;

    case LWS_CALLBACK_CLIENT_RECEIVE:
        printf("---LWS_CALLBACK_CLIENT_RECEIVE----%s---%ld-->\n",(char*)in,len);
        if (flag_echo) {
            p = (unsigned char *)in;
            for (n = 0; n < (int)len; n++)
                if (*p++ != lws_poly_rand(&rx)) {
                    lwsl_err("mismatch at rxb %d offset %d\n", rxb + (n / block_size), n % block_size);
                    errs++;
                    force_exit = 1;
                    return -1;
                }
            rx_count += (unsigned int)(unsigned long long)len;
            while (rx_count >= block_size) {
                rx_count -= block_size;
                rxb++;
            }
            if (rx_count == 0 && rxb == count_blocks) {
                lwsl_notice("Everything received: errs %d\n",
                        errs);
                force_exit = 1;
                return -1;
            }
        }
        break;
    default:
        break;
    }

    return 0;
}
//wss://appstore-gw.ztehome.com.cn:443/tunnel?mac=a8:74:84:e8:3b:94&sn=HN5YN81M7616415&type=ZXHN%20E1600-1000A&version=V1.0.0.2B1.1000&reversion=V1.1.0.5B4.1000

/*
static int
callback_test_raw_client(struct lws *wsi, enum lws_callback_reasons reason,
             void *user, void *in, size_t len)
{
    switch (reason) {
    case LWS_CALLBACK_RAW_ADOPT:
        lwsl_notice("LWS_CALLBACK_RAW_ADOPT\n");
        break;

    case LWS_CALLBACK_RAW_RX:
        lwsl_notice("LWS_CALLBACK_RAW_RX %ld\n", (long)len);
        puts(in);
        break;

    case LWS_CALLBACK_RAW_CLOSE:
        lwsl_notice("LWS_CALLBACK_RAW_CLOSE\n");
        break;

    case LWS_CALLBACK_RAW_WRITEABLE:
        lwsl_notice("LWS_CALLBACK_RAW_WRITEABLE\n");
        break;

    default:
        break;
    }

    return 0;
}
*/
/* list of supported protocols and callbacks */

static const struct lws_protocols protocols[] = {
    /*
    {
        "dumb-increment-protocol",
        callback_dumb_increment,
        0,
        20,
    },*/
    {
        "lws-mirror-protocol",
        callback_lws_mirror,
        0,
        4096,
    }, 
    /*
    {
        "lws-test-raw-client",
        callback_test_raw_client,
        0,
        128
    },*/
    { NULL, NULL, 0, 0 } /* end */
};

static const struct lws_extension exts[] = {
    {
        "permessage-deflate",
        lws_extension_callback_pm_deflate,
        "permessage-deflate; client_no_context_takeover"
    },
    {
        "deflate-frame",
        lws_extension_callback_pm_deflate,
        "deflate_frame"
    },
    { NULL, NULL, NULL /* terminator */ }
};



void sighandler(int sig)
{
    force_exit = 1;
}

static struct option options[] = {
    { "help",    no_argument,        NULL, 'h' },
    { "debug",      required_argument,      NULL, 'd' },
    { "port",    required_argument,    NULL, 'p' },
    { "ssl",    no_argument,        NULL, 's' },
    { "strict-ssl",    no_argument,        NULL, 'S' },
    { "version",    required_argument,    NULL, 'v' },
    { "undeflated",    no_argument,        NULL, 'u' },
    { "echo",    no_argument,        NULL, 'e' },
    { "multi-test",    no_argument,        NULL, 'm' },
    { "nomirror",    no_argument,        NULL, 'n' },
    { "justmirror",    no_argument,        NULL, 'j' },
    { "longlived",    no_argument,        NULL, 'l' },
    { "post",    no_argument,        NULL, 'o' },
    { "once",    no_argument,        NULL, 'O' },
    { "pingpong-secs", required_argument,    NULL, 'P' },
    { "ssl-cert",  required_argument,    NULL, 'C' },
    { "ssl-key",  required_argument,    NULL, 'K' },
    { "ssl-ca",  required_argument,        NULL, 'A' },
#if defined(LWS_WITH_TLS) && defined(LWS_HAVE_SSL_CTX_set1_param)
    { "ssl-crl",  required_argument,        NULL, 'R' },
#endif
    { NULL, 0, 0, 0 }
};

static int ratelimit_connects(unsigned int *last, unsigned int secs)
{
    struct timeval tv;

    gettimeofday(&tv, NULL);

    if (tv.tv_sec - (*last) < secs)
        return 0;

    *last = tv.tv_sec;

    return 1;
}

int main(int argc, char **argv)
{
    int n = 0, m, ret = 0, port = 7681, use_ssl = 0, ietf_version = -1;
    unsigned int rl_dumb = 0, rl_mirror = 0, do_ws = 1, pp_secs = 0,
             do_multi = 0;
    struct lws_context_creation_info info;
    struct lws_client_connect_info i;
    struct lws_context *context;
    const char *prot, *p;
    char path[300];
    char cert_path[1024] = "";
    char key_path[1024] = "";
    char ca_path[1024] = "";
    unsigned long last = lws_now_secs();

    

    memset(&info, 0, sizeof info);

    lwsl_notice("libwebsockets test client - license LGPL2.1+SLE\n");
    lwsl_notice("(C) Copyright 2010-2018 Andy Green <andy@warmcat.com>\n");

    if (argc < 2)
        goto usage;

    while (n >= 0) {
        n = getopt_long(argc, argv, "Sjnuv:hsp:d:lC:K:A:P:moeO", options,
                NULL);
        if (n < 0)
            continue;
        switch (n) {
        case 'd':
            lws_set_log_level(atoi(optarg), NULL);
            break;
        case 's': /* lax SSL, allow selfsigned, skip checking hostname */
            use_ssl = LCCSCF_USE_SSL |
                  LCCSCF_ALLOW_SELFSIGNED |
                  LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
            break;
        case 'S': /* Strict SSL, no selfsigned, check server hostname */
            use_ssl = LCCSCF_USE_SSL;
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 'e':
            flag_echo = 1;
            break;
        case 'P':
            pp_secs = atoi(optarg);
            lwsl_notice("Setting pingpong interval to %d\n", pp_secs);
            break;
        case 'j':
            justmirror = 1;
            break;
        case 'l':
            longlived = 1;
            break;
        case 'v':
            ietf_version = atoi(optarg);
            break;
        case 'u':
            deny_deflate = 1;
            break;
        case 'm':
            do_multi = 1;
            break;
        case 'o':
            test_post = 1;
            break;
        case 'O':
            once = 1;
            break;
        case 'n':
            flag_no_mirror_traffic = 1;
            lwsl_notice("Disabled sending mirror data (for pingpong testing)\n");
            break;
        case 'C':
            lws_strncpy(cert_path, optarg, sizeof(cert_path));
            break;
        case 'K':
            lws_strncpy(key_path, optarg, sizeof(key_path));
            break;
        case 'A':
            lws_strncpy(ca_path, optarg, sizeof(ca_path));
            break;

#if defined(LWS_WITH_TLS) && defined(LWS_HAVE_SSL_CTX_set1_param)
        case 'R':
            lws_strncpy(crl_path, optarg, sizeof(crl_path));
            break;
#endif
        case 'h':
            goto usage;
        }
    }

    if (optind >= argc)
        goto usage;

    signal(SIGINT, sighandler);

    memset(&i, 0, sizeof(i));

    i.port = port;
    if (lws_parse_uri(argv[optind], &prot, &i.address, &i.port, &p))
        goto usage;

    /* add back the leading / on path */
    if (p[0] != '/') {
        path[0] = '/';
        lws_strncpy(path + 1, p, sizeof(path) - 1);
        i.path = path;
    } else
        i.path = p;

    if (!strcmp(prot, "http") || !strcmp(prot, "ws"))
        use_ssl = 0;
    if (!strcmp(prot, "https") || !strcmp(prot, "wss"))
        if (!use_ssl)
            use_ssl = LCCSCF_USE_SSL;

    lwsl_debug("'%s' %p '%s' %p\n", i.address, i.address, i.path, i.path);

    /*
     * create the websockets context.  This tracks open connections and
     * knows how to route any traffic and which protocol version to use,
     * and if each connection is client or server side.
     *
     * For this client-only demo, we tell it to not listen on any port.
     */
    info.http_proxy_address = "proxy.XXX.com.cn";
    info.http_proxy_port = 80;
    info.port = CONTEXT_PORT_NO_LISTEN;
    info.protocols = protocols;
    info.gid = -1;
    info.uid = -1;
    info.ws_ping_pong_interval = pp_secs;
    info.extensions = exts;

#if defined(LWS_WITH_TLS)
    info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
#endif

    //wth0630
    use_ssl = LCCSCF_USE_SSL | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK | LCCSCF_ALLOW_EXPIRED| LCCSCF_ALLOW_SELFSIGNED;
    //

    if (use_ssl) {
        /*
         * If the server wants us to present a valid SSL client certificate
         * then we can set it up here.
         */

        if (cert_path[0])
            info.client_ssl_cert_filepath = cert_path;
        if (key_path[0])
            info.client_ssl_private_key_filepath = key_path;

        /*
         * A CA cert and CRL can be used to validate the cert send by the server
         */
        if (ca_path[0])
            info.client_ssl_ca_filepath = ca_path;

        printf("client_ssl_ca_filepath =%s \n",info.client_ssl_ca_filepath);
        
        info.client_ssl_cert_filepath =  "cloud.crt";
        info.client_ssl_private_key_filepath = "cloud.key.unsecure";
        info.client_ssl_ca_filepath ="ca.crt";


#if defined(LWS_WITH_TLS) && defined(LWS_HAVE_SSL_CTX_set1_param)
        else if (crl_path[0])
            lwsl_notice("WARNING, providing a CRL requires a CA cert!\n");
#endif
    }

    if (use_ssl & LCCSCF_USE_SSL) {
        lwsl_notice(" Using SSL\n");
#if defined(LWS_WITH_MBEDTLS)
        lwsl_notice("   (NOTE: mbedtls needs to be given the remote\n");
        lwsl_notice("    CA cert to trust (with -A) to validate it)\n");
#endif
    }
    else
        lwsl_notice(" SSL disabled\n");
    if (use_ssl & LCCSCF_ALLOW_SELFSIGNED)
        lwsl_notice(" Selfsigned certs allowed\n");
    else
        lwsl_notice(" Cert must validate correctly (use -s to allow selfsigned)\n");
    if (use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)
        lwsl_notice(" Skipping peer cert hostname check\n");
    else
        lwsl_notice(" Requiring peer cert hostname matches\n");

    context = lws_create_context(&info);
    if (context == NULL) {
        fprintf(stderr, "Creating libwebsocket context failed\n");
        return 1;
    }

    i.context = context;
    i.ssl_connection = use_ssl;
    i.host = i.address;
    i.origin = i.address;
    i.ietf_version_or_minus_one = ietf_version;

    if (!strcmp(prot, "http") || !strcmp(prot, "https")) {
        lwsl_notice("using %s mode (non-ws)\n", prot);
        if (test_post) {
            i.method = "POST";
            lwsl_notice("POST mode\n");
        }
        else
            i.method = "GET";
        do_ws = 0;
    } else
        if (!strcmp(prot, "raw")) {
            i.method = "RAW";
            i.protocol = "lws-test-raw-client";
            lwsl_notice("using RAW mode connection\n");
            do_ws = 0;
        } else
            lwsl_notice("using %s mode (ws)\n", prot);

    /*
     * sit there servicing the websocket context to handle incoming
     * packets, and drawing random circles on the mirror protocol websocket
     *
     * nothing happens until the client websocket connection is
     * asynchronously established... calling lws_client_connect() only
     * instantiates the connection logically, lws_service() progresses it
     * asynchronously.
     */

    m = 0;
    while (!force_exit) {

        if (do_multi) {
            for (n = 0; n < (int)LWS_ARRAY_SIZE(wsi_multi); n++) {
                if (!wsi_multi[n] && ratelimit_connects(&rl_multi[n], 2u)) {
                    lwsl_notice("dumb %d: connecting\n", n);
                    i.protocol = protocols[PROTOCOL_DUMB_INCREMENT].name;
                    i.pwsi = &wsi_multi[n];
                    lws_client_connect_via_info(&i);
                }
            }
        } else {

            if (do_ws) {
                if (!flag_echo && !justmirror && !wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
                    lwsl_notice("dumb: connecting\n");
                    i.protocol = protocols[PROTOCOL_DUMB_INCREMENT].name;
                    i.pwsi = &wsi_dumb;
                    lws_client_connect_via_info(&i);
                }

                if (!wsi_mirror && ratelimit_connects(&rl_mirror, 2u)) {
                    lwsl_notice("mirror: connecting\n");
                    i.protocol = protocols[PROTOCOL_LWS_MIRROR].name;
                    i.pwsi = &wsi_mirror;
                    wsi_mirror = lws_client_connect_via_info(&i);
                }
            } else
                if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
                    lwsl_notice("http: connecting\n");
                    i.pwsi = &wsi_dumb;
                    lws_client_connect_via_info(&i);
                }
        }

        lws_service(context, 500);

        if (do_multi) {
            m++;
            if (m == 10) {
                m = 0;
                lwsl_notice("doing lws_callback_on_writable_all_protocol\n");
                lws_callback_on_writable_all_protocol(context,
                       &protocols[PROTOCOL_DUMB_INCREMENT]);
            }
        }

        if (flag_echo && lws_now_secs() != last) {
            lwsl_notice("rxb %d, rx_count %d\n", rxb, rx_count);
            last = lws_now_secs();
        }
    }

    lwsl_err("Exiting\n");
    lws_context_destroy(context);

    return ret;

usage:
    fprintf(stderr, "Usage: libwebsockets-test-client "
                "<server address> [--port=<p>] "
                "[--ssl] [-k] [-v <ver>] "
                "[-d <log bitfield>] [-l]\n");
    return 1;
}

 



这篇关于wss的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程