欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?Socket實(shí)現(xiàn)TCP與UDP網(wǎng)絡(luò)編程

 更新時(shí)間:2022年01月20日 09:31:28   作者:cpp_learners  
本文主要介紹了C++?Socket實(shí)現(xiàn)TCP與UDP網(wǎng)絡(luò)編程,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

socket編程分為TCP和UDP兩個模塊,其中TCP是可靠的、安全的,常用于發(fā)送文件等,而UDP是不可靠的、不安全的,常用作視頻通話等。

如下圖:

在這里插入圖片描述

頭文件與庫:

#include <WinSock2.h>

#pragma comment(lib, "ws2_32.lib")

準(zhǔn)備工作:

創(chuàng)建工程后,首先右鍵工程,選擇屬性

在這里插入圖片描述

然后選擇 C/C++ - 預(yù)處理器 - 預(yù)處理器定義

在這里插入圖片描述

將字符串 _WINSOCK_DEPRECATED_NO_WARNINGS 添加到里面去,點(diǎn)擊應(yīng)用即可!

TCP

連接過程圖:

在這里插入圖片描述

創(chuàng)建tcp服務(wù)器和客戶端都是按照上圖的步驟來操作的!

1). 服務(wù)器

初始化套接字庫
對應(yīng)圖中socket()

WORD wVersion;
WSADATA wsaData;
int err;

// 設(shè)置版本,可以理解為1.1
wVersion = MAKEWORD(1, 1);	// 例:MAKEWORD(a, b) --> b | a << 8 將a左移8位變成高位與b合并起來

// 啟動
err = WSAStartup(wVersion, &wsaData);

創(chuàng)建tcp套接字
對應(yīng)圖中socket()

// AF_INET:ipv4   AF_INET6:ipv6
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);

綁定到本機(jī)
對應(yīng)圖中bind()

// 準(zhǔn)備綁定信息
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);	// 設(shè)置綁定網(wǎng)卡
addrSrv.sin_family = AF_INET;		// 設(shè)置綁定網(wǎng)絡(luò)模式
addrSrv.sin_port = htons(6000);		// 設(shè)置綁定端口
// hton: host to network  x86:小端    網(wǎng)絡(luò)傳輸:htons大端

// 綁定到本機(jī)
int retVal = bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

監(jiān)聽
對應(yīng)圖中listen()

// 同時(shí)能接收10個鏈接,主要看參數(shù)二的設(shè)置個數(shù)
listen(sockSrv, 10);

接收連接請求,返回針對客戶端的套接字
對應(yīng)圖中accept()

SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrCli, &len);

發(fā)送數(shù)據(jù)
對應(yīng)圖中write()

sprintf_s(sendBuf, "hello client!\n");
int iSend = send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);

接收數(shù)據(jù)
對應(yīng)圖中read()

recv(sockConn, recvBuf, 100, 0);

關(guān)閉套接字
對應(yīng)圖中close()

closesocket(sockConn);

清理套接字庫

WSACleanup();

具體實(shí)現(xiàn)代碼

#include <iostream>
#include <stdio.h>
#include <WinSock2.h>

#pragma comment(lib, "ws2_32.lib")


int main(void) {

	// 1.初始化套接字庫
	WORD wVersion;
	WSADATA wsaData;
	int err;

	// 設(shè)置版本,可以理解為1.1
	wVersion = MAKEWORD(1, 1);	// 例:MAKEWORD(a, b) --> b | a << 8 將a左移8位變成高位與b合并起來

	// 啟動
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0) {
		return err;
	}
	// 檢查:網(wǎng)絡(luò)低位不等于1 || 網(wǎng)絡(luò)高位不等于1
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
		// 清理套接字庫
		WSACleanup();
		return -1;
	}

	// 2.創(chuàng)建tcp套接字		// AF_INET:ipv4   AF_INET6:ipv6
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);

	// 準(zhǔn)備綁定信息
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);	// 設(shè)置綁定網(wǎng)卡
	addrSrv.sin_family = AF_INET;		// 設(shè)置綁定網(wǎng)絡(luò)模式
	addrSrv.sin_port = htons(6000);		// 設(shè)置綁定端口
	// hton: host to network  x86:小端    網(wǎng)絡(luò)傳輸:htons大端

	// 3.綁定到本機(jī)
	int retVal = bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
	if (retVal == SOCKET_ERROR) {
		printf("Failed bind:%d\n", WSAGetLastError());
		return -1;
	}

	// 4.監(jiān)聽,同時(shí)能接收10個鏈接
	if (listen(sockSrv, 10) == SOCKET_ERROR) {
		printf("Listen failed:%d", WSAGetLastError());
		return -1;
	}

	std::cout << "Server start at port: 6000" << std::endl;

	SOCKADDR_IN addrCli;
	int len = sizeof(SOCKADDR);

	char recvBuf[100];
	char sendBuf[100];
	while (1) {
		// 5.接收連接請求,返回針對客戶端的套接字
		SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrCli, &len);
		if (sockConn == SOCKET_ERROR) {
			//printf("Accept failed:%d", WSAGetLastError());
			std::cout << "Accept failed: " << WSAGetLastError() << std::endl;
			break;
		}

		//printf("Accept client IP:[%s]\n", inet_ntoa(addrCli.sin_addr));
		std::cout << "Accept client IP: " << inet_ntoa(addrCli.sin_addr) << std::endl;

		// 6.發(fā)送數(shù)據(jù)
		sprintf_s(sendBuf, "hello client!\n");
		int iSend = send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);
		if (iSend == SOCKET_ERROR) {
			std::cout << "send failed!\n";
			break;
		}

		// 7.接收數(shù)據(jù)
		recv(sockConn, recvBuf, 100, 0);
		std::cout << recvBuf << std::endl;

		// 關(guān)閉套接字
		closesocket(sockConn);
	}


	// 8.關(guān)閉套接字
	closesocket(sockSrv);

	// 9.清理套接字庫
	WSACleanup();

	return 0;
}

2). 客戶端

初始化套接字庫
對應(yīng)圖中socket()

WORD wVersion;
WSADATA wsaData;
int err;

// 可以理解為1.1
wVersion = MAKEWORD(1, 1);	// 例:MAKEWORD(a, b) --> b | a << 8 將a左移8位變成高位與b合并起來

// 啟動
err = WSAStartup(wVersion, &wsaData);

// 創(chuàng)建TCP套接字
SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);

連接服務(wù)器
對應(yīng)圖中connect()

// 連接服務(wù)器
int err_log = connect(sockCli, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

發(fā)送數(shù)據(jù)到服務(wù)器
對應(yīng)圖中write()

char sendBuf[] = "你好,服務(wù)器,我是客戶端!";
send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);

接收服務(wù)器的數(shù)據(jù)
對應(yīng)圖中read()

char recvBuf[100];
recv(sockCli, recvBuf, sizeof(recvBuf), 0);

關(guān)閉套接字并清除套接字庫
對應(yīng)圖中close()

closesocket(sockCli);
WSACleanup();

具體實(shí)現(xiàn)代碼

#include <iostream>
#include <WinSock2.h>


#pragma comment(lib, "ws2_32.lib")


int main(void) {

	// 1.初始化套接字庫
	WORD wVersion;
	WSADATA wsaData;
	int err;

	// 可以理解為1.1
	wVersion = MAKEWORD(1, 1);	// 例:MAKEWORD(a, b) --> b | a << 8 將a左移8位變成高位與b合并起來

	// 啟動
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0) {
		return err;
	}
	// 檢查:網(wǎng)絡(luò)地位不等于1 || 網(wǎng)絡(luò)高位不等于1
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
		// 清理套接字庫
		WSACleanup();
		return -1;
	}

	// 創(chuàng)建TCP套接字
	SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");	// 服務(wù)器地址
	addrSrv.sin_port = htons(6000);		// 端口號
	addrSrv.sin_family = AF_INET;		// 地址類型(ipv4)

	// 2.連接服務(wù)器
	int err_log = connect(sockCli, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
	if (err_log == 0) {
		printf("連接服務(wù)器成功!\n");
	
	} else {
		printf("連接服務(wù)器失??!\n");
		return -1;
	}


	char recvBuf[100];
	char sendBuf[] = "你好,服務(wù)器,我是客戶端!";
	// 3.發(fā)送數(shù)據(jù)到服務(wù)器
	send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);

	// 4.接收服務(wù)器的數(shù)據(jù)
	recv(sockCli, recvBuf, sizeof(recvBuf), 0);
	std::cout << recvBuf << std::endl;


	// 5.關(guān)閉套接字并清除套接字庫
	closesocket(sockCli);
	WSACleanup();

	system("pause");

	return 0;
}

運(yùn)行效果:

在這里插入圖片描述

3). TCP聊天小項(xiàng)目

下面是根據(jù)上面的代碼修改的一個聊天小項(xiàng)目(使用到了多線程)

只有一個服務(wù)器,服務(wù)器一直開啟等待客戶端連接;
客戶都安可以開啟多個,且可以一直連續(xù)的與服務(wù)器進(jìn)行發(fā)送接收消息;
服務(wù)器給客戶端發(fā)送數(shù)據(jù),得通過1 - 9來區(qū)分到底給那個客戶端發(fā)送消息,例如給第二個客戶端發(fā)送消息:2你好,客戶端
客戶端那邊接收到的數(shù)據(jù)是:你好,客戶端

服務(wù)器代碼

#include <iostream>
#include <WinSock2.h>
#include <stdio.h>
#include <Windows.h>
#include <process.h>
#include <vector>
#include <conio.h>
#include <string.h>
#include <string>

#pragma comment(lib, "ws2_32.lib")


SOCKET sockSrv;
std::vector<SOCKET> vec_sockConn;
std::vector<SOCKADDR_IN> vec_sockaddr_in;
std::vector<int> vec_sockIndex;


// 這個結(jié)構(gòu)體用作線程參數(shù)
typedef struct SERVER_CLIENT {
	SOCKET server;
	SOCKADDR_IN client;
	int clientIndex;
}SC;



// 判斷有沒有斷開連接
bool IsSocketClosed(SOCKET clientSocket) {
	bool ret = false;
	HANDLE closeEvent = WSACreateEvent();
	WSAEventSelect(clientSocket, closeEvent, FD_CLOSE);

	DWORD dwRet = WaitForSingleObject(closeEvent, 0);

	if (dwRet == WSA_WAIT_EVENT_0)
		ret = true;
	else if (dwRet == WSA_WAIT_TIMEOUT)
		ret = false;

	WSACloseEvent(closeEvent);
	return ret;
}


// 接收請求
unsigned int WINAPI  ThreadAccept(LPVOID p) {
	static int i = 0;
	while (1) {
		SOCKADDR_IN addrCli;
		int len = sizeof(SOCKADDR);

		// 5.接收連接請求,返回針對客戶端的套接字
		SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrCli, &len);
		if (sockConn == SOCKET_ERROR) {
			printf("Accept failed:%d", WSAGetLastError());
		}

		// 存儲當(dāng)前服務(wù)器與客戶端 連接綁定的socket
		vec_sockIndex.emplace_back(i++);
		vec_sockaddr_in.emplace_back(addrCli);
		vec_sockConn.emplace_back(sockConn);

		printf("\033[0;%d;40m客戶端[%d]上線\033[0m\n", 31, i);
	}
	

	return 0;
}

unsigned int WINAPI  _ThreadRecv(LPVOID p) {
	char recvBuf[100];
	memset(recvBuf, 0, 100);

	SC _sc = *(SC *)p;
	
	while (1) {
		Sleep(20);

		if (IsSocketClosed(_sc.server) == true) {
			printf("客戶端 [%d] 斷開連接!\n", _sc.clientIndex + 1);
			break;
		}


		// 接收數(shù)據(jù)
		recv(_sc.server, recvBuf, 100, 0);
		if (strlen(recvBuf) == 0) {
			continue;
		}
	
		printf("接收到客戶端 [%d] 的消息:%s\n", _sc.clientIndex + 1, recvBuf);
		memset(recvBuf, 0, 100);
	}
	return 0;
}

unsigned int WINAPI  ThreadRecv(LPVOID p) {

	static int index = 0;

	while (1) {
		// 還沒有客戶端與服務(wù)器進(jìn)行連接
		if (vec_sockConn.size() == 0) {
			continue;
		}

		// 接收線程已經(jīng)開啟和客戶端個數(shù)相等
		if (vec_sockConn.size()  == index) {
			continue;
		}

		SC sc;
		sc.server = vec_sockConn.at(index);
		sc.client = vec_sockaddr_in.at(index);
		sc.clientIndex = vec_sockIndex.at(index);

		HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, _ThreadRecv, (void *)&sc, 0, NULL);

		index++;
		Sleep(20);
	}

	return 0;
}



int main(void) {

	// 1.初始化套接字庫
	WORD wVersion;
	WSADATA wsaData;
	int err;

	// 設(shè)置版本,可以理解為1.1
	wVersion = MAKEWORD(1, 1);	// 例:MAKEWORD(a, b) --> b | a << 8 將a左移8位變成高位與b合并起來

	// 啟動
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0) {
		return err;
	}
	// 檢查:網(wǎng)絡(luò)低位不等于1 || 網(wǎng)絡(luò)高位不等于1
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
		// 清理套接字庫
		WSACleanup();
		return -1;
	}

	// 2.創(chuàng)建tcp套接字		// AF_INET:ipv4   AF_INET6:ipv6
	sockSrv = socket(AF_INET, SOCK_STREAM, 0);

	// 準(zhǔn)備綁定信息
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);	// 設(shè)置綁定網(wǎng)卡
	addrSrv.sin_family = AF_INET;		// 設(shè)置綁定網(wǎng)絡(luò)模式
	addrSrv.sin_port = htons(6000);		// 設(shè)置綁定端口
	// hton: host to network  x86:小端    網(wǎng)絡(luò)傳輸:htons大端

	// 3.綁定到本機(jī)
	int retVal = bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
	if (retVal == SOCKET_ERROR) {
		printf("Failed bind:%d\n", WSAGetLastError());
		return -1;
	}

	// 4.監(jiān)聽,同時(shí)接收10個鏈接
	if (listen(sockSrv, 10) == SOCKET_ERROR) {
		printf("Listen failed:%d", WSAGetLastError());
		return -1;
	}

	std::cout << "Server start at port: 6000" << std::endl;


	// 線程句柄				// 創(chuàng)建線程
	HANDLE hThread_1 = (HANDLE)_beginthreadex(NULL, 0, ThreadAccept, NULL, 0, NULL);
	HANDLE hThread_2 = (HANDLE)_beginthreadex(NULL, 0, ThreadRecv, NULL, 0, NULL);


	//uiInit();
	//editPrint(0, ">");


	char sendBuf[100];
	while (1) {

		//printf("請輸入發(fā)送內(nèi)容:");

		char c = getchar();				// 輸入發(fā)送給誰
		scanf_s("%s", sendBuf, 100);	// 輸入發(fā)送的內(nèi)容

		if (strlen(sendBuf) == 0) {
			printf("輸入內(nèi)容為空或者超長!\n");
		}

		// 1 至 9
		if (c < '1' || c > '9' || vec_sockConn.size() == 0 || c - '0' >= vec_sockConn.size() + 1) {
			while ((c = getchar()) != '\n');	// 清空輸入緩沖區(qū)
			memset(sendBuf, 0, 100);
			printf("輸入內(nèi)容不符合規(guī)則!\n");
			continue;
		}



		// 發(fā)送數(shù)據(jù)
		int index = --c - '0';	// 因?yàn)橄聵?biāo)是從零開始的,所以c要先自減
		int iSend = send(vec_sockConn.at(index) , sendBuf, strlen(sendBuf) + 1, 0);
		if (iSend == SOCKET_ERROR) {
			std::cout << "send failed!\n";
			break;
		}


		memset(sendBuf, 0, 100);
		while ((c = getchar()) != '\n');	// 清空輸入緩沖區(qū)
	}

	// 關(guān)閉套接字
	std::vector<SOCKET>::iterator it = vec_sockConn.begin();
	for (; it != vec_sockConn.end(); it++) {
		closesocket((SOCKET)(*it));
	}


	WaitForSingleObject(hThread_1, INFINITE);
	WaitForSingleObject(hThread_2, INFINITE);

	CloseHandle(hThread_1);
	CloseHandle(hThread_2);

	// 7.關(guān)閉套接字
	closesocket(sockSrv);

	// 8.清理套接字庫
	WSACleanup();

	return 0;
}

客戶端

#include <iostream>
#include <WinSock2.h>
#include <process.h>
#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")

SOCKET sockCli;


// 判斷有沒有斷開連接
bool IsSocketClosed(SOCKET clientSocket) {
	bool ret = false;
	HANDLE closeEvent = WSACreateEvent();
	WSAEventSelect(clientSocket, closeEvent, FD_CLOSE);

	DWORD dwRet = WaitForSingleObject(closeEvent, 0);

	if (dwRet == WSA_WAIT_EVENT_0)
		ret = true;
	else if (dwRet == WSA_WAIT_TIMEOUT)
		ret = false;

	WSACloseEvent(closeEvent);
	return ret;
}


unsigned int WINAPI  ThreadRecv(LPVOID p) {
	char recvBuf[100];
	memset(recvBuf, 0, 100);

	while (1) {
		Sleep(20);

		if (IsSocketClosed(sockCli) == true) {
			printf("服務(wù)器 斷開連接!\n");
			break;
		}

		// 接收服務(wù)器的數(shù)據(jù)
		recv(sockCli, recvBuf, sizeof(recvBuf), 0);
		if (strlen(recvBuf) == 0) continue;

		std::cout << recvBuf << std::endl;
		memset(recvBuf, 0, 100);
	}


	return 0;
}

int main(void) {

	// 1.初始化套接字庫
	WORD wVersion;
	WSADATA wsaData;
	int err;

	// 可以理解為1.1
	wVersion = MAKEWORD(1, 1);	// 例:MAKEWORD(a, b) --> b | a << 8 將a左移8位變成高位與b合并起來

	// 啟動
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0) {
		return err;
	}
	// 檢查:網(wǎng)絡(luò)地位不等于1 || 網(wǎng)絡(luò)高位不等于1
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
		// 清理套接字庫
		WSACleanup();
		return -1;
	}

	// 創(chuàng)建TCP套接字
	sockCli = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");	// 服務(wù)器地址
	addrSrv.sin_port = htons(6000);		// 端口號
	addrSrv.sin_family = AF_INET;		// 地址類型(ipv4)

	// 連接服務(wù)器
	int err_log = connect(sockCli, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
	if (err_log == 0) {
		printf("連接服務(wù)器成功!\n");

	} else {
		printf("連接服務(wù)器失??!\n");
		return -1;
	}

	// 線程句柄				// 創(chuàng)建線程
	HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadRecv, NULL, 0, NULL);


	char sendBuf[100];
	while (1) {

		//printf("請輸入發(fā)送內(nèi)容:");
		scanf_s("%s", sendBuf, 100);

		// 發(fā)送數(shù)據(jù)到服務(wù)器
		send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);

		memset(sendBuf, 0, 100);
		char c;
		while ((c = getchar()) != '\n');
	}


	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);


	// 關(guān)閉套接字并清除套接字庫
	closesocket(sockCli);
	WSACleanup();

	system("pause");

	return 0;
}

運(yùn)行效果:

在這里插入圖片描述

UDP

UDP就比較簡單了,步驟比tcp要少一些。

連接過程圖:

在這里插入圖片描述

1). 服務(wù)器

初始化套接字庫

WORD wVersion;
WSADATA wsaData;
int err;

wVersion = MAKEWORD(1, 1);

創(chuàng)建套接字

SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);

綁定

// SOCKADDR_IN addrSrv; 省略了定義和賦值
bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

接收數(shù)據(jù)

char recvBuf[100];
recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);

發(fā)送數(shù)據(jù)

char sendBuf[] = "hello Client,I'm Server!\n";
sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrCli, len);

關(guān)閉

closesocket(sockSrv);
WSACleanup();

具體實(shí)現(xiàn)代碼

#include <WinSock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

int main(void) {
	// 初始化套接字庫
	WORD wVersion;
	WSADATA wsaData;
	int err;

	wVersion = MAKEWORD(1, 1);
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0) {
		return err;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
		WSACleanup();
		return -1;
	}

	// 創(chuàng)建套接字
	SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6001);

	// 綁定到本機(jī)6001端口
	bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

	// 接收請求,處理請求
	SOCKADDR_IN addrCli;
	int len = sizeof(SOCKADDR);

	char sendBuf[] = "hello Client,I'm Server!\n";
	char recvBuf[100];

	std::cout << "start UDP server with port 6001" << std::endl;
	while (1) {
		// 接收數(shù)據(jù)
		recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);
		std::cout << "Recv:" << recvBuf << std::endl;

		// 發(fā)送數(shù)據(jù)
		sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrCli, len);
		std::cout << "Send:" << sendBuf << std::endl;
	}

	closesocket(sockSrv);
	WSACleanup();

	return 0;
}

2). 客戶端

初始化套接字庫

WORD wVersion;
WSADATA wsaData;
int err;

wVersion = MAKEWORD(1, 1);

創(chuàng)建UDP套接字

SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;

接收數(shù)據(jù)

char recvBuf[100];
recvfrom(sockCli, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);

發(fā)送數(shù)據(jù)

char sendBuf[] = "hello Client,I'm Server!\n";
sendto(sockCli, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrSrv, len);

關(guān)閉

closesocket(sockSrv);
WSACleanup();

具體實(shí)現(xiàn)代碼

#include <WinSock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")


int main(void) {

	// 初始化套接字庫
	WORD wVersion;
	WSADATA wsaData;
	int err;

	wVersion = MAKEWORD(1, 1);
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0) {
		return err;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
		WSACleanup();
		return -1;
	}

	// 創(chuàng)建UDP套接字
	SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6001);

	SOCKADDR_IN addrCli;
	int len = sizeof(SOCKADDR);

	char sendBuf[] = "hello, I'm Client!\n";
	char recvBuf[100];

	std::cout << "send to Server: " << sendBuf << std::endl;
	sendto(sockCli, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrSrv, len);

	recvfrom(sockCli, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);
	std::cout << "recv from: " << recvBuf << std::endl;


	closesocket(sockCli);
	WSACleanup();

	system("pause");
	return 0;
}

運(yùn)行效果:

在這里插入圖片描述

總結(jié)

socket的具體細(xì)節(jié)用法我不太清楚,現(xiàn)階段也只是熟悉TCP的一些簡單操作,UDP的話也還不是太懂,不懂的是不知道在具體項(xiàng)目中該如何進(jìn)行使用它們。
那個TCP的小項(xiàng)目也只是自己琢磨搞出來的,不知掉具體項(xiàng)目會不會這樣去寫!

到此這篇關(guān)于C++ Socket實(shí)現(xiàn)TCP與UDP網(wǎng)絡(luò)編程的文章就介紹到這了,更多相關(guān)C++ Socket實(shí)現(xiàn)TCP與UDP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++淺析類與對象基礎(chǔ)點(diǎn)

    C++淺析類與對象基礎(chǔ)點(diǎn)

    類和對象是兩種以計(jì)算機(jī)為載體的計(jì)算機(jī)語言的合稱。對象是對客觀事物的抽象,類是對對象的抽象。類是一種抽象的數(shù)據(jù)類型;變量就是可以變化的量,存儲在內(nèi)存中—個可以擁有在某個范圍內(nèi)的可變存儲區(qū)域
    2022-07-07
  • C++如何比較兩個字符串或string是否相等strcmp()和compare()

    C++如何比較兩個字符串或string是否相等strcmp()和compare()

    這篇文章主要介紹了C++如何比較兩個字符串或string是否相等strcmp()和compare()問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • C語言 function recursion函數(shù)遞歸詳解

    C語言 function recursion函數(shù)遞歸詳解

    遞歸指的是在函數(shù)的定義中使用函數(shù)自身的方法,舉個例子: 從前有座山,山里有座廟,廟里有個老和尚,正在給小和尚講故事呢!故事是什么呢?"從前有座山,山里有座廟,廟里有個老和尚,正在給小和尚講故事呢!故事是什么呢?"從前有座山,山里有座廟,循環(huán)下去
    2021-10-10
  • C++調(diào)用libcurl開源庫實(shí)現(xiàn)郵件的發(fā)送功能流程詳解

    C++調(diào)用libcurl開源庫實(shí)現(xiàn)郵件的發(fā)送功能流程詳解

    libcurl是一個免費(fèi)開源的網(wǎng)絡(luò)傳輸庫,支持ftp、ftps、tftp,http、https、telnet、ldap、pop3、smtp等多種協(xié)議,接下來讓我們一起來了解吧
    2021-11-11
  • OpenCV視頻流C++多線程處理方法詳細(xì)分析

    OpenCV視頻流C++多線程處理方法詳細(xì)分析

    為OpenCV是搞計(jì)算機(jī)視覺必須要掌握的基礎(chǔ),這篇文章主要給大家介紹了關(guān)于OpenCV視頻流多線程處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • Qt+OpenCV實(shí)現(xiàn)目標(biāo)檢測詳解

    Qt+OpenCV實(shí)現(xiàn)目標(biāo)檢測詳解

    這篇文章主要介紹了如何利用Qt和OpenCV中自帶xml文件實(shí)現(xiàn)目標(biāo)檢測,文中的實(shí)現(xiàn)過程講解詳細(xì),感興趣的小伙伴可以動手試一試
    2022-03-03
  • C++拷貝構(gòu)造函數(shù)(深拷貝與淺拷貝)詳解

    C++拷貝構(gòu)造函數(shù)(深拷貝與淺拷貝)詳解

    深拷貝和淺拷貝可以簡單理解為:如果一個類擁有資源,當(dāng)這個類的對象發(fā)生復(fù)制過程的時(shí)候,資源重新分配,這個過程就是深拷貝,反之,沒有重新分配資源,就是淺拷貝
    2013-09-09
  • C語言創(chuàng)建動態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下)

    C語言創(chuàng)建動態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下)

    本篇文章主要介紹了C語言創(chuàng)建動態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-11-11
  • C++ 網(wǎng)絡(luò)編程 總結(jié)

    C++ 網(wǎng)絡(luò)編程 總結(jié)

    這篇文章主要介紹了C++ 網(wǎng)絡(luò)編程的一些詳細(xì)相關(guān)內(nèi)容,有需要的小伙伴可以參考下。
    2015-06-06
  • 用C語言實(shí)現(xiàn)二分查找算法

    用C語言實(shí)現(xiàn)二分查找算法

    大家好,本篇文章主要講的是c語言實(shí)現(xiàn)二分查找法,感性的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01

最新評論