[发布项目] spserver 0.9.2

85 views
Skip to first unread message

stephen.nil

unread,
Jun 28, 2008, 11:44:18 PM6/28/08
to dev4server

Sorry,第一次发的时候,操作失误,变成了另外一个帖子的回复。


SPServer 是一个高并发的 tcp server framework 。目前支持 Unix/Linux 和 Windows 平台。
在 Unix/Linux 平台,基于 libevent;在 Windows 平台基于 IOCP 技术来实现。
SPServer 基于 LGPL 发布。

自上次发布(http://groups.google.com/group/dev4server/browse_thread/thread/c9a2a2495123f618)以来,做了下面的一些改动
1.recv 改为用 zero byte buffer ,这样对于避免 WSAENOBUFS 10055 错误有一定的作用
2.把之前 linux 下 SPServer 所有的功能都移植到了 iocp 版本上,包括 Leader/Follower 模式的框架,支持 SSL 的插件机制
3.移植 OpenSSL 插件到 iocp 版本上,新增加了一个 XySSL 的插件,XySSL 声称支持 Non-Blocking 模式
4.根据网友的反馈,在 SP_IocpDispatcher 中增加了一个 push 接口,以便 server 能更灵活地 push 信息给 client

主页 http://code.google.com/p/spserver/
下载 http://spserver.googlecode.com/files/spserver-0.9.2.src.tar.gz

SPServer 自带了一套用于压力测试的程序。

在 windows 平台是 testiocpecho.cpp 和 testiocpstress.cpp 。使用方法如下:

1)在一个 console 启动 testiocpecho.exe
E:\spserver-0.9.2\win32\testiocpecho\Debug>.\testiocpecho.exe
#1728 server type lf
#1728 Listen on port [3333]
#1728 Thread #2868 has been created to accept socket
#1728 [tp@unknown] create thread#4028
#1728 [tp@unknown] create thread#2492
#1728 [tp@unknown] create thread#1076
#1728 [tp@unknown] create thread#3204

2) 在另一个 console 启动 testiocpstress.exe
E:\spserver-0.9.2\win32\testiocpstress\Debug>.\testiocpstress.exe -c 100 -m 100
这个程序支持一些命令行参数,-c 用户指定模拟多少个 client ,-m 用于指定每个 client 发送多少条信息。

在一台有 512M 内存的 windows xp home edition 机器上,两个程序都在本机运行,可以稳定运行 5000 的并发连接。
如果上到 10K 的连接,在测试一段时间之后,会开始出现 10055 的错误。
限于目前没有更高配置的机器,没有办法做更大并发的测试。如果有人有兴趣,可以帮忙做一下测试。

===========================================================================

在 Unix/Linux 下是 testecho.cpp 和 teststress.cpp 。使用方法如下:
1) 启动 testecho
bash-2.05a$ ./testecho
testecho[15635]: Listen on port [3333]
testecho[15635]: [ex@work] Thread #1026 has been created for executor
testecho[15635]: [ex@act] Thread #2051 has been created for executor

2) 执行 teststress
bash-2.05a$ ./teststress -c 100 -m 1000
这个命令行指定模拟 100 个 client ,每个 client 发送 1000 个信息。


iincity

unread,
Jul 4, 2008, 1:13:34 AM7/4/08
to dev4s...@googlegroups.com
在windows下好像客户端发起有连接限制,至今不知道修改windows配置来去掉这个
限制,你是如何做的?

stephen.nil 写道:

lau stephen

unread,
Jul 4, 2008, 2:14:58 AM7/4/08
to dev4s...@googlegroups.com
在 windows xp home edition sp2 上改了两个参数。其他版本的 windows 还没试过

SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Winsock
MaxUserPort REG_DWORD 5000-65534(十进制)(默认值0x1388--十进制为5000)

SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Winsock
TcpNumConnections 有效范围:0 - 0xfffffe


2008/7/4 iincity <sky...@tom.com>:
>
> 在windows下好像客户端发起有连接限制,至今不知道修改windows配置来去掉这个
> 限制,你是如何做的?

iincity

unread,
Jul 4, 2008, 3:26:28 AM7/4/08
to dev4s...@googlegroups.com
谢谢
lau stephen 写道:

esx

unread,
Jul 5, 2008, 1:53:05 PM7/5/08
to 高性能网络编程邮件列表
作者是否能给一下关于spserver的架构图,这样便于理解spserver的设计方式可以更好的学习啊,呵呵。
另外建议作者能否给代码多一些注释?这样有利于社区的接触。

On Jun 29, 11:44 am, "stephen.nil" <stephen....@gmail.com> wrote:
> Sorry,第一次发的时候,操作失误,变成了另外一个帖子的回复。
>
> SPServer 是一个高并发的 tcp server framework 。目前支持 Unix/Linux 和 Windows 平台。
> 在 Unix/Linux 平台,基于 libevent;在 Windows 平台基于 IOCP 技术来实现。
> SPServer 基于 LGPL 发布。
>
> 自上次发布(http://groups.google.com/group/dev4server/browse_thread/thread/c9a2a2...以来,做了下面的一些改动
> 1.recv 改为用 zero byte buffer ,这样对于避免 WSAENOBUFS 10055 错误有一定的作用
> 2.把之前 linux 下 SPServer 所有的功能都移植到了 iocp 版本上,包括 Leader/Follower 模式的框架,支持 SSL 的插件机制
> 3.移植 OpenSSL 插件到 iocp 版本上,新增加了一个 XySSL 的插件,XySSL 声称支持 Non-Blocking 模式
> 4.根据网友的反馈,在 SP_IocpDispatcher 中增加了一个 push 接口,以便 server 能更灵活地 push 信息给 client
>
> 主页http://code.google.com/p/spserver/
> 下载http://spserver.googlecode.com/files/spserver-0.9.2.src.tar.gz

stephen.nil

unread,
Jul 5, 2008, 11:10:32 PM7/5/08
to 高性能网络编程邮件列表
Hi, esx

暂时没有计划编写详细的文档。

如果有兴趣,可以从 package 里面的一些 demo 程序开始了解 spserver 。
package 里面包括了 echo server ,chatroom server 这两类比较典型的服务器类型。

这两个 demo 程序都是基于命令行的,无论在 unix/linux 还是 windows 平台。

echo server ,这个不用多说,基本算是网络编程的 hello world 了。
一个 client 发送的消息仅仅返回给 client 本身。

chatroom server 是一个聊天室服务器,可以用 telnet 命令连到 server 上,进行消息的发送和接受。
任何一个 client 发送的消息都会广播到所有的 client 。

可以尝试修改这两个程序,实现一些更复杂的功能。
如果在尝试的过程中,遇到有什么疑问,可以发邮件出来,互相交流一下。


Best regards,

stephen.nil
2008-07-06

stephen.nil

unread,
Jul 5, 2008, 11:21:22 PM7/5/08
to 高性能网络编程邮件列表

这里有一个简单的说明文档,不知道是否有看过。

http://iunknown.javaeye.com/blog/59804

程序的总体结构,主要是 POSA2 中提到的几个模式:Half-Async/Half-Sync, Leader/Follower

SP_Server/SP_IocpServer/SP_Dispatcher/SP_IocpDispatcher 实现的是 Half-Async/Half-Sync
SP_LFServer/SP_IocpLFServer 实现的是 Leader/Follower

关于这两个模式的具体实现,有做过一个简单的分析

http://cpp-circle.group.javaeye.com/group/topic/2116

snlee

unread,
Jul 7, 2008, 9:15:27 PM7/7/08
to 高性能网络编程邮件列表
Hi, stephen.nil
这些例子里都是在 int XxxxHandler :: handle( SP_Request * request,
SP_Response * response ) 里处理
数据接收和发送的操作。如果发送数据不是在 handle 成员函数处理,例如:1)定时向在线的人员广播,
2)业务逻辑比较复杂,需要在其它线程里操作,完成后再把数据发送到指定的 client。
类似以上的功能用 spserver 应该如何操作?


谢谢

iunknown

unread,
Jul 8, 2008, 1:48:48 AM7/8/08
to 高性能网络编程邮件列表
这个就是这次做的改进之一。
>>4.根据网友的反馈,在 SP_IocpDispatcher 中增加了一个 push 接口,以便 server 能更灵活地 push 信息给 client

在 SP_Dispatcher/SP_IocpDispatcher 中加了一个 push 方法。

具体的使用例子可以参考 testchat_d.cpp testiocpdispatcher.cpp 。

注意看 main 函数中的这一段

char buffer[ 256 ] = { 0 };
snprintf( buffer, sizeof( buffer ), "SYS : %d online\r\n", ++chatID );

SP_Message * msg = new SP_Message();
onlineSidList.copy( msg->getToList(), NULL );
msg->getMsg()->append( buffer );

SP_Sid_t sid = { SP_Sid_t::ePushKey, SP_Sid_t::ePushSeq };
SP_Response * response = new SP_Response( sid );
response->addMessage( msg );

dispatcher.push( response );

vvo...@gmail.com

unread,
Aug 26, 2008, 12:05:40 PM8/26/08
to 高性能网络编程邮件列表
第一次接触spserver,感觉还是有不少可圈可点之处,用了一下SP_IocpDispatcher接口,感觉还有不少可以改进的地方,如没有使用
内存池(或许是我没有找到?),没有对accept进行封装(换句话说,accept不能使用IOCP的特性),另外还有一个小小的bug,就是
start,或是handle传入的参数:request,里面的mClientIP为空,虽然这个IP可以在accept时获取,但总归是不方便,望
楼主修正一下。

vvo...@gmail.com

unread,
Aug 26, 2008, 11:12:02 PM8/26/08
to 高性能网络编程邮件列表
另外,针对SP_IocpDispatcher,如果上层的应用需要主动的断开一个连接(比如聊天室的T人),好象还没有提供这样的接口,我加了一个方
法,不知是否有效?

/**
* @brief kill a session
*/
void SP_IocpDispatcher::killSession(SP_Sid_t sid)
{
uint16_t seq = 0;
SP_Session * session = mEventArg->getSessionManager()->get( sid.mKey,
&seq );
if( seq == sid.mSeq && NULL != session )
{
session->setStatus( SP_Session::eWouldExit );

vvo...@gmail.com

unread,
Aug 28, 2008, 11:04:55 AM8/28/08
to 高性能网络编程邮件列表
写了一个程序测试了一下,上面写的killSession方法好象不行,还是等楼主来实现吧,呵呵。

stephen liu

unread,
Aug 30, 2008, 12:14:49 PM8/30/08
to dev4s...@googlegroups.com
commit 了一些新代码到 svn ,在 SP_Response 中增加了一个 toCloseList ,用于实现 KillSession 的功能。
在 testiocpdispatcher.cpp 中增加了一些代码用于示范如何使用。如果有兴趣,可以从 svn 上获得最新的代码。

vvo...@gmail.com

unread,
Sep 1, 2008, 4:37:10 AM9/1/08
to 高性能网络编程邮件列表
恩,测试了一下最新的代码,toCloseList已经可以实现关闭任意一个Socket连接的功能了,Thanks!

不过又发现了两个问题:
1、testiocpdispatcher.cpp中的accept会一直阻塞线程,而且closesocke之后,并不会导致accept的退出,用
如下的方法可以解决,不知是否为最优的解决办法:
在for(;;)里面,accept之前,加上如下的代码:
FD_ZERO(&t_testfd);
FD_SET(iListenFd,&t_testfd);
t_interval.tv_sec = 0;
t_interval.tv_usec = 0;

if(!select(0,&t_testfd,NULL,NULL,&t_interval))
{
if(iListenFd == -1)
break;
else
{
Sleep(1);
continue;
}
}

2、SP_IocpDispatcher的析构有问题:
服务器运行之后,只要有一个连接之后,SP_IocpDispatcher的析构是正常的,但是如果没有任何连接,就析构的话,for( ;
mIsRunning; ) sleep( 1 ); 这儿会是一个死循环,楼主分析一下,找找原因。

On 8月31日, 上午12时14分, "stephen liu" <stephen....@gmail.com> wrote:
> commit 了一些新代码到 svn ,在 SP_Response 中增加了一个 toCloseList ,用于实现 KillSession 的功能。
> 在 testiocpdispatcher.cpp 中增加了一些代码用于示范如何使用。如果有兴趣,可以从 svn 上获得最新的代码。
>
> 2008/8/28 vvou...@gmail.com <vvou...@gmail.com>

vvo...@gmail.com

unread,
Sep 1, 2008, 4:56:15 AM9/1/08
to 高性能网络编程邮件列表
关于前面的第二个问题,SP_IocpDispatcher的析构在没有连接会阻塞的问题,跟踪了一下,发现是在:
DWORD timeout = SP_IocpEventHelper::timeoutNext( eventArg-
>getEventHeap() );
当里面没有event时,timeout = INFINITE,所以就一直阻塞在GetQueuedCompletionStatus这里面了。

lau stephen

unread,
Sep 1, 2008, 6:36:23 AM9/1/08
to dev4s...@googlegroups.com
这第二个问题,看起来还有点麻烦。应该可以通过 push 一个伪事件来唤醒 GQCS 。
对于第一个问题,testiocpdispatcher.cpp 里面的代码的确有不完善的地方。
不过 test 里面的代码,本来也就是为了示范写出来的,大家实际用的时候,main 函数里面的代码可以全部重写过。

2008/9/1 vvo...@gmail.com <vvo...@gmail.com>:

vvo...@gmail.com

unread,
Sep 2, 2008, 1:22:36 AM9/2/08
to 高性能网络编程邮件列表
是的,测试了一下,push一个伪事件已经可以正常的析构了。

On 9月1日, 下午6时36分, "lau stephen" <stephen....@gmail.com> wrote:
> 这第二个问题,看起来还有点麻烦。应该可以通过 push 一个来唤醒 GQCS 。
> 对于第一个问题,testiocpdispatcher.cpp 里面的代码的确有不完善的地方。
> 不过 test 里面的代码,本来也就是为了示范写出来的,大家实际用的时候,main 函数里面的代码可以全部重写过。
>
> 2008/9/1 vvou...@gmail.com <vvou...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages