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

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

猜你喜欢

转载自blog.csdn.net/SlowIsFastLemon/article/details/106386211