windows下实现tcp/ip通信

1.创建(在visual studio)

点击创建新项目

双击空项目

改好项目名称和位置后,点击创建

右键解决方案->选择添加->新建项目

此时会生成两个项目,右键重命名,一个改为ClientSocket,一个改为ServerSocket

在ClientSocket中创建Client.cpp  在ServerSocket中创建Server.cpp

点击源文件->添加->新建项   

链接库  ClientSocket和ServerSocket这两个项目都要进行

右键项目->属性

链接器->输入->点下拉列表->点编辑

输入

ws2_32.lib

一直点确定退出就行

(一些头文件是windows自带的,但是使用 Windows Sockets 2 (Winsock) 编程接口时,需要链接 ws2_32.lib 库)

2.服务端

Server.cpp

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

#pragma comment(lib, "ws2_32.lib")
#define PORT 65432

void Cleanup(SOCKET socket)
{
	closesocket(socket);//关闭套接字
	WSACleanup(); //清理WSA的资源
}

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;
}

3.客户端

Client.cpp

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

#pragma comment(lib, "ws2_32.lib")
#define PORT 65432

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, "127.0.0.1", &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;
}

取消SDL检查()

右键ClientSocket项目->属性

C/C++->常规->SDL检查->点击下拉列表->选否

再点确定,退出

(使用一些c++中目前版本不太支持的语句时,sdl检查就会报错)

4.编译

f5运行或者点开始调试

项目->在资源管理打开文件夹  

找到Debug文件夹,有的会发现只生成了客户端或者服务器的一个.exe文件

这时候说明只编译了一个,另一个没有编译

右键没有编译的项目->设为启动项

f5再编译一次,打开上面的Debug文件夹,就会发现都有了

这时候要打开两个终端运行,复制前面Debug的路径

win+R 输入cmd打开命令窗口

cd Debug的路径(粘贴刚才复制的路径)

ServerSocket.exe

再打开一个终端

cd Debug的路径(粘贴刚才复制的路径)

ClientSocket.exe

两边成功通信,建立连接

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值