提交 60bc21cd 编写于 作者: X xuchi

完善局域网TCP客户端支持ipv6连接功能

上级 a9a274af
......@@ -12,18 +12,21 @@
#include <WinSock2.h>
#include <ws2ipdef.h>
#include <WS2tcpip.h> // 系统库文件名不区分大小写
#include <iphlpapi.h> // if_nametoindex,函数声明
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"iphlpapi.lib") // 函数定义,静态库文件
#else
#ifdef __APPLE__
// 分析:通过查看macos系统API头文件中详细说明(这是最权威的说明,一般位API开发者提供的解释),只要定义了下面的宏,就解除了select网络模型对socket数量上限值的限定
#define _DARWIN_UNLIMITED_SELECT // 定义一个宏
#endif // !__APPLE__
#include<unistd.h> //uni std
#include<unistd.h> //unix std
#include<arpa/inet.h>
#include<string.h>
#include<signal.h>
#include<sys/socket.h>
#include <net/if.h>
#define SOCKET int
#define INVALID_SOCKET (SOCKET)(~0)
......
......@@ -73,6 +73,7 @@ namespace doyou {
}
else { // ipv6
sockaddr_in6 sin = {}; // 局部变量不要以下划线开头
sin.sin6_scope_id = if_nametoindex(_scope_id_name.c_str()); // 指定TCPCLIENT使用的网卡编号(网卡名)
sin.sin6_family = AF_INET6;
sin.sin6_port = htons(port);
// 将para2数值按照para1格式转换后存储到para3
......@@ -161,6 +162,12 @@ namespace doyou {
return SOCKET_ERROR;
}
// 设置ipv6本机使用网卡名
void SetScopeIdName(std::string scope_id_name)
{
_scope_id_name = scope_id_name;
}
protected:
// 内部事件分析: 作用域当前类和子类内部,因为外部调用可能会出现错误
......@@ -179,6 +186,7 @@ namespace doyou {
protected: // 作用域:当前类内部或子类内部
Client* _pClient = nullptr; // 与具体的网络通信模型无关
int _addressFamily = AF_INET; // 协议类型:ipv4或ipv6, 默认ipv4
std::string _scope_id_name = ""; // 使用ipv6本机网卡名
bool _isConnect = false;
};
......
......@@ -4,6 +4,10 @@
// 欲速则不达 qzfull 工欲善其事必先利其器
// 请按照规范进行标准注释
// linux系统编译命令:
g++ server.cpp -std=c++11 -pthread -o EasyServer
1.消息缓冲区设置大小应该依据消息size来加以考虑。
2.chatGPT工具高频应用来解决实际问题。具体使用请加以研究,要翻墙。
......@@ -15,12 +19,30 @@
5.服务端和客户端要么同时用ipv4, 要么同时用ipv6, 混搭是不行的,比如ipv4客户端是不能链接ipv6服务端。
总之,客户端和服务端采用的ip协议版本必须保持一致,才能正常进行网络通信。
6.编码建议:函数太长了就要封装更小的函数,以避免代码冗余。建议函数上限30行。
6.编码建议:
函数太长了就要封装更小的函数,以避免代码冗余。建议函数上限30行。
7.理论上讲,服务器每接收一个新的客户端连接,都应该把对应ip地址信息,存储在对应的客户端对象中,
并对Ip地址进行安全性分析,采用白名单或黑名单等,去除恶意IP.
8.代码有相同的部分,可以封装成独立函数调用,以避免代码冗余。
9.在同一程序里面(同一进程)可以同时使用ipv4和ipv6.
10.先采用ping机制确定网络环境是通的,在检查软件问题。
11.本机任意ip:
[127.0.0.1] // ipv4协议,本机任意ip
[::1] // ipv6协议,本机任意ip
12.当前问题:
wins client connect linux server ipv6 failed.
linux client connect wins server ipv6 failed.
原因:windwos内核和linux内核对于TCP连接的IP处理存在差异,比如,ping方式参数不同等。
需要进行代码适配调整。
针对,unix系统衍生系统,比如linux系统,作为ipv6 tcp client, 必须要指定网卡才能连接
到局域网的ipv6 tcp server.在windows系统下面可有也可没有。
13.ipv6的外网服务器没有,但是可以兼容ipv4的外网服务器也行。
......@@ -76,6 +76,7 @@
<ClCompile Include="client.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\bin\Debug\TcpEasyClient_linux_ipv6.sh" />
<None Include="..\..\bin\Debug\TcpEasyClient_wins_ipv4.bat" />
<None Include="..\..\bin\Debug\TcpEasyClient_wins_ipv6.bat" />
</ItemGroup>
......
......@@ -26,5 +26,8 @@
<None Include="..\..\bin\Debug\TcpEasyClient_wins_ipv6.bat">
<Filter>头文件</Filter>
</None>
<None Include="..\..\bin\Debug\TcpEasyClient_linux_ipv6.sh">
<Filter>头文件</Filter>
</None>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -199,6 +199,9 @@ void WorkThread(Thread* pThread, int id)
// 分析:数组元素访问越界,可能直接导致系统崩溃。
if (Config::Instance().hasKey("-ipv6")) { // 通过配置实现:采用ipv4或ipv6
CELLLog_Info("-ipv6");
clients[n]->SetScopeIdName(Config::Instance().getStr("scope_id_name", ""));
if (INVALID_SOCKET == clients[n]->InitSocket(AF_INET6, nSendBuffSize, nRecvBuffSize)) // 使用IPV6
break;
}
......
......@@ -76,6 +76,8 @@
<ClCompile Include="server.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\bin\Debug\TcpEasyServer_linux_ipv4.sh" />
<None Include="..\..\bin\Debug\TcpEasyServer_linux_ipv6.sh" />
<None Include="..\..\bin\Debug\TcpEasyServer_wins_ipv4.bat" />
<None Include="..\..\bin\Debug\TcpEasyServer_wins_ipv6.bat" />
</ItemGroup>
......
......@@ -26,5 +26,11 @@
<None Include="..\..\bin\Debug\TcpEasyServer_wins_ipv6.bat">
<Filter>头文件</Filter>
</None>
<None Include="..\..\bin\Debug\TcpEasyServer_linux_ipv4.sh">
<Filter>头文件</Filter>
</None>
<None Include="..\..\bin\Debug\TcpEasyServer_linux_ipv6.sh">
<Filter>头文件</Filter>
</None>
</ItemGroup>
</Project>
\ No newline at end of file
// 高性能服务器可采用的网络通信模型三选一:select/epoll/iocp/
//#include "TcpSelectServer.hpp" // using select, both linux and windows.
#include "TcpSelectServer.hpp" // using select, both linux and windows.
//#include "TcpEpollServer.hpp" // using epoll, only linux.
#include "TcpIocpServer.hpp" // using iocp, only windows.
//#include "TcpIocpServer.hpp" // using iocp, only windows.
#include "MsgStream.hpp"
#include "Config.hpp"
......@@ -11,7 +11,7 @@
using namespace doyou::io; // 使用名称空间
// 可使用服务模型(三选一):1-TcpSelectServer 2-TcpEpollServer 3-TcpIocpServer
class MyServer : public TcpIocpServer
class MyServer : public TcpSelectServer
{
public:
MyServer()
......
生成启动时间为 2023/3/27 22:19:02。
生成成功。
已用时间 00:00:00.19
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册