社区
网络及通讯开发
帖子详情
为什么程序中使用了TNMUDP控件,线程数就多了一个?
angowb
2006-05-15 11:29:06
为什么程序中使用了TNMUDP控件,线程数就多了一个?
TNMUDP控件会自己创建一个线程吗,使用这个控件需要注意一些什么问题?
TNMUDP控件会自己创建一个接受数据的缓冲队列吗?(好像是8k)
请各位高手讲讲啊!
...全文
346
22
打赏
收藏
为什么程序中使用了TNMUDP控件,线程数就多了一个?
为什么程序中使用了TNMUDP控件,线程数就多了一个? TNMUDP控件会自己创建一个线程吗,使用这个控件需要注意一些什么问题? TNMUDP控件会自己创建一个接受数据的缓冲队列吗?(好像是8k) 请各位高手讲讲啊!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
22 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
铖邑
2006-05-19
打赏
举报
回复
不对。线程之间是有竞争的。楼主继续研究吧
angowb
2006-05-19
打赏
举报
回复
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString str_data = "send test data";
PostMessage(this->Handle, _MsgId_Test, 0, 0);
NMUDP1->SendBuffer(str_data.c_str(), str_data.Length(), str_data.Length());
m_UCStatus = 999;
}
上面的代码是我为了描述问题而作的一个Sample,实际上我们现在做的程序已提交给客户,如果要修改代码就必须对客户作出解释。
您说的原因我已理解了。
但是,我认为如果当前函数Button1Click(TObject *Sender)在响应 _MsgId_Test 消息时,必须执行完该函数。
即使NMUDP1->SendBuffer(str_data.c_str(), str_data.Length(), str_data.Length());是执行了另外一个线程,那也只能是把当前线程挂起,而不应该再这个主线程中的函数执行了一半(m_UCStatus没能赋值为999)就执行消息队列,我认为程序只有在处理完当前函数后才能够执行消息队列中的消息。
铖邑
2006-05-19
打赏
举报
回复
你把顺序调换一下估计就可以了
AnsiString str_data = "send test data";
NMUDP1->SendBuffer(str_data.c_str(), str_data.Length(), str_data.Length());
PostMessage(this->Handle, _MsgId_Test, 0, 0);
m_UCStatus = 999;
原因就是,如果你不用ip地址,用主机名,那么就需要先对主机名进行解析,这要多花一点时间,于是在SendBuffer这个函数上就多停留了一会儿,而这时消息已经到达,所以m_UCStatus依旧是0(还没来得及运行到m_UCStatus = 999;)
铖邑
2006-05-19
打赏
举报
回复
我知道什么原因了,先标记一下
angowb
2006-05-19
打赏
举报
回复
如下:
.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
m_UCStatus = 0;
NMUDP1->LocalPort = 5001;
NMUDP1->RemotePort = 5002;
//NMUDP1->RemoteHost = "127.0.0.1"; //////////ShowMessage是999
NMUDP1->RemoteHost = "LocalHost"; //////////ShowMessage是0
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString str_data = "send test data";
PostMessage(this->Handle, _MsgId_Test, 0, 0);
NMUDP1->SendBuffer(str_data.c_str(), str_data.Length(), str_data.Length());
m_UCStatus = 999;
}
//---------------------------------------------------------------------------
void TForm1::OnTest(TMessage & msg)
{
ShowMessage(m_UCStatus);
}
.h
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <NMUDP.hpp>
#define _MsgId_Test (WM_USER + 1)
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:
TButton *Button1;
TNMUDP *NMUDP1;
void __fastcall Button1Click(TObject *Sender);
private:
int m_UCStatus;
void OnTest(TMessage & msg);
public:
__fastcall TForm1(TComponent* Owner);
protected:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(_MsgId_Test, TMessage, OnTest)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
铖邑
2006-05-19
打赏
举报
回复
呵呵,不太明白你的意思啊
angowb
2006-05-19
打赏
举报
回复
又发现了一个奇怪的问题。
TNMUDP控件的RemoteHost属性,设置为127.0.0.1 和LocalHost时代码执行的竟然不同。
原因还在调查中
铖邑
2006-05-19
打赏
举报
回复
是不同的线程
angowb
2006-05-19
打赏
举报
回复
xpdavis(咕嘟) 大哥:
但是在同一线程内部,一个函数要是没执行完毕,就可以执行另外的一个函数(也是同一线程的),那岂不是乱套了,单线程的也需要排他?
铖邑
2006-05-19
打赏
举报
回复
线程 进程都是这样的,你在哪里看到的必须执行完一个函数才能切换到另一个线程 进程?
这不是显而易见的事情吗?
建议找本线程 进程的书看看
angowb
2006-05-19
打赏
举报
回复
xpdavis(咕嘟) 大哥:
再给点指导吧,这块我想了好久也没想明白阿.
在一个线程中为什么函数执行了一半就开始处理消息队列了.
铖邑
2006-05-17
打赏
举报
回复
楼主是想研究这个控件吗?据我了解,好象这个控件也是第三方的,并且不提供源码。它的实现机制不太清楚
铖邑
2006-05-17
打赏
举报
回复
晕,不明白了,没有研究
angowb
2006-05-16
打赏
举报
回复
希望能和各位讨论一下TNMUDP控件。
angowb
2006-05-16
打赏
举报
回复
xpdavis(咕嘟) 大哥:
经过测试(BCB6),在工程中添加1个,2个,3个 TNMUDP控件,仅是增加了一个线程。
而且我发现TNMUDP控件自己有缓存队列,队列大小约8K。
铖邑
2006-05-16
打赏
举报
回复
网络通信控件必须及时的把数据从缓冲区中取出,否则新的数据无法进入或者旧的数据会被覆盖,而且需要及时了解数据是否到来,所以,这类控件通常要启动一个线程,来判断是否有数据来临。这是很正常的,楼主不想多一个线程的吗?
铖邑
2006-05-16
打赏
举报
回复
多个TNMUDP控件可以共享这个线程吗?不行!那样对这个控件而言设计太复杂。
angowb
2006-05-16
打赏
举报
回复
xpdavis(咕嘟) 大哥:
>>这个线程是用来异步接收数据的,不然怎么触发事件???
多个TNMUDP控件可以共享这个线程吗?xpdavis(咕嘟)大哥能否再给小弟多讲讲啊,小弟对这不怎么懂。谢谢您。
铖邑
2006-05-16
打赏
举报
回复
这个线程是用来异步接收数据的,不然怎么触发事件???
angowb
2006-05-16
打赏
举报
回复
xpdavis(咕嘟) :
为什么 占用一个线程是正常的啊???
加载更多回复(2)
fastnet for delphi 7
delphi 7 fastnet
控件
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
用Delphi编写局域网
中
的聊天
程序
.doc
用dephi编写的聊天
程序
简单,好用。doc文件
Delphi 5编程实例与技巧
目 录 前言 第一部分 Delphi编程基础 第1章 Delphi集成开发环境 1 1.1 集成开发环境简介 1 1.2 集成调试器 5 1.3 开发环境的优化 6 1.3.1 自定义工具栏 6 1.3.2 编程环境设置 7 1.3.3 编辑环境设置 8 1.3.4 工程设置 8 1.4 方法与技巧 9 1.4.1
使用
代码浏览器 9 1.4.2
使用
代码编辑器 9 1.4.3
使用
帮助系统 10 1.4.4 设置IDE桌面 11 第2章 对象Pascal语言 12 2.1 学习对象Pascal语言的
一个
通用 例程 12 2.2 对象Pascal语言基础 14 2.2.1 标识符 14 2.2.2 保留字和指令字 14 2.2.3 注释 15 2.2.4
数
据类型 16 2.2.5 运算符 21 2.2.6 语句 24 2.2.7 过程与函
数
27 2.3 对象Pascal语言的关键技术 30 2.3.1 对象和类 31 2.3.2 类的封装与继承 31 2.3.3 构造函
数
和析构函
数
32 2.3.4 多态性 35 2.3.5 抽象类 38 2.3.6 运行时类型信息 39 2.3.7 类方法 41 2.3.8 类引用 42 2.3.9 单元文件与工程文件 43 2.4 异常处理 45 2.4.1 raise语句 45 2.4.2 try...except语句 45 2.4.3 try...finally语句 47 2.5 方法与技巧 48 2.5.1 命名规则 48 2.5.2 在编译时自由设置是否获得提示 信息 48 2.5.3
使用
代码模板 49 2.5.4
使用
动态多维
数
组 49 2.5.5 定义两个相互包含的类 50 2.5.6 获取和
使用
命令行参
数
51 2.5.7 引用参
数
传递 51 第二部分 Delphi编程的核心技能 第3章 窗体和组件 53 3.1 窗体和组件 53 3.1.1 窗体 54 3.1.2 组件 56 3.1.3 在窗体
中
使用
组件 57 3.2 文本组件 60 3.3 特殊输入组件 61 3.4 按钮及其分类组件 63 3.5 列表组件 64 3.6 分组组件 67 3.7 信息反馈组件 69 3.8 表格显示组件 70 3.9 图形显示组件 71 3.10 开发MDI应用
程序
73 3.11 常用组件的用法 74 3.12 方法与技巧 84 3.12.1 窗体、组件的
使用
原则 84 3.12.2
使用
信息对话框 85 3.12.3
使用
组件的Hint属性 88 3.12.4
使用
Edit组件的IME属性 89 3.12.5 将系统字体添加到ComboBox 组件
中
89 3.12.6 在RichEdit组件
中
存取文件 90 3.12.7 设置模态对话框的返回值 90 3.12.8
使用
事件处理过程
中
的Sender 参
数
91 3.12.9 为
控件
生成多行提示信息 91 3.12.10 生成非矩形窗口 92 3.12.11 移动无标题栏窗口 94 3.12.12 制作动态字幕 95 3.12.13 在窗体上动态地设置背景 画面 96 3.12.14 Owner和Parent的区别 97 第4章 菜单、工具栏和状态栏 98 4.1 菜单 98 4.1.1 主菜单 99 4.1.2 鼠标右键弹出式菜单 99 4.1.3
使用
菜单模板 99 4.2 工具栏 100 4.2.1 ToolBar 100 4.2.2 CoolBar 100 4.2.3 ControlBar 101 4.3 状态栏 101 4.4 方法与技巧 106 4.4.1 动态创建菜单 106 4.4.2 为菜单动态定义快捷键 108 4.4.3 动态改变菜单 108 4.4.4 定制系统菜单 109 4.4.5 制作图形菜单项 110 4.4.6 在状态栏
中
添加进度条等其他 组件 111 4.4.7 MDI应用
程序
中
的菜单融合 113 4.4.8 制作可随处拖放的工具栏 116 4.4.9 将菜单项移到菜单栏的最右边 117 4.4.10 运行时
控件
的移动 117 第5章 键盘和鼠标 119 5.1 键盘事件 119 5.2 鼠标事件 120 5.2.1 常用鼠标事件 120 5.2.2 拖曳事件 120 5.3
DELPHI 5编程实例与技巧
Delphi是由Inprise公司推出的面向对象的可视化软件开发工具。Delphi 5是Delphi的最新版本。本书共分三部分、16章,主要介绍Delphi 5集成开发环境,对象Pascal语言、组件、通用编程技术、动态链接库、多
线程
、多媒体编程、
数
据库编程、网络编程和Windows API编程等。 目 录 前言 第一部分 Delphi编程基础 第1章 Delphi集成开发环境 1 1.1 集成开发环境简介 1 1.2 集成调试器 5 1.3 开发环境的优化 6 1.3.1 自定义工具栏 6 1.3.2 编程环境设置 7 1.3.3 编辑环境设置 8 1.3.4 工程设置 8 1.4 方法与技巧 9 1.4.1
使用
代码浏览器 9 1.4.2
使用
代码编辑器 9 1.4.3
使用
帮助系统 10 1.4.4 设置IDE桌面 11 第2章 对象Pascal语言 12 2.1 学习对象Pascal语言的
一个
通用 例程 12 2.2 对象Pascal语言基础 14 2.2.1 标识符 14 2.2.2 保留字和指令字 14 2.2.3 注释 15 2.2.4
数
据类型 16 2.2.5 运算符 21 2.2.6 语句 24 2.2.7 过程与函
数
27 2.3 对象Pascal语言的关键技术 30 2.3.1 对象和类 31 2.3.2 类的封装与继承 31 2.3.3 构造函
数
和析构函
数
32 2.3.4 多态性 35 2.3.5 抽象类 38 2.3.6 运行时类型信息 39 2.3.7 类方法 41 2.3.8 类引用 42 2.3.9 单元文件与工程文件 43 2.4 异常处理 45 2.4.1 raise语句 45 2.4.2 try...except语句 45 2.4.3 try...finally语句 47 2.5 方法与技巧 48 2.5.1 命名规则 48 2.5.2 在编译时自由设置是否获得提示 信息 48 2.5.3
使用
代码模板 49 2.5.4
使用
动态多维
数
组 49 2.5.5 定义两个相互包含的类 50 2.5.6 获取和
使用
命令行参
数
51 2.5.7 引用参
数
传递 51 第二部分 Delphi编程的核心技能 第3章 窗体和组件 53 3.1 窗体和组件 53 3.1.1 窗体 54 3.1.2 组件 56 3.1.3 在窗体
中
使用
组件 57 3.2 文本组件 60 3.3 特殊输入组件 61 3.4 按钮及其分类组件 63 3.5 列表组件 64 3.6 分组组件 67 3.7 信息反馈组件 69 3.8 表格显示组件 70 3.9 图形显示组件 71 3.10 开发MDI应用
程序
73 3.11 常用组件的用法 74 3.12 方法与技巧 84 3.12.1 窗体、组件的
使用
原则 84 3.12.2
使用
信息对话框 85 3.12.3
使用
组件的Hint属性 88 3.12.4
使用
Edit组件的IME属性 89 3.12.5 将系统字体添加到ComboBox 组件
中
89 3.12.6 在RichEdit组件
中
存取文件 90 3.12.7 设置模态对话框的返回值 90 3.12.8
使用
事件处理过程
中
的Sender 参
数
91 3.12.9 为
控件
生成多行提示信息 91 3.12.10 生成非矩形窗口 92 3.12.11 移动无标题栏窗口 94 3.12.12 制作动态字幕 95 3.12.13 在窗体上动态地设置背景 画面 96 3.12.14 Owner和Parent的区别 97 第4章 菜单、工具栏和状态栏 98 4.1 菜单 98 4.1.1 主菜单 99 4.1.2 鼠标右键弹出式菜单 99 4.1.3
使用
菜单模板 99 4.2 工具栏 100 4.2.1 ToolBar 100 4.2.2 CoolBar 100 4.2.3 ControlBar 101 4.3 状态栏 101 4.4 方法与技巧 106 4.4.1 动态创建菜单 106 4.4.2 为菜单动态定义快捷键 108 4.4.3 动态改变菜单 108 4.4.4 定制系统菜单 109 4.4.5 制作图形菜单项 110 4.4.6 在状态栏
中
添加进度条等其他 组件 111 4.4.7 MDI应用
程序
中
的菜单融合 113 4.4.8 制作可随处拖放的工具栏 116 4.4.9 将菜单项移到菜单栏的最右边 117 4.4.10 运行时
控件
的移动 117 第5章 键盘和鼠标 119 5.1 键盘事件 119 5.2 鼠标事件 120 5.2.1 常用鼠标事件 120 5.2.2 拖曳事件 120 5.3 方法与技巧 122 5.3.1 检测Shift、Alt和Ctrl键是否 按下 122 5.3.2 屏蔽系统功能键 123 5.3.3 模拟按下键盘上的某个键 124 5.3.4 限制鼠标移动的范围 124 5.3.5 自定义鼠标 125 5.3.6 设置光标闪烁的速度 126 5.3.7 不同
程序
间的拖曳操作 127 第6章 文件、目录和驱动器 129 6.1 文件 129 6.2 文件对话框组件 129 6.3 Win3.1相关组件 131 6.4 常用函
数
131 6.4.1 文件操作常用函
数
131 6.4.2 目录操作常用函
数
136 6.4.3 驱动器操作常用函
数
138 6.4.4 文件名操作常用函
数
139 6.5 方法与技巧 145 6.5.1 获取驱动器类型信息 145 6.5.2 操作INI文件 146 6.5.3 从文件
中
读取超过255个字符 的行 148 6.5.4 获取文件的日期信息 149 6.5.5 检测软盘或光盘是否有变化 150 6.5.6 检测驱动器容量 151 6.5.7 拷贝整个目录 152 6.5.8 将文件删除到回收站
中
153 6.5.9 检测驱动器是否就绪 153 6.5.10 获取应用
程序
的文件名 154 6.5.11 操作临时文件 154 第7章 打印 156 7.1 一些简单的打印输出 156 7.2 TPrinter对象和TScreen对象 156 7.3 打印操作常用函
数
157 7.4 方法与技巧 164 7.4.1 获取默认打印机的信息 164 7.4.2 获取打印机队列的状态信息 165 7.4.3 打印窗体 166 第8章 多
线程
应用
程序
167 8.1 进程与
线程
167 8.2 TThread类 167 8.3
线程
的同步 169 8.4
线程
的优先级 170 第9章 动态链接库 176 9.1 概述 176 9.2 创建动态链接库 177 9.3
使用
动态链接库 179 9.4 方法与技巧 180 9.4.1 如何调试动态链接库 180 9.4.2 在DLL
中
使用
MessageBox代替ShowMessage 181 9.4.3 如何动态地装入DLL 181 9.4.4 如何定制不同语言版本的应用
程序
183 第三部分 Delphi高级编程技术 第10章 多媒体技术 185 10.1 多媒体 185 10.1.1 概述 185 10.1.2 多媒体应用领域 186 10.1.3 多媒体软件开发工具 187 10.2 图像格式的处理 188 10.2.1 位图 189 10.2.2 JPEG文件 191 10.3 特殊显示效果 193 10.3.1 画布 193 10.3.2 调用CopyRect 193 10.3.3 调用BitBlt 194 10.4 动画 199 10.4.1 文字动画 199 10.4.2 图像动画 200 10.5 音频、视频 206 10.6 方法与技巧 209 10.6.1
使用
MessageBeep与Beep 209 10.6.2
使用
PlaySound 210 10.6.3
使用
mciSendString 211 第11章 关系
数
据库 215 11.1 关系
数
据库 215 11.1.1 关键字 215 11.1.2 表之间的约束 215 11.1.3 结构化查询语言(SQL) 216 11.2 Delphi提供的
数
据库辅助工具 218 11.2.1
使用
SQL Explorer 218 11.2.2
使用
Database Desktop 218 11.2.3
使用
BDE Administrator 220 11.3
数
据库组件 221 11.3.1 TTable 221 11.3.2 TQuery 225 11.3.3 表的连接 227 11.3.4 计算字段 229 11.3.5 查找字段 230 11.3.6 网格 231 11.4 查询记录 232 11.4.1 GotoKey 232 11.4.2 FindKey 233 11.4.3 模糊查询 233 11.4.4 Locate 234 11.5 修改记录 234 11.6 插入和删除记录 235 11.7
数
据模块 237 11.8
数
据字典查看器 238 11.9 事务 240 11.10 处理
数
据库异常 244 第12章 InterBase服务器 248 12.1 客户/服务器的概念 248 12.1.1 客户 248 12.1.2 InterBase 客户例程库 248 12.1.3 InterBase服务器 248 12.1.4 Borland
数
据库引擎 248 12.2
数
据库的管理和维护 249 12.2.1 创建
数
据库 249 12.2.2 创建表 250 12.2.3
数
据库安全 250 12.2.4 备份与恢复 251 12.3 服务器端
程序
252 12.3.1 存储过程 252 12.3.2 触发器 252 12.4 本地缓存 253 第13章 Web与
数
据库 260 13.1 CGI的工作原理 260 13.2 Delphi对CGI的支持 260 13.3 创建Web应用
程序
261 13.4 表单 262 13.5 把信息保存到
数
据库 264 13.6 查找记录 266 第14章 COM 270 14.1 在DLL
中
实现对象 270 14.2 接口 274 14.2.1 对象的生存期 277 14.2.2 IUnknown 279 14.2.3 全局唯一标志符(GUID) 281 14.2.4 注册表 281 14.2.5 多个接口问题 281 14.2.6 Variant类型 284 14.2.7 TComObject 289 14.2.8 TTypedComObject 295 14.3 OLE自动化 307 14.3.1 创建OLE自动化服务器 307 14.3.2 建立OLE客户
程序
314 14.3.3 访问自动化服务器的方法 316 14.3.4
使用
Word 316 14.4 复合文档 319 第15章 分布式
程序
设计 329 15.1 CORBA结构 329 15.1.1 CORBA在
数
据库的应用 335 15.1.2 远程访问 341 15.1.3 OSFind 341 15.2 远程
数
据集 342 15.2.1 基础 342 15.2.2 扩展服务器 346 15.2.3 参
数
传递 353 15.2.4 主从约束 355 15.2.5 离线处理 358 15.2.6 ActiveForm 361 15.3 插口Socket 362 15.3.1 插口的
使用
362 15.3.2
使用
插口的
一个
例子 363 15.3.3
TNM
UDP
组件 369 第16章 其他编程技术 374 16.1
使用
剪贴板 374 16.1.1 组件对剪贴板操作的支持 374 16.1.2
使用
剪贴板类 375 16.1.3 操作图形 378 16.1.4 操作组件 379 16.1.5 操作定制格式的
数
据 379 16.2 动态
数
据交换(DDE) 381 16.3 操作注册表 385 16.3.1 TRegistry类 387 16.3.2 与注册表相关的API函
数
390 16.4 帮助系统的制作 395 16.4.1 RTF文件 395 16.4.2 HPJ文件与HLP文件 398 16.4.3 启动帮助 402 16.5 安装与卸载 403 16.6 方法与技巧 404 16.6.1 获取Windows版本信息 404 16.6.2 获取系统的度量信息和相关 配置信息 405 16.6.3 获取CPU信息 407 16.6.4 获取内存信息 408 16.6.5 存取系统的颜色信息 409 16.6.6 获取Windows及系统路径 409 16.6.7 存取计算机名称 410 16.6.8 获取用户注册信息 411 16.6.9 关闭Windows 411 16.6.10 启动控制面板 412 16.6.11 启动屏幕保护 415 16.6.12 使窗体标题栏闪烁 415 16.6.13 使窗口背景颜色渐变 416 16.6.14 隐藏/显示桌面上的图标 416 16.6.15 获取窗口标题栏
中
的文字 417 16.6.16 制作软件封面 418 16.6.17 隐藏/显示Windows任务栏 420 16.6.18 使应用
程序
不出现在Windows 的任务栏上 420 16.6.19 状态栏编程 421 16.6.20 存取系统参
数
信息 426 16.6.21 Windows启动时运行
程序
427 16.6.22 为
程序
在启动菜单
中
创建 快捷方式 428 16.6.23 在
程序
中
运行其他
程序
429 16.6.24 同时只运行
程序
的
一个
实例 429 16.6.25 关闭运行的其他应用
程序
431 16.6.26 显示旋转字体 432
C++ Builder 编程实战
这个资料传错了,看到的请不要下载,我压缩东西的时候电脑出了点问题,实在不好意思。
网络及通讯开发
1,317
社区成员
8,874
社区内容
发帖
与我相关
我的任务
网络及通讯开发
C++ Builder 网络及通讯开发
复制链接
扫一扫
分享
社区描述
C++ Builder 网络及通讯开发
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章