linux編譯運行build.sh,linux下libwebsockets編譯及實例

最近想自己搭建一個webscoket協議的服務器,打算用libwebsockts這個庫。

下載代碼編譯。

編寫一個shell腳本

#!/bin/sh

# wget http://git.warmcat.com/cgi-bin/cgit/libwebsockets/snapshot/libwebsockets-1.4-chrome43-firefox-36.tar.gz

# tar xvzf libwebsockets-1.4-chrome43-firefox-36.tar.gz

#cd libwebsockets-1.4-chrome43-firefox-36

# build

git clone https://github.com/warmcat/libwebsockets.git

cd libwebsockets

documentRoot=`pwd`

mkdir build

cmake ..

make

執行shell腳本就下載編譯成功了。

運行一個例子

其實在庫里面有一些實例的.

cd build

#!/bin/sh

documentRoot=`pwd`

libdir=libwebsockets

cd $libdir/build/bin

./libwebsockets-test-server --resource_path=$documentRoot/test-server

這樣就運行自帶的服務器。運行結果.

0818b9ca8b590ca3270a3433284dd417.png

瀏覽器輸入127.0.0.1:7681結果:

0818b9ca8b590ca3270a3433284dd417.png

這樣就是完整的結果了。

搭建自己的websocket server

#include

#include

#include

#include

#include

#include

#define KGRN "\033[0;32;32m"

#define KCYN "\033[0;36m"

#define KRED "\033[0;32;31m"

#define KYEL "\033[1;33m"

#define KMAG "\033[0;35m"

#define KBLU "\033[0;32;34m"

#define KCYN_L "\033[1;36m"

#define RESET "\033[0m"

static int destroy_flag = 0;

static void INT_HANDLER(int signo) {

destroy_flag = 0;

}

/* *

* websocket_write_back: write the string data to the destination wsi.

*/

int websocket_write_back(struct lws *wsi_in, char *str, int str_size_in)

{

if (str == NULL || wsi_in == NULL)

return -1;

int n;

int len;

unsigned char *out = NULL;

if (str_size_in < 1)

len = strlen(str);

else

len = str_size_in;

out = (unsigned char *)malloc(sizeof(unsigned char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));

//* setup the buffer*/

memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, str, len );

//* write out*/

n = lws_write(wsi_in, out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);

printf(KBLU"[websocket_write_back] %s\n"RESET, str);

//* free the buffer*/

free(out);

return n;

}

static int ws_service_callback(

struct lws *wsi,

enum lws_callback_reasons reason, void *user,

void *in, size_t len)

{

switch (reason) {

case LWS_CALLBACK_ESTABLISHED:

printf(KYEL"[Main Service] Connection established\n"RESET);

break;

//* If receive a data from client*/

case LWS_CALLBACK_RECEIVE:

printf(KCYN_L"[Main Service] Server recvived:%s\n"RESET,(char *)in);

//* echo back to client*/

websocket_write_back(wsi ,(char *)in, -1);

break;

case LWS_CALLBACK_CLOSED:

printf(KYEL"[Main Service] Client close.\n"RESET);

break;

default:

break;

}

return 0;

}

struct per_session_data {

int fd;

};

int main(void) {

// server url will usd port 5000

int port = 5000;

const char *interface = NULL;

struct lws_context_creation_info info;

struct lws_protocols protocol;

struct lws_context *context;

// Not using ssl

const char *cert_path = NULL;

const char *key_path = NULL;

// no special options

int opts = 0;

//* register the signal SIGINT handler */

struct sigaction act;

act.sa_handler = INT_HANDLER;

act.sa_flags = 0;

sigemptyset(&act.sa_mask);

sigaction( SIGINT, &act, 0);

//* setup websocket protocol */

protocol.name = "my-echo-protocol";

protocol.callback = ws_service_callback;

protocol.per_session_data_size=sizeof(struct per_session_data);

protocol.rx_buffer_size = 0;

//* setup websocket context info*/

memset(&info, 0, sizeof info);

info.port = port;

info.iface = interface;

info.protocols = &protocol;

info.extensions = lws_get_internal_extensions();

info.ssl_cert_filepath = cert_path;

info.ssl_private_key_filepath = key_path;

info.gid = -1;

info.uid = -1;

info.options = opts;

//* create libwebsocket context. */

context = lws_create_context(&info);

if (context == NULL) {

printf(KRED"[Main] Websocket context create error.\n"RESET);

return -1;

}

printf(KGRN"[Main] Websocket context create success.\n"RESET);

//* websocket service */

while ( !destroy_flag ) {

lws_service(context, 50);

}

usleep(10);

lws_context_destroy(context);

return 0;

}

執行腳本:

#!/bin/sh

libdir=libwebsockets

g++ -g -o ws_servertest_ws_server.cpp -I$libdir/lib -I$libdir/build -L$libdir/build/lib -lwebsockets

編寫自己的websocket client

#include

#include

#include

#include

#include

#include

#include

#define KGRN "\033[0;32;32m"

#define KCYN "\033[0;36m"

#define KRED "\033[0;32;31m"

#define KYEL "\033[1;33m"

#define KBLU "\033[0;32;34m"

#define KCYN_L "\033[1;36m"

#define KBRN "\033[0;33m"

#define RESET "\033[0m"

static int destroy_flag = 0;

static int connection_flag = 0;

static int writeable_flag = 0;

static void INT_HANDLER(int signo) {

destroy_flag = 0;

}

struct session_data {

int fd;

};

struct pthread_routine_tool {

struct lws_context *context;

struct lws *wsi;

};

static int websocket_write_back(struct lws *wsi_in, char *str, int str_size_in)

{

if (str == NULL || wsi_in == NULL)

return -1;

int n;

int len;

unsigned char *out = NULL;

if (str_size_in < 1)

len = strlen(str);

else

len = str_size_in;

out = (unsigned char *)malloc(sizeof(unsigned char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));

//* setup the buffer*/

memcpy (out + LWS_SEND_BUFFER_PRE_PADDING, str, len );

//* write out*/

n = lws_write(wsi_in, out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);

printf(KBLU"[websocket_write_back] %s\n"RESET, str);

//* free the buffer*/

free(out);

return n;

}

static int ws_service_callback(

struct lws *wsi,

enum lws_callback_reasons reason, void *user,

void *in, size_t len)

{

switch (reason) {

case LWS_CALLBACK_CLIENT_ESTABLISHED:

printf(KYEL"[Main Service] Connect with server success.\n"RESET);

connection_flag = 1;

break;

case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:

printf(KRED"[Main Service] Connect with server error.\n"RESET);

destroy_flag = 1;

connection_flag = 0;

break;

case LWS_CALLBACK_CLOSED:

printf(KYEL"[Main Service] LWS_CALLBACK_CLOSED\n"RESET);

destroy_flag = 1;

connection_flag = 0;

break;

case LWS_CALLBACK_CLIENT_RECEIVE:

printf(KCYN_L"[Main Service] Client recvived:%s\n"RESET, (char *)in);

if (writeable_flag)

destroy_flag = 1;

break;

case LWS_CALLBACK_CLIENT_WRITEABLE :

printf(KYEL"[Main Service] On writeable is called. send byebye message\n"RESET);

websocket_write_back(wsi, "Byebye! See you later", -1);

writeable_flag = 1;

break;

default:

break;

}

return 0;

}

static void *pthread_routine(void *tool_in)

{

struct pthread_routine_tool *tool = (struct pthread_routine_tool*)tool_in;

printf(KBRN"[pthread_routine] Good day. This is pthread_routine.\n"RESET);

//* waiting for connection with server done.*/

while(!connection_flag)

usleep(1000*20);

//*Send greeting to server*/

printf(KBRN"[pthread_routine] Server is ready. send a greeting message to server.\n"RESET);

websocket_write_back(tool->wsi, "Good day", -1);

printf(KBRN"[pthread_routine] sleep 2 seconds then call onWritable\n"RESET);

sleep(1);

printf(KBRN"------------------------------------------------------\n"RESET);

sleep(1);

//printf(KBRN"[pthread_routine] sleep 2 seconds then call onWritable\n"RESET);

//*involked wriable*/

printf(KBRN"[pthread_routine] call on writable.\n"RESET);

lws_callback_on_writable(tool->wsi);

}

int main(void)

{

//* register the signal SIGINT handler */

struct sigaction act;

act.sa_handler = INT_HANDLER;

act.sa_flags = 0;

sigemptyset(&act.sa_mask);

sigaction( SIGINT, &act, 0);

struct lws_context *context = NULL;

struct lws_context_creation_info info;

struct lws *wsi = NULL;

struct lws_protocols protocol;

memset(&info, 0, sizeof info);

info.port = CONTEXT_PORT_NO_LISTEN;

info.iface = NULL;

info.protocols = &protocol;

info.ssl_cert_filepath = NULL;

info.ssl_private_key_filepath = NULL;

info.extensions = lws_get_internal_extensions();

info.gid = -1;

info.uid = -1;

info.options = 0;

protocol.name = "my-echo-protocol";

protocol.callback = &ws_service_callback;

protocol.per_session_data_size = sizeof(struct session_data);

protocol.rx_buffer_size = 0;

protocol.id = 0;

protocol.user = NULL;

context = lws_create_context(&info);

printf(KRED"[Main] context created.\n"RESET);

if (context == NULL) {

printf(KRED"[Main] context is NULL.\n"RESET);

return -1;

}

wsi = lws_client_connect(context, "localhost", 5000, 0, "/", "localhost:5000", NULL,

protocol.name, -1);

if (wsi == NULL) {

printf(KRED"[Main] wsi create error.\n"RESET);

return -1;

}

printf(KGRN"[Main] wsi create success.\n"RESET);

struct pthread_routine_tool tool;

tool.wsi = wsi;

tool.context = context;

pthread_t pid;

pthread_create(&pid, NULL, pthread_routine, &tool);

pthread_detach(pid);

while(!destroy_flag)

{

lws_service(context, 50);

}

lws_context_destroy(context);

return 0;

}編寫腳本:

#!/bin/sh

libdir=libwebsockets

g++ -g -o ws_client test_ws_client.cpp -I$libdir/lib -I$libdir/build -L$libdir/build/lib -lwebsockets -lpthread

運行結果

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

紅線部分是交互的結果.這樣就是完整的一套邏輯了.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257978.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257978.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257978.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Tomcat如何配置環境變量

1&#xff0c; JDK&#xff1a;版本為jdk-7-windows-i586.exe 下載地址: http://www.oracle.com/technetwork/java/javase/downloads/index.html 2&#xff0c;tomcat&#xff1a;版本為apache-tomcat-7.0.33-windows-x86.zip 下載地址&#xff1a;http://tomcat.apache.org/ 2…

eclipse常用快捷鍵——非常實用

1、eclipse 查看變量或方法被調用的快捷鍵如下&#xff1a; &#xff08;1&#xff09;雙擊選中變量或者方法&#xff08;2&#xff09;鍵盤上CtrlshiftG組合鍵 2、eclipse中查看接口實現類快捷鍵 先找到接口類打開,然后雙擊接口名選中,再按住ctrlT就可以了。 3、eclipse中全局…

反編譯查看源碼dex2jar

為什么80%的碼農都做不了架構師&#xff1f;>>> 上次說到了用apktool反編譯&#xff0c;這次我們來用dex2jar 把apk解壓得到文件夾 文件夾打開看到這些文件 其中這個classes.dex就是這次需要用到的字節碼文件 把這個字節碼文件托到dex2jar目錄里 命令行編輯 得到下…

linux命令驗證sqlldr,Linux:sqlldr命令

第一步&#xff1a;寫一個 ctl格式的控制文件CTL 控制文件的內容 &#xff1a;load data --1. 控制文件標識infilexxx.txt --2. 要導入的數據文件名insert into table test--3. 將文件插入到數據庫的 test 表中fields terminated by X09 --4. 用于分割一行中各個屬性值的符號(例…

STL 中的鏈表排序

一直以來學習排序算法&#xff0c; 都沒有在鏈表排序上下太多功夫&#xff0c;因為用得不多。最近看STL源碼&#xff0c;才發現&#xff0c;原來即使是鏈表&#xff0c;也能有時間復雜度為O(nlogn)的算法&#xff0c; 大大出乎我的意料之外&#xff0c;一般就能想到個插入排序。…

cmd更換編碼類型

chcp 65001 UTF-8 65001 GBK 936 本文出自 “曾頤楠的播客” 博客&#xff0c;請務必保留此出處http://zengyinan.blog.51cto.com/9524976/1721475 轉載于:https://www.cnblogs.com/zengyinanos/p/5042732.html

代碼混淆之后定位線上bug

代碼混淆的目的 代碼混淆的目的是防止競爭對手通過反編譯來閱讀項目代碼。 Android中通過ProGuard來做代碼混淆&#xff08;當然也還有其他的產品可以做代碼混淆&#xff09;。 bug日志反混淆 資料&#xff1a;錯誤log、mapping.txt 異常log&#xff1a; mapping.txt&#xff…

linux怎么切換不同版本的r,在linux中用同一個版本的R 同時安裝 Seurat2 和 Seurat3

在linux中用同一個版本的R 同時安裝 Seurat 2 和 Seurat 3Seurat 作為單細胞分析中的重量級R包&#xff0c;有多好用用&#xff0c;用過的人都知道。Seurat 分析流程基本涵蓋了單細胞分析中的所有常見分析方法&#xff0c;包括filtering&#xff0c;tSNE&#xff0c;UMAP降維及…

Unity手游之路四3d旋轉-四元數,歐拉角和變幻矩陣

http://blog.csdn.net/janeky/article/details/17272625 今天我們來談談關于Unity中的旋轉。主要有三種方式。變換矩陣&#xff0c;四元數和歐拉角。 定義 變換矩陣可以執行任意的3d變換&#xff08;平移&#xff0c;旋轉&#xff0c;縮放&#xff0c;切邊&#xff09;并且透視…

本地通知

本地通知&#xff0c;local notification&#xff0c;用于基于時間行為的通知&#xff0c;比如有關日歷或者todo列表的小應用。另外&#xff0c;應用如果在后臺執行&#xff0c;iOS允許它在受限的時間內運行&#xff0c;它也會發現本地通知有用。比如&#xff0c;一個應用&…

Redux 并不慢,只是你使用姿勢不對 —— 一份優化指南

原文地址&#xff1a;Redux 并不慢&#xff0c;只是你使用姿勢不對 —— 一份優化指南原文作者&#xff1a;Julian Krispel譯文出自&#xff1a;掘金翻譯計劃本文永久鏈接&#xff1a;github.com/xitu/gold-m…譯者&#xff1a;reid3290校對者&#xff1a;sunui&#xff0c;xek…

把windows裝到linux下,如何將WSL(Windows Subsystem for Linux 2)安裝到Windows 10?

原標題&#xff1a;如何將WSL(Windows Subsystem for Linux 2)安裝到Windows 10&#xff1f;Windows 10憑借大受歡迎的WSL(Windows Subsystem for Linux)進入Linux領域。由于最近推出了WSL的最新版WSL2&#xff0c;用戶現在可以利用實際的Linux內核從Windows執行Linux任務。現在…

TWRP-recovery中文界面安裝方法[轉]

把下載到的ui.zip放入sdcard1/twrp文件夾。注意&#xff0c;是內置存儲卡中。如沒有上述文件夾&#xff0c;自行建立后通過文件管理器放入&#xff0c;不是卡刷。文件夾應如下所示&#xff1a;sdcard1&#xff08;內置SD&#xff09; &#xff5c; ┕--twrp&#xff08;文件夾…

如何定期備份網站數據

產生這個問題的背景是我在維護兩個個人的網站&#xff0c;因為采用的是虛擬主機&#xff0c;有時候空間續費不及時等&#xff0c;都可能造成數據的丟失&#xff0c;為了保障數據不丟失&#xff0c;因為有必要每15天左右對網站數據進行備份以防止發生不當的事情。 我們希望做的就…

初創團隊可能不適合應屆生小孩

根據最近招聘中接觸到的一些剛畢業小孩的表現&#xff0c;談談這個問題&#xff1a; 1、扛不住&#xff0c;初創團隊一般最好一人撐一快工作&#xff0c;剛畢業經驗比較薄的小孩在這方面一是心理上不敢擔當&#xff0c;二是能力上確實還需要磨煉成長 2、初創團隊的那個環境可能…

vba執行linux命令,從VBA中的shell命令捕獲輸出值?

慕蓋茨4494581根據Andrew Lessard的回答&#xff0c;這是一個運行命令并將輸出作為字符串返回的函數 -Public Function ShellRun(sCmd As String) As StringRun a shell command, returning the output as a stringDim oShell As ObjectSet oShell CreateObject("WScript…

溢出和剪裁,可見性

內容溢出和剪裁 如果一個元素的內容對于元素大小來說過大&#xff0c;就有可能溢出元素本身。對于此情況&#xff0c;有一些解決辦法可選。 溢出 overflow 值 visible(默認):內容在元素框外可見。一般會導致內容超出其自己的元素框&#xff0c;但不會改變框的形狀scroll:溢出部…

C#= 棧模仿堆的操作

//原理&#xff0c;利用兩個棧&#xff0c;互相作用&#xff0c;來模仿堆的效果&#xff0c;先進先出。。 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Threading.Tasks;5 6 namespace TwoStacksQueue7 {8 public class Progra…

linux計劃任務執行日志,linux中centos制定計劃任務執行命令并且輸出日志

1.寫腳本最簡單的 寫如下代碼#!/bin/shABC1.每個命令之間用;隔開說明&#xff1a;各命令的執行給果&#xff0c;不會影響其它命令的執行。換句話說&#xff0c;各個命令都會執行&#xff0c;但不保證每個命令都執行成功。2.每個命令之間用&&隔開說明&#xff1a;若前面…

Java-大集合拆分為指定大小的小集合

因為Oracle數據的in 最大允許1000 ,超過就會報錯&#xff0c; 所以需要將集合拆分為多個集合進行處理. /*** 拆分集合* param <T>* param resList 要拆分的集合* param count 每個集合的元素個數* return 返回拆分后的各個集合*/public static <T> List<L…