最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中套接字庫sockpp的使用詳解

 更新時間:2023年11月15日 11:29:38   作者:fengbingchun  
sockpp是一個開源、簡單、現(xiàn)代的C++套接字庫,這篇文章主要為大家詳細(xì)介紹一下套接字庫sockpp的使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下

sockpp是一個開源、簡單、現(xiàn)代的C++套接字庫,地址為:https://github.com/fpagliughi/sockpp,最新發(fā)布版本為0.8.1,license為BSD-3-Clause。目前支持Linux、Windows、Mac上的IPv4、IPv6和Unix域套接字。其它*nix和POSIX系統(tǒng)只需很少的修改或無需修改即可工作。

1.套接字基類包裝(wrap)系統(tǒng)套接字句柄,并維持其生命周期。當(dāng)C++對象超出范圍時,它會關(guān)閉底層套接字句柄。套接字對象通常是可移動的,但不可復(fù)制??梢允褂?std::move()將套接字從一個作用域(或線程)傳輸?shù)搅硪粋€作用域。

2.庫中的所有代碼都位于sockpp C++命名空間內(nèi)。

3.TCP和其它"流"網(wǎng)絡(luò)應(yīng)用程序通常設(shè)置為服務(wù)器或客戶端。接受器用于創(chuàng)建TCP/流服務(wù)器。它綁定一個地址并偵聽已知端口以接受傳入連接。 當(dāng)連接被接受時,會創(chuàng)建一個新的流式套接字。該新套接字可以直接處理或移動到線程(或線程池)進(jìn)行處理。

相反,要創(chuàng)建TCP客戶端,需要創(chuàng)建連接器對象并將其連接到已知地址(通常是主機(jī)和套接字)的服務(wù)器。連接后,套接字是一種流式套接字,可以直接用于讀寫。

對于IPv4,sockpp::tcp_acceptor和sockpp::tcp_connector類分別用于創(chuàng)建服務(wù)器和客戶端。它們使用sockpp::inet_address類來指定由32位主機(jī)地址和16位端口號組成的端點(diǎn)地址。

sockpp::tcp_acceptor通常位于一個循環(huán)中接受新連接,并將它們傳遞給另一個進(jìn)程、線程或線程池以與客戶端交互。

TCP客戶端稍微簡單一些,創(chuàng)建一個sockpp::tcp_connector對象并連接,然后可以直接讀寫數(shù)據(jù)。

4.每個套接字類的默認(rèn)構(gòu)造函數(shù)不執(zhí)行任何操作,只是將底層句柄設(shè)置為INVALID_SOCKET。它們不創(chuàng)建套接字對象。

5.套接字對象不是線程安全的。想要有多個線程從套接字讀取或?qū)懭胩捉幼值膽?yīng)用程序應(yīng)該使用某種形式的序列化,例如std::mutex來保護(hù)訪問。套接字可以安全地從一個線程移動到(moved)另一個線程。這是服務(wù)器的一種常見模式,它使用一個線程接受傳入連接,然后將新套接字傳遞給另一個線程或線程池進(jìn)行處理。

由于套接字無法復(fù)制,唯一的選擇是將套接字移動到這樣的函數(shù)。這是一種常見的模式,尤其是在客戶端應(yīng)用程序中,讓一個線程從套接字讀取數(shù)據(jù),另一個線程向套接字寫入數(shù)據(jù)。在這種情況下,底層套接字句柄可以被認(rèn)為是線程安全的(一個讀線程和一個寫線程)。但即使在這種情況下,sockpp::socket對象仍然不是線程安全的,特別是由于緩存的錯誤值(cached error value)。寫入線程可能會看到讀取線程上發(fā)生的錯誤,反之亦然。

這種情況的解決方案是使用socket::clone()方法來復(fù)制套接字。這將使用系統(tǒng)的dup()函數(shù)或類似的函數(shù)創(chuàng)建另一個帶有套接字句柄的重復(fù)副本的套接字。這樣做的另一個好處是套接字的每個副本都可以保持獨(dú)立的生命周期。在兩個對象超出范圍之前,底層套接字不會關(guān)閉。

在Windows和Linux上編譯的sockpp的shell腳本如下:

#! /bin/bash
 
if [ $# != 2 ]; then
    echo "Error: requires two parameters: 1: windows or linux; 2: release or debug"
    echo "For example: $0 windows debug"
    exit -1
fi
 
if [ $1 != "windows"  ] && [ $1 != "linux" ]; then
    echo "Error: the first parameter can only be windows or linux"
    exit -1
fi
 
if [ $2 != "debug" ] && [ $2 != "release" ]; then
    echo "Error: the second parameter can only be debug or release"
    exit -1
fi
 
if [ $1 == "windows" ] && [ $2 == "debug" ]; then
    cmake \
        -G"Visual Studio 17 2022" -A x64 \
        -DCMAKE_BUILD_TYPE=Debug \
        -DCMAKE_CONFIGURATION_TYPES=Debug \
        -DSOCKPP_BUILD_SHARED=OFF \
        -DSOCKPP_BUILD_STATIC=ON \
        -DSOCKPP_BUILD_EXAMPLES=ON \
        -DCMAKE_INSTALL_PREFIX=install/debug \
        -Bbuild \
        .
    
    cmake --build build/ --target install --config debug
fi
 
if [ $1 == "windows" ] && [ $2 == "release" ]; then
    cmake \
        -G"Visual Studio 17 2022" -A x64 \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_CONFIGURATION_TYPES=Release \
        -DSOCKPP_BUILD_SHARED=OFF \
        -DSOCKPP_BUILD_STATIC=ON \
        -DSOCKPP_BUILD_EXAMPLES=ON \
        -DCMAKE_INSTALL_PREFIX=install/release \
        -Bbuild \
        .
 
    cmake --build build/ --target install --config release
fi
 
if [ $1 == "linux" ] && [ $2 == "debug" ]; then
    cmake \
        -DCMAKE_BUILD_TYPE=Debug \
        -DSOCKPP_BUILD_SHARED=OFF \
        -DSOCKPP_BUILD_STATIC=ON \
        -DSOCKPP_BUILD_EXAMPLES=ON \
        -DCMAKE_INSTALL_PREFIX=install/debug \
        -Bbuild \
        .
    
    cmake --build build/ --target install --config debug
fi
 
if [ $1 == "linux" ] && [ $2 == "release" ]; then
    cmake \
        -DCMAKE_BUILD_TYPE=Release \
        -DSOCKPP_BUILD_SHARED=OFF \
        -DSOCKPP_BUILD_STATIC=ON \
        -DSOCKPP_BUILD_EXAMPLES=ON \
        -DCMAKE_INSTALL_PREFIX=install/release \
        -Bbuild \
        .
 
    cmake --build build/ --target install --config release
fi
 
rc=$?
if [[ ${rc} != 0 ]]; then
    echo "Error: please check: ${rc}"
	exit ${rc}
fi

以下為IPv4的測試代碼:

1.客戶端測試代碼如下:

int test_sockpp_client()
{
    sockpp::initialize();
 
    sockpp::tcp_connector conn({host, port});
	if (!conn) {
		std::cerr << "Error: connecting to server at: "
			<< sockpp::inet_address(host, port)
			<< ", message: " << conn.last_error_str() << std::endl;
		return -1;
	}
 
    std::cout << "created a connection from: " << conn.address() << std::endl;
	std::cout << "created a connection to " << conn.peer_address() << std::endl;
 
    // set a timeout for the responses
    if (!conn.read_timeout(std::chrono::seconds(5))) {
        std::cerr << "Error: setting timeout on TCP stream: " << conn.last_error_str() << std::endl;
    }
 
    const std::vector<std::string> addr{"csdn", "github", "gitlab"};
    std::unique_ptr<unsigned char[]> buf(new unsigned char[len]);
    int index{0};
 
	std::atomic<bool> quit{ false };
	std::thread th([&quit] {
		std::this_thread::sleep_for(std::chrono::seconds(20));
		quit = true;
	});
 
	while (true) {
		if (quit) break;
 
        auto ret = conn.write(addr[index]);
        if (ret != addr[index].size()) {
            std::cerr << "Error: writing to the TCP stream: " << conn.last_error_str() << std::endl;
            break;
        }
 
		memset(buf.get(), 0, len);
        ret = conn.read(buf.get(), len);
        if (ret == -1) {
            std::cerr << "Error: reading from TCP stream: " << conn.last_error_str() << std::endl;
            break;
        }
 
        std::cout << addr[index] << ": " << buf.get() << std::endl;
 
        if (++index == addr.size()) index = 0;
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
 
	th.join();
    return 0;
}

2.服務(wù)器端測試代碼如下:

int test_sockpp_server()
{
    sockpp::initialize();
 
    sockpp::tcp_acceptor acc(port);
	if (!acc) {
		std::cerr << "Error: creating the acceptor: " << acc.last_error_str() << std::endl;
		return -1;
	}
 
	while (true) {
		sockpp::inet_address peer;
		// accept a new client connection
		sockpp::tcp_socket sock = acc.accept(&peer);
		std::cout << "received a connection request from: " << peer << std::endl;
		if (!sock) {
			std::cerr << "Error: accepting incoming connection: " << acc.last_error_str() << std::endl;
		}
		else {
			// create a thread and transfer the new stream to it
			std::thread th2(run_echo, std::move(sock));
			th2.detach();
		}
	}
 
    return 0;
}

3.輔助code如下所示:

namespace {
 
constexpr char* host{"127.0.0.1"};
constexpr in_port_t port{ 8888 };
constexpr int len {64};
 
void run_echo(sockpp::tcp_socket sock)
{
	std::cout << "thread id: " << std::this_thread::get_id() << std::endl;
 
	std::map<std::string, std::string> addr;
	addr["csdn"] = "https://blog.csdn.net/fengbingchun";
	addr["github"] = "https://github.com/fengbingchun";
 
	std::unique_ptr<unsigned char[]> buf(new unsigned char[len]);
 
	while (true) {
		memset(buf.get(), 0, len);
		auto ret = sock.read(buf.get(), len);
		if (ret == -1) {
			std::cerr << "Error: reading from TCP stream: " << sock.last_error_str() << std::endl;
            break;
		}
 
		auto it = addr.find(std::string((char*)buf.get()));
		if (it != addr.end()) {
			sock.write(it->second);
		}
		else
			sock.write("unkonwn");
	}
}
 
} // namespace

Windows上執(zhí)行結(jié)果如下所示:模擬1個服務(wù)器端,3個客戶端

Linux上執(zhí)行結(jié)果如下圖所示:模擬1個服務(wù)器端,3個客戶端

GitHubhttps://github.com/fengbingchun/OpenSSL_Test

到此這篇關(guān)于C++中套接字庫sockpp的使用詳解的文章就介紹到這了,更多相關(guān)C++套接字庫sockpp內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言中函數(shù)指針與軟件設(shè)計經(jīng)驗總結(jié)

    C語言中函數(shù)指針與軟件設(shè)計經(jīng)驗總結(jié)

    今天小編就為大家分享一篇關(guān)于C語言中函數(shù)指針與軟件設(shè)計經(jīng)驗總結(jié),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 簡單了解設(shè)計模式中的裝飾者模式及C++版代碼實現(xiàn)

    簡單了解設(shè)計模式中的裝飾者模式及C++版代碼實現(xiàn)

    這篇文章主要介紹了簡單了解設(shè)計模式中的裝飾者模式及C++版代碼實現(xiàn),ConcreteComponent的引用(指針)也可以達(dá)到修飾的功能,需要的朋友可以參考下
    2016-03-03
  • C語言新手入門速通手冊

    C語言新手入門速通手冊

    C 語言是一種通用的、面向過程式的計算機(jī)程序設(shè)計語言。1972 年,為了移植與開發(fā) UNIX 操作系統(tǒng),丹尼斯·里奇在貝爾電話實驗室設(shè)計開發(fā)了 C 語言。C 語言是一種廣泛使用的計算機(jī)語言,它與 Java 編程語言一樣普及,二者在現(xiàn)代軟件程序員之間都得到廣泛使用
    2022-04-04
  • C++中memset函數(shù)用法詳解

    C++中memset函數(shù)用法詳解

    這篇文章主要介紹了C++中memset函數(shù)用法,結(jié)合實例形式詳細(xì)分析了memset函數(shù)的功能、使用方法與相關(guān)注意事項,需要的朋友可以參考下
    2016-06-06
  • 手把手教你實現(xiàn)漂亮的Qt?登錄界面

    手把手教你實現(xiàn)漂亮的Qt?登錄界面

    最近在使用Qt5,Qt?Creator做一個管理系統(tǒng)類的項目,需要用到登錄界面,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Visual Studio Code 從簡介、安裝到配置所需插件詳細(xì)介紹

    Visual Studio Code 從簡介、安裝到配置所需插件詳細(xì)介紹

    這篇文章給大家介紹到vs與vs code的區(qū)別,并且會詳細(xì)介紹vscode的安裝步驟,和我所了解過的插件配置,感興趣的朋友跟隨小編一起看看吧
    2020-03-03
  • C語言中的分支循環(huán)其嵌套語句

    C語言中的分支循環(huán)其嵌套語句

    這篇文章主要介紹了C語言中的分支循環(huán)其嵌套語句,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java C++ 算法題解leetcode1582二進(jìn)制矩陣特殊位置

    Java C++ 算法題解leetcode1582二進(jìn)制矩陣特殊位置

    這篇文章主要為大家介紹了Java C++ 算法題解leetcode1582二進(jìn)制矩陣特殊位置示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • C++?引用和指針的區(qū)別對比分析

    C++?引用和指針的區(qū)別對比分析

    在C++?中,指針(Pointer)和引用(Reference)都用于間接訪問變量,但是它們在語法和語義上都有顯著的差異,下面通過本文給大家介紹C++?引用和指針的區(qū)別,感興趣的朋友一起看看吧
    2025-10-10
  • C++與C語言的區(qū)別你知道嗎

    C++與C語言的區(qū)別你知道嗎

    這篇文章主要為大家詳細(xì)介紹了C++與C的區(qū)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評論

金塔县| 涞水县| 临汾市| 衡东县| 南城县| 黄骅市| 湟源县| 瓮安县| 新干县| 晴隆县| 孝感市| 南华县| 新安县| 朝阳区| 洛阳市| 托里县| 和政县| 景谷| 汝城县| SHOW| 抚宁县| 屏南县| 定陶县| 格尔木市| 凌云县| 扎鲁特旗| 洪湖市| 教育| 扎囊县| 本溪市| 新河县| 怀安县| 朔州市| 密云县| 苍梧县| 宁明县| 达日县| 额尔古纳市| 延安市| 子洲县| 旬阳县|