亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

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

服務(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)建套接字失??!錯誤代碼:" << 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 << "地址綁定失敗!錯誤代碼:" << WSAGetLastError() << endl;
		closesocket(sock_server);
		WSACleanup();
		return 0;
	}
	//將套接字設(shè)為監(jiān)聽狀態(tài)
	listen(sock_server, 0);
	
	//主線程循環(huán)接收客戶端的連接
	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)建線程 并且傳入與client通訊的套接字
			HANDLE hThread = CreateThread(NULL, 0, ThreadFun, (LPVOID)con, 0, NULL);
			CloseHandle(hThread); //關(guān)閉對線程的引用
		}
	}
	closesocket(sock_server);
	WSACleanup();
	return 0;
}
//線程通訊部分
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter) 
{
	//與客戶端通訊 先發(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);//給客戶端發(fā)送一段信息
		if (strcmp(msgbuffer, "end\0") == 0)
		{
			cout << "關(guān)閉和" << sock << "的連接!" << endl;
			return 0;
		}
		if (size == SOCKET_ERROR || size == 0)
		{
			cout << "發(fā)送信息失敗!錯誤代碼:" << WSAGetLastError() << endl;
			return 0;
		}
		else cout << "信息發(fā)送成功!" << endl;
		
		//接收客戶端數(shù)據(jù)
		msgbuffer[999] = { 0 };
		int ret = recv(sock, msgbuffer, sizeof(msgbuffer), 0);
		if(ret == SOCKET_ERROR || ret == 0)
		{
			cout << sock << "斷開了連接!" << endl;
			break;
		}
		else cout << sock << "  說: " << msgbuffer << endl;
	}
	return 0;
}

客戶端

#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)建套接字失??!錯誤代碼:" << 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 << "連接失??!錯誤代碼:" << WSAGetLastError() << endl;
		return 0;
	}
	//實現(xiàn)交互部分,客戶端先接收后發(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 << "接收信息失?。″e誤代碼:" << WSAGetLastError() << endl;
			break;
		}
		else if (size == 0)
		{
			cout << "對方已經(jīng)關(guān)閉連接" << endl;
			break;
		}
		else cout << "The message from Server:" << msgbuffer << endl;

		//從鍵盤輸入一行文字發(fā)送給服務(wù)器
		msgbuffer[999] =  0 ;
		cout << "從鍵盤輸入發(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ā)送信息失??!錯誤代碼:" << WSAGetLastError() << endl;
			break;
		}
		else cout << "信息發(fā)送成功!" << endl;
	}
	closesocket(sock_client);
	WSACleanup();
	return 0;
}

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

運行實例

在這里插入圖片描述

實例展示了服務(wù)器端和兩個客戶端通信的運行過程,包括正常交互、交互過程中另一服務(wù)器請求建立連接、服務(wù)器主動斷開連接和客戶端主動斷開連接等過程。

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

相關(guān)文章

  • C語言文件操作零基礎(chǔ)新手入門保姆級教程

    C語言文件操作零基礎(chǔ)新手入門保姆級教程

    在實際應(yīng)用中,我們往往需要對文件進(jìn)行操作,下面這篇文章主要給大家分享了關(guān)于C語言文件操作的零基礎(chǔ)新手入門保姆級教程,文中通過示例代碼以及圖片介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • C語言獲取消耗內(nèi)存的方法

    C語言獲取消耗內(nèi)存的方法

    這篇文章主要介紹了C語言獲取消耗內(nèi)存的方法,涉及C語言中malloc方法的使用技巧,非常簡單實用,需要的朋友可以參考下
    2015-07-07
  • C語言聯(lián)合體Union特點及運用全面講解教程

    C語言聯(lián)合體Union特點及運用全面講解教程

    這篇文章主要為大家介紹了C語言聯(lián)合體Union特點及運用的全面講解教程有需要深度朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-10-10
  • C語言程序設(shè)計50例(經(jīng)典收藏)

    C語言程序設(shè)計50例(經(jīng)典收藏)

    本篇文章是對C語言程序設(shè)計的50個小案例進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • C++中的RAII機(jī)制詳解

    C++中的RAII機(jī)制詳解

    這篇文章主要介紹了C++中的RAII機(jī)制詳解,RAII是Resource Acquisition Is Initialization的簡稱,是C++語言的一種管理資源、避免泄漏的慣用法,需要的朋友可以參考下
    2014-09-09
  • 快速學(xué)習(xí)C語言中for循環(huán)語句的基本使用方法

    快速學(xué)習(xí)C語言中for循環(huán)語句的基本使用方法

    這篇文章主要簡單介紹了C語言中for循環(huán)語句的基本使用方法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • c語言main函數(shù)使用及其參數(shù)介紹

    c語言main函數(shù)使用及其參數(shù)介紹

    這篇文章主要介紹了c語言main函數(shù)使用及其參數(shù)介紹,需要的朋友可以參考下
    2014-04-04
  • C++程序設(shè)計-五子棋

    C++程序設(shè)計-五子棋

    本文將以簡單的存儲結(jié)構(gòu)及簡單的運算,條件語句,分支語句,循環(huán)語句結(jié)合,帶來一個雙人對戰(zhàn)版五子棋,這是一個簡單的模型,實現(xiàn)了五子棋最最基本的功能。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • C語言入門篇--關(guān)鍵字static詳解

    C語言入門篇--關(guān)鍵字static詳解

    本篇文章是C語言系列基礎(chǔ)篇,C語言中,static是用來修飾變量和函數(shù):1.修飾局部變量–>靜態(tài)局部變量2.修飾全局變量–>靜態(tài)全局變量3.修飾函數(shù)–>靜態(tài)函數(shù)
    2021-08-08
  • 探討數(shù)組與字符串輸入的問題(C++版)

    探討數(shù)組與字符串輸入的問題(C++版)

    本文對C++數(shù)組與字符串輸入的問題進(jìn)行了探討,需要的朋友可以參考下
    2015-07-07

最新評論