建立能够持续请求的CS网络程序

本文详细介绍如何使用Socket API构建持续请求的CS(客户端-服务器)网络程序。包括服务端与客户端的代码实现,涵盖socket创建、连接、数据收发及循环处理等关键步骤。

1 建立能够持续请求的CS网络程序

1.1 概述

我们在上一次的代码基础,建立能够持续请求的CS网络程序:
在这里插入图片描述

用Socket API建立简易TCP服务端:

  1. 建立一个socket
  2. 绑定接受客户端连接的端口 bind
  3. 监听网络端口 listen
  4. 等待新客户端连接 accept
  5. 等待客户端请求 recv
  6. 向客户端返回请求的数据send
    //–循环5-6
  7. 关闭socket closesocket

用Socket API建立简易TCP客户端

  1. 建立一个socket
  2. 连接服务器 connect
  3. 向服务端发送请求 send
  4. 接收服务器返回的数据 recv
    //–循环3-4
  5. 关闭socket closesocket

1.2 服务端代码

server.cpp:

#include <iostream>

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <WinSock2.h>

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

using namespace std;

int main()
{
	WSADATA data;
	WORD version = MAKEWORD(2, 2);

	// 初始化Sokcet库
	WSAStartup(version, &data);

	//-- 用Socket API建立简易TCP服务端
	// 1 建立一个socket
	SOCKET _sock;
	_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (INVALID_SOCKET == _sock)
	{
		cout << "server : create socket error !" << endl;
		WSACleanup();
		return -1;
	}
	else
	{
		cout << "server : create socket success !" << endl;
	}
	
	// 2 bind 绑定用于接受客户端连接的网络端口
	sockaddr_in _sockaddr;
	_sockaddr.sin_family = AF_INET;
	_sockaddr.sin_port = htons(4567);
	_sockaddr.sin_addr.S_un.S_addr = ADDR_ANY; //inet_addr("127.0.0.1");
	
	int ret = bind(_sock, (sockaddr*)&_sockaddr, sizeof(sockaddr_in));
	if (SOCKET_ERROR == ret)
	{
		cout << "server : bind error!" << endl;
		WSACleanup();
		return -1;
	}
	else
	{
		cout << "server : bind success !" << endl;
	}


	// 3 listen 监听网络端口
	ret = listen(_sock, 5);
	if (SOCKET_ERROR == ret)
	{
		cout << "server : listen error !" << endl;
		WSACleanup();
		return -1;
	}
	else
	{
		cout << "server : listen success !" << endl;
	}


	sockaddr_in _sockaddr_in;
	int len = sizeof(sockaddr_in);

	// 4 accept 等待接受客户端连接
	SOCKET clientSock = accept(_sock, (sockaddr*)&_sockaddr_in, &len);

	if (INVALID_SOCKET == clientSock)
	{
		cout << "server : accept bad socket!" << endl;
	}
	else
	{
		cout << "server : new client join, IP : " << inet_ntoa(_sockaddr_in.sin_addr) << endl;
	}

	char buffer[] = "hello, client! I am server !";
	while (true)
	{
		// 5 从客户端接收数据并处理
		int recvLen = recv(clientSock, buffer, sizeof(buffer), 0);
		
		if (recvLen > 0)
		{
			cout << "recv : " << buffer << endl;

			if (0 == strcmp(buffer, "getName"))
			{
				char msgBuffer[] = "lemon";
				send(clientSock, msgBuffer, strlen(msgBuffer) + 1, 0);
			}
			else if (0 == strcmp(buffer, "getAge"))
			{
				char msgBuffer[] = "18";
				send(clientSock, msgBuffer, strlen(msgBuffer) + 1, 0);
			}
			else
			{
				char msgBuffer[] = "??? What are you want to ask?";
				send(clientSock, msgBuffer, strlen(msgBuffer) + 1, 0);
			}
		}
		else
		{
			cout << "client quit ..." << endl;
			break;
		}
	}
	
	// 6 关闭套节字closesocket
	closesocket(_sock);

	// 对Socket资源进行处理
	WSACleanup();

	getchar();

	return 0;
}

1.3 客户端代码

client.cpp:

#include <iostream>

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <WinSock2.h>

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

using namespace std;

int main()
{
	WSADATA data;
	WORD version = MAKEWORD(2, 2);

	// 初始化Sokcet库
	WSAStartup(version, &data);

	//------------
	//-- 用Socket API建立简易TCP客户端
	// 1 建立一个socket
	SOCKET _sock;
	_sock = socket(AF_INET, SOCK_STREAM, 0);	// 客户端的协议类型可以直接给0

	if (INVALID_SOCKET == _sock)
	{
		cout << "client : create socket error !" << endl;
		WSACleanup();
		return -1;
	}
	else
	{
		cout << "client : create socket success !" << endl;
	}

	// 2 连接服务器 connect
	sockaddr_in _sockaddr;
	_sockaddr.sin_family = AF_INET;
	_sockaddr.sin_port = htons(4567);
	_sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	int ret = connect(_sock, (sockaddr*)&_sockaddr, sizeof(sockaddr_in));

	if (SOCKET_ERROR == ret)
	{
		cout << "client : connect error !" << endl;
		WSACleanup();
		return -1;
	}
	else
	{
		cout << "client : connect success !" << endl;
	}

	char cmdBuffer[128] = { 0 };
	char recvBuffer[128] = { 0 };
	while (true)
	{
		// 3 接收用户输入并发送到服务器,然后接收回应
		cin >> cmdBuffer;

		if (0 == strcmp(cmdBuffer, "quit"))
		{
			break;
		}

		send(_sock, cmdBuffer, strlen(cmdBuffer) + 1, 0);

		int len = recv(_sock, recvBuffer, sizeof(recvBuffer), 0);
		if (len > 0)
		{
			cout << "client recv : " << recvBuffer << endl;
		}
		else
		{
			break;
		}
	}
	

	// 4 关闭套节字closesocket
	closesocket(_sock);

	// 对Socket资源进行处理
	WSACleanup();

	getchar();

	return 0;
}

参考资料:

  1. C++ 百万并发网络通信引擎架构与实现 (服务端、客户端、跨平台) Version 1.0
【复现】并_离网风光互补制氢合成氨系统容量-调度优化分析(Python代码实现)内容概要:本文围绕“并_离网风光互补制氢合成氨系统容量-调度优化分析”的主题,提供了基于Python代码实现的技术研究与复现方法。通过构建风能、太阳能互补的可再生能源系统模型,结合电解水制氢与合成氨工艺流程,对系统的容量配置与运行调度进行联合优化分析。利用优化算法求解系统在不同运行模式下的最优容量配比和调度策略,兼顾经济性、能效性和稳定性,适用于并网与离网两种场景。文中强调通过代码实践完成系统建模、约束设定、目标函数设计及求解过程,帮助读者掌握综合能源系统优化的核心方法。; 适合人群:具备一定Python编程基础和能源系统背景的研究生、科研人员及工程技术人员,尤其适合从事可再生能源、氢能、综合能源系统优化等相关领域的从业者;; 使用场景及目标:①用于教学与科研中对风光制氢合成氨系统的建模与优化训练;②支撑实际项目中对多能互补系统容量规划与调度策略的设计与验证;③帮助理解优化算法在能源系统中的应用逻辑与实现路径;; 阅读建议:建议读者结合文中提供的Python代码进行逐模块调试与运行,配合文档说明深入理解模型构建细节,重点关注目标函数设计、约束条件设置及求解器调用方式,同时可对比Matlab版本实现以拓宽工具应用视野。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值