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

C++多線(xiàn)程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶(hù)端通信

 更新時(shí)間:2021年05月17日 09:11:50   作者:新西蘭做的飯  
通訊建立后首先由服務(wù)器端發(fā)送消息,客戶(hù)端接收消息;接著客戶(hù)端發(fā)送消息,服務(wù)器端接收消息,實(shí)現(xiàn)交互發(fā)送消息。本文主要介紹了C++多線(xiàn)程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶(hù)端通信,感興趣的可以了解一下

通訊建立后首先由服務(wù)器端發(fā)送消息,客戶(hù)端接收消息;接著客戶(hù)端發(fā)送消息,服務(wù)器端接收消息,實(shí)現(xiàn)交互發(fā)送消息。

服務(wù)器同時(shí)可以和多個(gè)客戶(hù)端建立連接,進(jìn)行交互;

在某次交互中,服務(wù)器端或某客戶(hù)端有一方發(fā)送"end"即終止服務(wù)器與其的通信;服務(wù)器還可以繼續(xù)接收其他客戶(hù)端的請(qǐng)求,與其他客戶(hù)端通信。

服務(wù)器端

#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define PORT 65432
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);
int main() 
{
	//初始化winsock2.DLL
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		cout << "加載winsock.dll失??!" << endl;
		return 0;
	}
	//創(chuàng)建套接字
	SOCKET  sock_server;
	if ((sock_server = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
	{
		cout << "創(chuàng)建套接字失??!錯(cuò)誤代碼:" << WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}
	//綁定端口和Ip
	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);//綁定本機(jī)的環(huán)回地址
	if (SOCKET_ERROR == bind(sock_server, (SOCKADDR*)&addr, sizeof(sockaddr_in)))
	{
		cout << "地址綁定失敗!錯(cuò)誤代碼:" << WSAGetLastError() << endl;
		closesocket(sock_server);
		WSACleanup();
		return 0;
	}
	//將套接字設(shè)為監(jiān)聽(tīng)狀態(tài)
	listen(sock_server, 0);
	
	//主線(xiàn)程循環(huán)接收客戶(hù)端的連接
	while (1) 
	{
		sockaddr_in addrClient;
		int len = sizeof(sockaddr_in);
		//接收成功返回與client通訊的socket
		SOCKET con = accept(sock_server, (SOCKADDR*)&addrClient, &len);
		if (con != INVALID_SOCKET) 
		{
			//創(chuàng)建線(xiàn)程 并且傳入與client通訊的套接字
			HANDLE hThread = CreateThread(NULL, 0, ThreadFun, (LPVOID)con, 0, NULL);
			CloseHandle(hThread); //關(guān)閉對(duì)線(xiàn)程的引用
		}
	}
	closesocket(sock_server);
	WSACleanup();
	return 0;
}
//線(xiàn)程通訊部分
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter) 
{
	//與客戶(hù)端通訊 先發(fā)送再接收數(shù)據(jù)
	SOCKET sock = (SOCKET)lpThreadParameter;
	cout << "成功和" << sock << "建立連接!" << endl;
	while (1)
	{
		char msgbuffer[1000];//字符緩沖區(qū)
		printf("服務(wù)器向%d發(fā)送數(shù)據(jù):\n", sock);
		cin.getline(msgbuffer, sizeof(msgbuffer));
		int size = send(sock, msgbuffer, sizeof(msgbuffer), 0);//給客戶(hù)端發(fā)送一段信息
		if (strcmp(msgbuffer, "end\0") == 0)
		{
			cout << "關(guān)閉和" << sock << "的連接!" << endl;
			return 0;
		}
		if (size == SOCKET_ERROR || size == 0)
		{
			cout << "發(fā)送信息失?。″e(cuò)誤代碼:" << WSAGetLastError() << endl;
			return 0;
		}
		else cout << "信息發(fā)送成功!" << endl;
		
		//接收客戶(hù)端數(shù)據(jù)
		msgbuffer[999] = { 0 };
		int ret = recv(sock, msgbuffer, sizeof(msgbuffer), 0);
		if(ret == SOCKET_ERROR || ret == 0)
		{
			cout << sock << "斷開(kāi)了連接!" << endl;
			break;
		}
		else cout << sock << "  說(shuō): " << msgbuffer << endl;
	}
	return 0;
}

客戶(hù)端

#include <winsock2.h>
#include <WS2tcpip.h>
#include <iostream>
using  namespace std;
#pragma comment(lib, "ws2_32.lib")
#define PORT 65432
int  main() 
{
	//初始化winsock2.DLL
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		cout << "加載winsock.dll失敗!" << endl;
		return 0;
	}
	//創(chuàng)建套接字
	SOCKET  sock_client; 
	if ((sock_client = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
	{
		cout << "創(chuàng)建套接字失?。″e(cuò)誤代碼:" << WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}
	//連接服務(wù)器
	sockaddr_in   addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);//綁定本機(jī)的環(huán)回地址
	int len = sizeof(sockaddr_in);
	if (connect(sock_client, (SOCKADDR*)&addr, len) == SOCKET_ERROR) {
		cout << "連接失??!錯(cuò)誤代碼:" << WSAGetLastError() << endl;
		return 0;
	}
	//實(shí)現(xiàn)交互部分,客戶(hù)端先接收后發(fā)送數(shù)據(jù)
	while (1)
	{
		//接收服務(wù)端的消息
		char msgbuffer[1000] = { 0 };
		int size = recv(sock_client, msgbuffer, sizeof(msgbuffer), 0);
		if (strcmp(msgbuffer, "end\0") == 0)
		{
			cout << "服務(wù)器端已經(jīng)關(guān)閉連接!" << endl;
			break;
		}
		if (size < 0)
		{
			cout << "接收信息失??!錯(cuò)誤代碼:" << WSAGetLastError() << endl;
			break;
		}
		else if (size == 0)
		{
			cout << "對(duì)方已經(jīng)關(guān)閉連接" << endl;
			break;
		}
		else cout << "The message from Server:" << msgbuffer << endl;

		//從鍵盤(pán)輸入一行文字發(fā)送給服務(wù)器
		msgbuffer[999] =  0 ;
		cout << "從鍵盤(pán)輸入發(fā)給服務(wù)器的信息:" << endl;
		cin.getline(msgbuffer, sizeof(msgbuffer));
		if (strcmp(msgbuffer, "end\0") == 0)
		{
			cout << "關(guān)閉連接!" << endl;
			break;
		}
		int ret = send(sock_client, msgbuffer, sizeof(msgbuffer), 0);
		if (ret == SOCKET_ERROR || ret == 0)
		{
			cout << "發(fā)送信息失??!錯(cuò)誤代碼:" << WSAGetLastError() << endl;
			break;
		}
		else cout << "信息發(fā)送成功!" << endl;
	}
	closesocket(sock_client);
	WSACleanup();
	return 0;
}

我們用建立連接時(shí)服務(wù)器端接收的客戶(hù)端套接字來(lái)唯一標(biāo)識(shí)該客戶(hù)端。
服務(wù)器端可以隨時(shí)接收客戶(hù)端的連接并與其進(jìn)行交互。

運(yùn)行實(shí)例

在這里插入圖片描述

實(shí)例展示了服務(wù)器端和兩個(gè)客戶(hù)端通信的運(yùn)行過(guò)程,包括正常交互、交互過(guò)程中另一服務(wù)器請(qǐng)求建立連接、服務(wù)器主動(dòng)斷開(kāi)連接和客戶(hù)端主動(dòng)斷開(kāi)連接等過(guò)程。

到此這篇關(guān)于C++多線(xiàn)程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶(hù)端通信 的文章就介紹到這了,更多相關(guān)C++ 服務(wù)器端和多個(gè)客戶(hù)端通信 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • OpenCV實(shí)現(xiàn)二值圖像的邊緣光滑處理

    OpenCV實(shí)現(xiàn)二值圖像的邊緣光滑處理

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)二值圖像的邊緣光滑處理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)算法

    C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)算法

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • STL容器之vector源碼詳細(xì)解讀

    STL容器之vector源碼詳細(xì)解讀

    這篇文章主要介紹了STL容器之vector源碼詳細(xì)解讀,vector的數(shù)據(jù)安排和array和類(lèi)似,它們的主要差別在于空間的運(yùn)用和靈活性,array是靜態(tài)空間,一旦配置了就不能改變,需要的朋友可以參考下
    2024-01-01
  • 鏈接庫(kù)動(dòng)態(tài)鏈接庫(kù)詳細(xì)介紹

    鏈接庫(kù)動(dòng)態(tài)鏈接庫(kù)詳細(xì)介紹

    靜態(tài)鏈接庫(kù).lib和動(dòng)態(tài)鏈接庫(kù).dll。其中動(dòng)態(tài)鏈接庫(kù)在被使用的時(shí)候,通常還提供一個(gè).lib,稱(chēng)為引入庫(kù),它主要提供被Dll導(dǎo)出的函數(shù)和符號(hào)名稱(chēng),使得鏈接的時(shí)候能夠找到dll中對(duì)應(yīng)的函數(shù)映射
    2012-11-11
  • C語(yǔ)言報(bào)錯(cuò)Use of Uninitialized Variable的原因及解決方案

    C語(yǔ)言報(bào)錯(cuò)Use of Uninitialized Variable的原因及解決方案

    Use of Uninitialized Variable是C語(yǔ)言中常見(jiàn)且危險(xiǎn)的錯(cuò)誤之一,它通常在程序試圖使用一個(gè)未初始化的變量時(shí)發(fā)生,本文將詳細(xì)介紹Use of Uninitialized Variable的產(chǎn)生原因,提供多種解決方案,并通過(guò)實(shí)例代碼演示如何有效避免和解決此類(lèi)錯(cuò)誤,需要的朋友可以參考下
    2024-06-06
  • C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)版通訊錄的代碼分享

    C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)版通訊錄的代碼分享

    這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的動(dòng)態(tài)版通訊錄,主要運(yùn)用了結(jié)構(gòu)體,一維數(shù)組,函數(shù),分支與循環(huán)語(yǔ)句等等知識(shí),需要的可以參考一下
    2023-01-01
  • QT+ffmpeg實(shí)現(xiàn)視頻解析的示例詳解

    QT+ffmpeg實(shí)現(xiàn)視頻解析的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用QT+ffmpeg實(shí)現(xiàn)視頻解析功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定幫助,需要的可以參考一下
    2022-09-09
  • C語(yǔ)言實(shí)現(xiàn)楊輝三角實(shí)例

    C語(yǔ)言實(shí)現(xiàn)楊輝三角實(shí)例

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)楊輝三角的方法,主要通過(guò)數(shù)組簡(jiǎn)單實(shí)現(xiàn),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-09-09
  • cocos2d-x學(xué)習(xí)筆記之CCLayer、CCLayerColor、CCLayerGradient、CCLayerMultiplex場(chǎng)景層介紹

    cocos2d-x學(xué)習(xí)筆記之CCLayer、CCLayerColor、CCLayerGradient、CCLayerMu

    這篇文章主要介紹了cocos2d-x學(xué)習(xí)筆記之CCLayer、CCLayerColor、CCLayerGradient、CCLayerMultiplex場(chǎng)景層介紹,需要的朋友可以參考下
    2014-09-09
  • C++?棧和隊(duì)列的實(shí)現(xiàn)超詳細(xì)解析

    C++?棧和隊(duì)列的實(shí)現(xiàn)超詳細(xì)解析

    棧和隊(duì)列,嚴(yán)格意義上來(lái)說(shuō),也屬于線(xiàn)性表,因?yàn)樗鼈円捕加糜诖鎯?chǔ)邏輯關(guān)系為?"一對(duì)一"?的數(shù)據(jù),但由于它們比較特殊,因此將其單獨(dú)作為一章,做重點(diǎn)講解
    2022-03-03

最新評(píng)論

和顺县| 湘潭县| 利川市| 金川县| 贺州市| 松江区| 孟州市| 东方市| 贵南县| 乌兰浩特市| 怀远县| 阳西县| 来凤县| 宁安市| 运城市| 江川县| 麻江县| 五大连池市| 四川省| 大方县| 义马市| 临颍县| 蒙自县| 洞口县| 墨脱县| 辽宁省| 竹北市| 百色市| 永康市| 曲麻莱县| 龙里县| 乐亭县| 聊城市| 肇源县| 罗城| 大渡口区| 读书| 旺苍县| 左贡县| 临海市| 太和县|