C++下TCP网络通信TCP_Demo例子(VS)

下面是一个简单的tcp网络通信demo。

客户端:

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

#pragma comment(lib, ws2_32.lib)

#define IP "192.168.0.100"
#define PORT 5555

void Cleanup(SOCKET socket)
{
	closesocket(socket);
	WSACleanup();
}

int main()
{
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		std::cout << "加载winsock.dll失败!" << std::endl;
		return 0;
	}

	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (clientSocket == INVALID_SOCKET)
	{
		std::cout << "创建套接字失败!错误代码:!" << WSAGetLastError() << std::endl;
		Cleanup(clientSocket);
		return 0;
	}

	sockaddr_in serverAddress;
	serverAddress.sin_family = AF_INET;
	serverAddress.sin_port = htons(PORT);
	inet_pton(AF_INET, IP, &serverAddress.sin_addr);

	if (connect(clientSocket, reinterpret_cast<SOCKADDR*>(&serverAddress), sizeof(serverAddress)) == SOCKET_ERROR)
	{
		std::cout << "连接失败!错误代码:" << WSAGetLastError() << std::endl;
		Cleanup(clientSocket);
		return 0;
	}

	while (true)
	{
		std::string receivedMessage;
		char buffer[1000];
		int size = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (size <= 0)
		{
			if (size == 0)
				std::cout << "连接已关闭" << std::endl;
			else
				std::cout << "接收信息失败!错误代码:" << WSAGetLastError() << std::endl;
			break;
		}
		buffer[size] = '\0';
		receivedMessage = buffer;
		if (receivedMessage == "end")
		{
			std::cout << "服务器端已关闭连接!" << std::endl;
			break;
		}
		else
		{
			std::cout << "收到服务器消息:" << receivedMessage << std::endl;
		}

		std::string sendMessage;
		std::cout << "请输入要发送给服务器的消息:" << std::endl;
		std::getline(std::cin, sendMessage);

		if (sendMessage == "end")
		{
			std::cout << "关闭连接!" << std::endl;
			break;
		}

		int sentBytes = send(clientSocket, sendMessage.c_str(), static_cast<int>(sendMessage.length()), 0);
		if (sentBytes == SOCKET_ERROR || sentBytes == 0)
		{
			std::cout << "[发送信息失败] 错误代码: " << WSAGetLastError() << std::endl;
			break;
		}
		else
		{
			std::cout << " [信息发送成功] " << std::endl;
		}
	}

	Cleanup(clientSocket);
	return 0;
}

服务端:

#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <string>
#include <thread>

#pragma comment(lib, ws2_32.lib)
#define PORT 5555

void Cleanup(SOCKET socket)
{
	closesocket(socket);
	WSACleanup();
}
void HandleClientCommunication(SOCKET clientSocket)
{
	std::cout << "成功和" << clientSocket << "建立连接!" << std::endl;

	while (true)
	{
		char buffer[1000];
		std::cout << "服务器向" << clientSocket << "发送数据:" << std::endl;
		std::cin.getline(buffer, sizeof(buffer));

		std::string message = buffer;
		int size = send(clientSocket, message.c_str(), static_cast<int>(message.length()), 0);
		if (message == "end")
		{
			std::cout << "关闭和" << clientSocket << "的连接!" << std::endl;
			break;
		}
		else if (size == SOCKET_ERROR || size == 0)
		{
			std::cout << "[发送信息失败] 错误代码:" << WSAGetLastError() << std::endl;
			break;
		}
		else
		{
		std::cout << "[信息发送成功]" << std::endl;
		}
		memset(buffer, 0, sizeof(buffer));
		int receivedBytes = recv(clientSocket, buffer, sizeof(buffer), 0);
		if (receivedBytes == SOCKET_ERROR || receivedBytes == 0)
		{
			std::cout << clientSocket << "断开了连接!" << std::endl;
			break;
		}
		else
		{
			std::cout << clientSocket << "  说: "<< buffer << std::endl;
		}
	}
	closesocket(clientSocket);
}

int main()
{
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);
	if (WSAStartup(wVersionRequested, &wsaData) != 0)
	{
		std::cout <<  "加载winsock.dll失败!" << std::endl;
		return 0;
	}

	SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (serverSocket == INVALID_SOCKET)
	{
		std::cout << "创建套接字失败!错误代码:" << WSAGetLastError() << std::endl;
		WSACleanup();
		return 0;
	}

	sockaddr_in serverAddress;
	serverAddress.sin_family = AF_INET;
	serverAddress.sin_port = htons(PORT);
	inet_pton(AF_INET, "127.0.0.1", & serverAddress.sin_addr); 

	if (bind(serverSocket, reinterpret_cast<SOCKADDR*>(&serverAddress), sizeof(serverAddress)) == SOCKET_ERROR)
	{
		std::cout << "地址绑定失败!错误代码:" << WSAGetLastError() << std::endl;
		Cleanup(serverSocket);
		return 0;
	}

	if (listen(serverSocket, 0) == SOCKET_ERROR)
	{
		std::cout << "监听失败!错误代码:" << WSAGetLastError() << std::endl;
		Cleanup(serverSocket);
		return 0;

	}
	while (true)
	{
		sockaddr_in clientAddress;
		int clientAddressSize = sizeof(clientAddress);
		SOCKET clientSocket = accept(serverSocket, reinterpret_cast<SOCKADDR*>(&clientAddress), &clientAddressSize);
		if (clientSocket != INVALID_SOCKET)
		{
			std::thread clientThread(HandleClientCommunication, clientSocket);
			clientThread.detach(); // "分离线程,不等待线程结束"
		}
	}

	Cleanup(serverSocket);
	return 0;
}

注:需要在工程属性里,链接器-输入-附加依赖项手动添加对应的库

版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: TCP通信demo是指基于TCP协议实现的通信示例程序。TCP协议是一种可靠的、面向连接的传输层协议,它的主要特点是在通信双方建立连接后,可保证数据的完整性、有序性和可靠性,在数据传输过程中还可以进行流量控制和拥塞控制,因此在网络传输中得到广泛的应用。 在实现TCP通信demo的过程中,需要注意以下几个方面: 1.连接建立:在TCP协议中,连接的建立需要经过三次握手的过程,即发送SYN报文、收到SYN+ACK报文、发送ACK报文。因此,在demo中需要实现连接建立的过程,并保证建立成功后才能进行数据传输。 2.数据传输:在TCP协议中,数据是分段传输的,每个数据包都有一个序号和确认序号。因此,在demo中需要实现数据的分段传输和接收,并进行序号和确认序号的匹配。 3.流量控制和拥塞控制:在TCP协议中,为了避免网络拥塞导致数据传输的失败,需要进行流量控制和拥塞控制。在demo中可以实现简单的流量控制和拥塞控制,例如设置最大传输速度和传输窗口大小。 总之,TCP通信demo是一个重要的网络编程示例程序,它可以帮助我们了解TCP协议的工作原理和应用场景,提高我们的网络编程技能和调试能力。 ### 回答2: TCP通信是计算机网络中重要的传输层协议,用于在两个设备之间提供可靠的数据传输。编写一个TCP通信demo是帮助理解TCP协议及其应用的一种方式。以下是一份简单的TCP通信demo的说明: 该demo包含两个客户端和一个服务器端。客户端向服务器发送数据,服务器接收数据并返回响应。客户端与服务器之间通过一个连接在TCP协议下进行通信。客户端通过套接字socket()函数创建一个套接字,并使用connect()函数连接到服务器。服务器端也使用socket()函数创建套接字,并调用bind()函数绑定端口号,然后使用listen()函数开启监听模式。当客户端连接到服务器后,服务器端使用accept()函数接受连接请求,然后使用recv()函数接收客户端发送的数据,并使用send()函数发送响应。客户端通过send()函数发送数据,并使用recv()函数接收服务器端的响应。 在编写TCP通信demo时需要注意以下事项: 1. 客户端和服务器端需使用相同的协议族(如IPv4或IPv6)和协议类型(如TCP或UDP)。 2. 确定通信过程中所需的数据格式,并在客户端和服务器端之间使用相同的格式传输数据。 3. 需要注意TCP协议中的粘包问题,即多个数据包可能会被合并在一起,需要使用固定长度或特殊分隔符来区分数据包。 4. 在处理网络异常情况时,应考虑超时、连接失效等问题,并进行相应的异常处理。 通过编写TCP通信demo,可以更加深入理解TCP协议的工作原理和应用,加强网络编程的基本功。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值