提交 68c24ad4 编写于 作者: X xuchi

IOCP网络模型支持获取新加入客户端IP信息

上级 60bc21cd
......@@ -311,7 +311,20 @@ namespace doyou {
&_lpfnAcceptEx, sizeof(_lpfnAcceptEx), // 注册函数指针
&dwBytes, NULL, NULL);
if (iResult == SOCKET_ERROR) {
CELLLog_PError("WSAIoctl failed.");
CELLLog_PError("WSAIoctl failed to _lpfnAcceptEx, err: %u", WSAGetLastError()); // 记录错误日志
return false;
}
// 加载函数指针到内存-_getAcceptExAddrs
GUID GuidAcceptExAddrs = WSAID_GETACCEPTEXSOCKADDRS;
dwBytes = 0;
// Load the _getAcceptExAddrs function into memory using WSAIoctl.
iResult = WSAIoctl(ListenSocket, SIO_GET_EXTENSION_FUNCTION_POINTER,
&GuidAcceptExAddrs, sizeof(GuidAcceptExAddrs),
&_getAcceptExAddrs, sizeof(_getAcceptExAddrs), // 注册函数指针
&dwBytes, NULL, NULL);
if (iResult == SOCKET_ERROR) {
CELLLog_PError("WSAIoctl failed to _getAcceptExAddrs, err: %u", WSAGetLastError());
return false;
}
......@@ -320,9 +333,43 @@ namespace doyou {
return true;
}
// 获取新加入客户端本端和远端IP信息
char* GetAcceptExAddrsIpv4(IO_DATA_BASE* pIO_DATA)
{
if (NULL == _getAcceptExAddrs) { // 指针使用前应判空校验
CELLLog_Error("NULL == _getAcceptExAddrs");
return NULL;
}
int nLocalLen = 0;
int nRemoteLen = 0;
sockaddr_in* pLocalAddr_in = NULL;
sockaddr_in* pRemoteAddr_in = NULL;
// 获取远程和本地网络地址
_getAcceptExAddrs( // 当前函数作用:将para1存储的新加入客户端IP信息进行解析
pIO_DATA->wsabuff.buf, // 在AccepteEx函数接受连接新客户时,本端和远端IP信息已经存入当前变量
0,
sizeof(sockaddr_in) + 16, // ipv4
sizeof(sockaddr_in) + 16,
(sockaddr**)pLocalAddr_in,
&nLocalLen,
(sockaddr**)pRemoteAddr_in, // 解析后远端客户端IP信息会存入当前变量
&nRemoteLen
);
// 获取IP地址-远端客户端
char* ip = inet_ntoa(pRemoteAddr_in->sin_addr); // 指针间接访问对象, 函数返回指针指向的对象,是一个静态都变量,不会随着函数执行结束而释放
//CELLLog_Info("AcceptEx ipv4[%s]", ip);
return ip; // 指针变量值拷贝
}
private:
// 将AccepEx加载到内存中,函数调用效率更高(原理:通过GUID搜索函数)
LPFN_ACCEPTEX _lpfnAcceptEx = NULL; // 函数指针(AcceptEx)(函数地址)(全局变量)(函数指针)
// 将AcceptExAddrs加载到内存中,函数调用效率更高(原理:通过GUID搜索函数)
LPFN_GETACCEPTEXSOCKADDRS _getAcceptExAddrs = NULL; // 存储服务器接受加入新客户端的地址信息
HANDLE _completionPort = NULL; // NULL-c++以前的空指针写法
SOCKET _sockServer = INVALID_SOCKET; // 服务器socket套接字对象
......
......@@ -5,6 +5,7 @@
#include "NetWork.hpp"
#include "MessageHeader.hpp"
#include "Client.hpp"
#include <string>
namespace doyou {
namespace io { // 增加两层命令空间,避免在其它项目应用时类名出现冲突
......
// 高性能网络通信服务器2.0关键技术点总结DOC
// 开始时间[2023-3-8 to 至今]
// 欲速则不达 qzfull 工欲善其事必先利其器
// 欲速则不达 qzfull=c++ 工欲善其事必先利其器
// 请按照规范进行标准注释
// linux系统编译命令:
......@@ -45,4 +45,17 @@ linux client connect wins server ipv6 failed.
13.ipv6的外网服务器没有,但是可以兼容ipv4的外网服务器也行。
14.网卡名scope_id_name可以作为独立配置项,也可和IP配置项目一起配置,然后在代码中
对IP配置进行分割,分别获取ip信息和网卡名信息即可。
15.服务端接收新的客户端连接后,可以通过客户端IP地址判断加入的客户端属于什么地区,
并对客户端IP合法性进行校验,避免恶意连接,将恶意攻击IP设置进入黑名单中,将非法操作
IP直接存入黑名单中,所以,服务端获取客户端IP地址很有意义。select/epoll已经支持
此项功能,当前需完善IOCP网络模型下,获取客户端IP地址。先获取客户端IP地址,然后
再将其存储在客户端对象中。
16.在搭建高性能服务器代码编写中,根据情况可以少量使用比如std::string等而采用char*代替,
因为string会动态new/delete,会一定程度降低程序执行效率。
生成启动时间为 2023/3/27 22:19:02。
生成成功。
已用时间 00:00:00.19
#pragma once
#pragma execution_character_set("utf-8")
#include <stdio.h>
#include <inaddr.h>
// SOCKET
#ifdef _WIN32
#define FD_SETSIZE 65535 // fd_set集合元素的最大值,集合中实际元素数量不能超过这个最大值
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <windows.h> // wins系统头文件
#include <WinSock2.h>
#include <ws2ipdef.h>
#include <WS2tcpip.h> // 系统库文件名不区分大小写
#pragma comment(lib,"ws2_32.lib")
#else
#ifdef __APPLE__
// 分析:通过查看macos系统API头文件中详细说明(这是最权威的说明,一般位API开发者提供的解释),只要定义了下面的宏,就解除了select网络模型对socket数量上限值的限定
#define _DARWIN_UNLIMITED_SELECT // 定义一个宏
#endif // !__APPLE__
#include<unistd.h> //uni std
#include<arpa/inet.h>
#include<string.h>
#include<signal.h>
#include<sys/socket.h>
#define SOCKET int
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#endif
void main()
{
struct in_addr inaddr;
char str[INET_ADDRSTRLEN];
memset(str, 0, INET_ADDRSTRLEN);
inaddr.s_addr = inet_addr("127.0.0.1"); // 假设in_addr为127.0.0.1
inet_ntop(AF_INET, &inaddr, str, INET_ADDRSTRLEN);
printf("TEST IP address is %s\n", str); // 输出IP地址
int a = 0;
char b = '0';
printf("a=%02X\n", a);
printf("b=%02X\n", b);
system("pause");
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册