提交 43d689a8 编写于 作者: X xuchi

服务器将新加入客户端IP信息存储到client对象中

上级 a0778682
......@@ -205,21 +205,44 @@ namespace doyou {
return (_isPostRecv || _isPostSend); // 逻辑或:只要有一个及其以上为真,则为真
}
// 设置客户端IP地址
void SetIp(char* ip)
{
if (nullptr == ip) {
return;
}
// 分析:如果src传入实际字串长度小于para3, 会将src字串拷贝至dest,不足para3长度用空字符填充
// 如果src传入实际字串长度等于para3, 将src字串拷贝至dest
// 如果src传入实际字串长度大于para3, 只将para3指定长度拷贝至dest, 避免数据溢出
strncpy(_ip, ip, INET6_ADDRSTRLEN); // 比strcpy函数更安全,para3-要复制的字符个数。如果源字符串的长度小于n个字符,则目标字符串将被用空字符填充直到其长度为n个字符。
}
// 返回客户端IP地址
char* GetIp()
{
return _ip; // 指针变量间值拷贝,通过指针变量的值可以间接访问指针变量值指向的对象
}
#endif // CELL_USE_IOCP
private:
// 编程建议:变量在声明同时,建议进行初始化
// socket fd_set file desc set
SOCKET _sockfd;
//第二缓冲区 接收消息缓冲区
Buffer _recvBuff; // 推荐对象组合,优于继承
//发送缓冲区
SOCKET _sockfd = INVALID_SOCKET;
// 第二缓冲区 接收消息缓冲区
Buffer _recvBuff; // 推荐对象组合,优于继承, 降低耦合读
// 发送缓冲区
Buffer _sendBuff;
//心跳死亡计时
time_t _dtHeart;
//上次发送消息数据的时间
time_t _dtSend;
//发送缓冲区遇到写满情况计数
// 心跳死亡计时
time_t _dtHeart = 0;
// 上次发送消息数据的时间
time_t _dtSend = 0;
// 发送缓冲区遇到写满情况计数
int _sendBuffFullCount = 0;
// 客户端对象IP信息
char _ip[INET6_ADDRSTRLEN]; // 对象存在,对象属性就存在,= {0} // vs2013工具对c++11特性,属性声明初始化操作支持得不是特别好
#ifdef CELL_USE_IOCP
bool _isPostRecv = false; // Iocp是否投递接收数据任务, 也可以采用Int计数,记录投递次数
......
......@@ -66,7 +66,7 @@ namespace doyou {
char* ip = iocp.GetAcceptExAddrs(ioEvent.pIOData, _address_family);
CELLLog_Info("new client[sockfd=%d][ip=%s] to join.\n", ioEvent.pIOData->sockfd, ip); // 目前从返回的数据中无法获取其它信息,因为只传入了sockServer的信息
IocpAccept(ioEvent.pIOData->sockfd); // 客户端socket已知
IocpAccept(ioEvent.pIOData->sockfd, ip); // 客户端socket已知
// 待优化点:投递接收任务前,先校验已经连接的客户端总数是否超过连接上限-done
// 继续 向Iocp投递接收连接的任务
iocp.PostAccept(&ioData, _address_family);
......@@ -76,7 +76,7 @@ namespace doyou {
} // onrun
// Iocp接受客户端连接
SOCKET IocpAccept(SOCKET cSock)
SOCKET IocpAccept(SOCKET cSock, char* ip)
{
// 新连接的客户端的IP地址和端口号PORT, 暂时不需要,后期业务有需要再传递过来
//sockaddr_in clientAddr = {};
......@@ -98,8 +98,9 @@ namespace doyou {
NetWork::make_reuseaddr(cSock);
// 将新客户端分配给客户数量最少的cellServer
addClientToCELLServer(new Client(cSock, _nSendBuffSize, _nRecvBuffSize));
//获取IP地址 inet_ntoa(clientAddr.sin_addr)
auto pClient = new Client(cSock, _nSendBuffSize, _nRecvBuffSize);
pClient->SetIp(ip);
addClientToCELLServer(pClient);
}
else {
// 获取IP地址 inet_ntoa(clientAddr.sin_addr)
......
......@@ -195,17 +195,20 @@ namespace doyou {
{
NetWork::make_reuseaddr(cSock); // 处理程序关闭及时释放socket资源,可立即重用
//CELLLog_Info("accept cSock<%d>", cSock);
// 获取IP地址, 从para2中获取IPV6地址,存储到para3
static char ip[INET6_ADDRSTRLEN] = {}; // 涉及到跨线程操作,所以采用静态变量
inet_ntop(AF_INET6, &clientAddr.sin6_addr, ip, INET6_ADDRSTRLEN - 1); // ?-1: 如果有结束符就不用拷贝
CELLLog_Info("Accept_Ipv6 : %s\n", ip);
// 客户端链接上限校验
if (_clientAccept < _nMaxClient)
{
_clientAccept++; // 连接的新客户端被分配给Server,计数+1
// 将新客户端分配给客户数量最少的cellServer
addClientToCELLServer(new Client(cSock, _nSendBuffSize, _nRecvBuffSize));
// 获取IP地址, 从para2中获取IPV6地址,存储到para3
char strIp[INET6_ADDRSTRLEN] = {};
inet_ntop(AF_INET6, &clientAddr.sin6_addr, strIp, INET6_ADDRSTRLEN - 1); // ?-1: 如果有结束符就不用拷贝
printf("Accept_Ipv6 : %s\n", strIp); // tmplog
auto pClient = new Client(cSock, _nSendBuffSize, _nRecvBuffSize);
pClient->SetIp(ip);
addClientToCELLServer(pClient);
}
else {
// 获取IP地址 inet_ntoa(clientAddr.sin_addr)
......@@ -243,15 +246,19 @@ namespace doyou {
{
NetWork::make_reuseaddr(cSock);
//CELLLog_Info("accept cSock<%d>", cSock);
// 获取IP地址
char* ip = inet_ntoa(clientAddr.sin_addr);
CELLLog_Info("Accept_Ipv4 : %s \n", ip);
// 客户端链接上限校验
if (_clientAccept < _nMaxClient)
{
_clientAccept++; // 连接的新客户端被分配给Server,计数+1
// 将新客户端分配给客户数量最少的cellServer
addClientToCELLServer(new Client(cSock, _nSendBuffSize, _nRecvBuffSize));
// 获取IP地址
char* strIp = inet_ntoa(clientAddr.sin_addr);
printf("Accept_Ipv4 : %s \n", strIp); // tmplog
auto pClient = new Client(cSock, _nSendBuffSize, _nRecvBuffSize);
pClient->SetIp(ip);
addClientToCELLServer(pClient);
}
else {
// 获取IP地址 inet_ntoa(clientAddr.sin_addr)
......
......@@ -57,5 +57,13 @@ IP直接存入黑名单中,所以,服务端获取客户端IP地址很有意
16.在搭建高性能服务器代码编写中,根据情况可以少量使用比如std::string等而采用char*代替,
因为string会动态new/delete,会一定程度降低程序执行效率。
17.采用c风格的代码写法,内存更可控。执行效率更高。但是c代码开发量更大。
18.类对象属性赋值,可以写一个init初始化方法。
19.编程建议:不要打印非必要日志,1)打印日志会消耗系统资源 2)打印日志可能刷屏,影响分析关键日志输出
20.注意区分指针变量的值,和指针变量指向的对象,可以有多个指针变量存储相同的值,这些指针都指向同一对象。
生成启动时间为 2023/3/31 22:36:47。
1>项目“E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\EasyClient\EasyClient.vcxproj”在节点 2 上(Rebuild 个目标)。
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(388,5): warning MSB8028: The intermediate directory (E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\tmp\Debug\) contains files shared from another project (EasyServer.vcxproj, Engine1.0.vcxproj, TestDemo.vcxproj). This can lead to incorrect clean and rebuild behavior.
1>ClCompile:
D:\software\VC\bin\CL.exe /c /I..\Depends\include /ZI /nologo /W3 /WX- /sdl- /Od /Oy- /D _MBCS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\tmp\Debug\\" /Fd"E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\tmp\Debug\vc120.pdb" /Gd /TP /analyze- /errorReport:prompt client.cpp
client.cpp
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\depends\include\log.hpp(70): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\time.inl(112) : 参见“localtime”的声明
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\depends\include\log.hpp(71): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\stdio.h(356) : 参见“sprintf”的声明
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\depends\include\log.hpp(74): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\stdio.h(356) : 参见“sprintf”的声明
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\depends\include\log.hpp(78): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\stdio.h(211) : 参见“fopen”的声明
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\easyclient\client.cpp(118): warning C4800: “int”: 将值强制为布尔值“true”或“false”(性能警告)
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\easyclient\client.cpp(230): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\string.h(112) : 参见“strcpy”的声明
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\easyclient\client.cpp(231): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\string.h(112) : 参见“strcpy”的声明
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\easyclient\client.cpp(322): warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\stdio.h(283) : 参见“scanf”的声明
1>e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\depends\include\log.hpp(197): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
d:\software\vc\include\time.inl(112) : 参见“localtime”的声明
e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\depends\include\log.hpp(99): 参见对正在编译的函数 模板 实例化“void doyou::io::Log::EchoReal<const char*>(bool,const char *,const char *,const char *)”的引用
e:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\depends\include\log.hpp(91): 参见对正在编译的函数 模板 实例化“void doyou::io::Log::PError<const char*>(const char *,const char *)”的引用
Link:
D:\software\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\bin\Debug\EasyClient.exe" /INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\bin\Debug\EasyClient.pdb" /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\bin\Debug\EasyClient.lib" /MACHINE:X86 "E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\tmp\Debug\client.obj"
EasyClient.vcxproj -> E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\\..\bin\Debug\EasyClient.exe
1>已完成生成项目“E:\files\技术doc\engine2.0\engine2.0\engine2.0\engine2.0\EasyClient\EasyClient.vcxproj”(Rebuild 个目标)的操作。
生成成功。
已用时间 00:00:02.24
生成启动时间为 2023/3/31 22:42:24。
生成成功。
已用时间 00:00:00.04
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册