Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
一个会的不多的人
engine2.0
提交
966c575e
E
engine2.0
项目概览
一个会的不多的人
/
engine2.0
与 Fork 源项目一致
Fork自
xc13262215230 / engine2.0
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine2.0
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
966c575e
编写于
3月 15, 2023
作者:
X
xuchi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
服务端升级为ipv6_001
上级
4d57c891
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
113 addition
and
30 deletion
+113
-30
engine2.0/engine2.0/Depends/include/TcpServer.hpp
engine2.0/engine2.0/Depends/include/TcpServer.hpp
+107
-29
engine2.0/engine2.0/Doc/Record.txt
engine2.0/engine2.0/Doc/Record.txt
+2
-0
engine2.0/engine2.0/engine1.0/engine1.0.vcxproj
engine2.0/engine2.0/engine1.0/engine1.0.vcxproj
+4
-1
engine2.0/engine2.0/engine2.0.sdf
engine2.0/engine2.0/engine2.0.sdf
+0
-0
engine2.0/engine2.0/engine2.0.v12.suo
engine2.0/engine2.0/engine2.0.v12.suo
+0
-0
未找到文件。
engine2.0/engine2.0/Depends/include/TcpServer.hpp
浏览文件 @
966c575e
...
...
@@ -24,24 +24,26 @@ namespace doyou {
private:
//
Thread
_thread
;
//消息处理对象,内部会创建线程
//
消息处理对象,内部会创建线程
std
::
vector
<
Server
*>
_cellServers
;
//每秒消息计时
//
每秒消息计时
Timestamp
_tTime
;
// 服务端套接字,功能:接收新的客户端加入
SOCKET
_sock
;
protected:
// 服务端采用IPV协议版本,默认IPV4
int
_address_family
=
AF_INET
;
// 客户端发送缓冲区大小
int
_nSendBuffSize
;
// 客户端接收缓冲区大小
int
_nRecvBuffSize
;
// 客户端连接上限
int
_nMaxClient
;
//
SOCKET recv计数
//
SOCKET recv计数 原子操作(多线程数据保护)
std
::
atomic_int
_recvCount
;
//收到消息计数
std
::
atomic_int
_msgCount
;
//
收到消息计数
std
::
atomic_int
_msgCount
;
// (已连接)客户端计数 = 连接已分配总数 + 连接未分配总数
std
::
atomic_int
_clientAccept
;
// 已分配(给处理接收和发送网络消息线程)客户端计数
...
...
@@ -64,7 +66,7 @@ namespace doyou {
Close
();
}
// 初始化Socket(服务端程序)
SOCKET
InitSocket
(
)
SOCKET
InitSocket
(
int
af
=
AF_INET
)
// 参数默认值-IPV4
{
NetWork
::
Init
();
if
(
INVALID_SOCKET
!=
_sock
)
...
...
@@ -72,7 +74,9 @@ namespace doyou {
CELLLog_Warring
(
"initSocket close old socket<%d>..."
,
(
int
)
_sock
);
Close
();
}
_sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
IPPROTO_TCP
);
_address_family
=
af
;
_sock
=
socket
(
af
,
SOCK_STREAM
,
IPPROTO_TCP
);
if
(
INVALID_SOCKET
==
_sock
)
{
CELLLog_PError
(
"create socket failed..."
);
...
...
@@ -85,34 +89,51 @@ namespace doyou {
return
_sock
;
}
//绑定IP和端口号
//
绑定IP和端口号
int
Bind
(
const
char
*
ip
,
unsigned
short
port
)
{
//if (INVALID_SOCKET == _sock)
//{
// InitSocket();
//}
// 2 bind 绑定用于接受客户端连接的网络端口
sockaddr_in
_sin
=
{};
_sin
.
sin_family
=
AF_INET
;
_sin
.
sin_port
=
htons
(
port
);
//host to net unsigned short
int
ret
=
SOCKET_ERROR
;
// 编程建议:变量在声明同时进行初始化,避免可能的错误
if
(
AF_INET
==
_address_family
)
{
// ipv4
sockaddr_in
sin
=
{};
sin
.
sin_family
=
AF_INET
;
sin
.
sin_port
=
htons
(
port
);
// host to net unsigned short
#ifdef _WIN32
if
(
ip
){
_
sin
.
sin_addr
.
S_un
.
S_addr
=
inet_addr
(
ip
);
}
else
{
_sin
.
sin_addr
.
S_un
.
S_addr
=
INADDR_ANY
;
}
#ifdef _WIN32
// 采用宏来区分window和linux系统
if
(
ip
){
sin
.
sin_addr
.
S_un
.
S_addr
=
inet_addr
(
ip
);
}
else
{
sin
.
sin_addr
.
S_un
.
S_addr
=
INADDR_ANY
;
// 本机任意IP
}
#else
if
(
ip
)
{
_sin
.
sin_addr
.
s_addr
=
inet_addr
(
ip
);
if
(
ip
)
{
sin
.
sin_addr
.
s_addr
=
inet_addr
(
ip
);
}
else
{
sin
.
sin_addr
.
s_addr
=
INADDR_ANY
;
}
#endif
ret
=
bind
(
_sock
,
(
sockaddr
*
)
&
sin
,
sizeof
(
sin
));
}
else
{
_sin
.
sin_addr
.
s_addr
=
INADDR_ANY
;
else
if
(
AF_INET6
==
_address_family
)
{
// ipv6
sockaddr_in6
sin
=
{};
sin
.
sin6_family
=
AF_INET6
;
sin
.
sin6_port
=
htons
(
port
);
if
(
nullptr
!=
ip
)
{
inet_pton
(
AF_INET6
,
ip
,
&
sin
.
sin6_addr
);
// inet_pton函数在其标准文本呈现形式中将 IPv4 或 IPv6 Internet 网络地址转换为其数字二进制形式。// 将para2数值按照para1格式转换后存储到para3
}
else
{
sin
.
sin6_addr
=
in6addr_any
;
// 没传入IP, 默认本机任意IP
}
ret
=
bind
(
_sock
,
(
sockaddr
*
)
&
sin
,
sizeof
(
sin
));
}
#endif
int
ret
=
bind
(
_sock
,
(
sockaddr
*
)
&
_sin
,
sizeof
(
_sin
));
else
{
CELLLog_Error
(
"bind port failed, _address_family<%d>"
,
_address_family
);
return
ret
;
}
if
(
SOCKET_ERROR
==
ret
)
{
// GetLastError(): windows系统获取错误时机的错误码,可在网上搜罗错误码的错误含义或者差错误手册
...
...
@@ -122,6 +143,7 @@ namespace doyou {
else
{
CELLLog_Info
(
"bind port<%d> success..."
,
port
);
}
return
ret
;
}
...
...
@@ -144,6 +166,61 @@ namespace doyou {
SOCKET
Accept
()
{
// 4 accept 等待接受客户端连接
if
(
AF_INET
==
_address_family
)
{
return
Accept_Ipv4
();
}
return
Accept_Ipv6
();
// 不是ipv4, 就是ipv6, 前面已经校验过
}
// 接受客户端连接-ipv6
SOCKET
Accept_Ipv6
()
{
sockaddr_in6
clientAddr
=
{};
int
nAddrLen
=
sizeof
(
clientAddr
);
SOCKET
cSock
=
INVALID_SOCKET
;
#ifdef _WIN32
cSock
=
accept
(
_sock
,
(
sockaddr
*
)
&
clientAddr
,
&
nAddrLen
);
#else
cSock
=
accept
(
_sock
,
(
sockaddr
*
)
&
clientAddr
,
(
socklen_t
*
)
&
nAddrLen
);
#endif
if
(
INVALID_SOCKET
==
cSock
)
{
// errno-错误码 strerror-错误码对应描述信息
// 接收到的新客户端套接字无效
CELLLog_PError
(
"accept INVALID_SOCKET...errno<%d> errMsg<%s>"
,
errno
,
strerror
(
errno
));
}
else
{
//CELLLog_Info("accept cSock<%d>", cSock);
// 客户端链接上限校验
if
(
_clientAccept
<
_nMaxClient
)
{
_clientAccept
++
;
// 连接的新客户端被分配给Server,计数+1
NetWork
::
make_reuseaddr
(
cSock
);
// 将新客户端分配给客户数量最少的cellServer
addClientToCELLServer
(
new
Client
(
cSock
,
_nSendBuffSize
,
_nRecvBuffSize
));
// 获取IP地址 inet_ntoa(clientAddr.sin_addr)
}
else
{
// 获取IP地址 inet_ntoa(clientAddr.sin_addr)
// 分析:超出链接上限,先链接再关闭:
// 好处1)可以知道是谁链接我们了(客户端信息)。
// 好处2)做一些其它操作,比如通知客户端我超限制了
// 好处3)可以查看该客户端是否在黑名单或白名单中,是否有传指定验证码token, 客户端需要传入一个正确的检验码。
// 如果重复多次链接,有可能是恶意链接。
NetWork
::
destroy_socket
(
cSock
);
CELLLog_Warring
(
"Accept to nMaxClient"
);
}
}
return
cSock
;
}
// 接受客户端连接-ipv4
SOCKET
Accept_Ipv4
()
{
sockaddr_in
clientAddr
=
{};
int
nAddrLen
=
sizeof
(
sockaddr_in
);
SOCKET
cSock
=
INVALID_SOCKET
;
...
...
@@ -173,7 +250,8 @@ namespace doyou {
else
{
// 获取IP地址 inet_ntoa(clientAddr.sin_addr)
// 分析:超出链接上限,先链接再关闭:
// 好处1)可以知道是谁链接我们了(客户端信息)。好处2)做一些其它操作,比如通知客户端我超限制了
// 好处1)可以知道是谁链接我们了(客户端信息)。
// 好处2)做一些其它操作,比如通知客户端我超限制了
// 好处3)可以查看该客户端是否在黑名单或白名单中,是否有传指定验证码token, 客户端需要传入一个正确的检验码。
// 如果重复多次链接,有可能是恶意链接。
NetWork
::
destroy_socket
(
cSock
);
...
...
engine2.0/engine2.0/Doc/Record.txt
浏览文件 @
966c575e
...
...
@@ -14,4 +14,6 @@
5.服务端和客户端要么同时用ipv4, 要么同时用ipv6, 混搭是不行的,比如ipv4客户端是不能链接ipv6服务端。
6.编码建议:函数太长了就要封装更小的函数,以避免代码冗余。建议函数上限30行。
engine2.0/engine2.0/engine1.0/engine1.0.vcxproj
浏览文件 @
966c575e
...
...
@@ -38,7 +38,10 @@
<Import
Project=
"$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition=
"exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
Label=
"LocalAppDataPlatform"
/>
</ImportGroup>
<PropertyGroup
Label=
"UserMacros"
/>
<PropertyGroup
/>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Debug|Win32'"
>
<OutDir>
$(SolutionDir)../bin/$(Configuration)\
</OutDir>
<IntDir>
$(SolutionDir)../tmp/$(Configuration)\
</IntDir>
</PropertyGroup>
<ItemDefinitionGroup
Condition=
"'$(Configuration)|$(Platform)'=='Debug|Win32'"
>
<ClCompile>
<WarningLevel>
Level3
</WarningLevel>
...
...
engine2.0/engine2.0/engine2.0.sdf
浏览文件 @
966c575e
无法预览此类型文件
engine2.0/engine2.0/engine2.0.v12.suo
浏览文件 @
966c575e
无法预览此类型文件
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录