- 论坛徽章:
- 15
|
本帖最后由 yulihua49 于 2010-07-06 15:14 编辑
把你的线程处理函数全部贴出来,我看一下. select没什么问题,相比epoll要简单.
samlumengjun 发表于 2010-07-06 14:18 ![]()
代码在24楼,把39行的死循环限制100次,客户端可以异常退出了。
问题还是出在服务器,多线程select,虽然基本可以正常工作,但忙起来还是会挤掉个别连接。估计也不一定是select,因为正常连接是挤不掉的,只有未登录的连接会被挤掉,看来毛病在我。
在46行挤掉的。
线程工作函数:- #include <sdbc.h>
- #include <bignum.h>
- extern srvfunc Function[]; //user program.
- static void * thread_work(void *param)
- {
- T_Connect Conn=*(T_Connect *)param;
- T_NetHead Head;
- int ret,logined=0;
- T_SRV_Var ctx;
- srvfunc *fp;
- int svcnum=0;
- int (*init)(T_Connect *conn,T_NetHead *head);
- #ifdef __GNUC__
- char gda[Conn.SendLen+1];//本线程的全局数据区必须在此分配。
- #else
- char *gda=alloca(Conn.SendLen+1);
- #endif
- ((T_Connect *)param)->Socket=-1;//通知主线程
- if(Conn.SendLen>0) ctx.var=gda;
- else ctx.var=0;
- Conn.SendLen=0;
- ctx.tid=pthread_self();//标志多线程服务
- ctx.poolno=0;
- ___SQL_Init_SQL_Connect(&ctx.SQL_Connect);
- Conn.Var=&ctx;
- init=Conn.only_do;
- Conn.only_do=0;
- //借用only_do存放函数地址 conn_init
- if(init) init(&Conn,&Head);
- if(!Conn.only_do) for(fp=Function;fp->funcaddr!=0;fp++) svcnum++;
- ShowLog(2,"%s:tid=%lu,sock=%d",__FUNCTION__,ctx.tid,Conn.Socket);
- // 协商密钥
- Conn.CryptFlg=mk_clikey(Conn.Socket,&Conn.t,Conn.family);
- if(Conn.CryptFlg<0) { //协商密钥失败
- ShowLog(1,"%s:tid=%lu 协商密钥失败!",__FUNCTION__,ctx.tid);
- freeconnect(&Conn);
- return NULL;
- }
- while(1) {
- ret=RecvPack(&Conn,&Head);
- if(ret<0) {
- ShowLog(1,"%s:tid=%lu,接收结束,sock=%d,status=%d,%s",
- __FUNCTION__,ctx.tid,Conn.Socket,errno,strerror(errno));
- break;
- }
- ShowLog(4,"%s: tid=%lu,PROTO_NUM:%d len:%d",__FUNCTION__,ctx.tid,
- Head.PROTO_NUM,Head.PKG_LEN);
- if(Head.PROTO_NUM==1){
- Echo(&Conn,&Head);
- continue;
- }
- if(Head.PROTO_NUM==0xFFFF){
- ShowLog(0,"%s:Disconnect by client,tid=%lu",__FUNCTION__,ctx.tid);
- break;
- }
- if(!Head.PROTO_NUM) {
- if(!logined) {//还是一个有状态服务
- logined=Function[0].funcaddr(&Conn,&Head);
- if(logined==-1) break;
- } else {
- if(!Conn.only_do) ret=get_srvname(&Conn,&Head);
- else ret=Conn.only_do(&Conn,&Head);
- continue;
- }
- } else if(Conn.only_do) {
- ret=Conn.only_do(&Conn,&Head);
- continue;
- } else {
- if(Head.PROTO_NUM>svcnum) {
- ShowLog(1,"%s:没有这个服务号 %s",__FUNCTION__,Head.PROTO_NUM);
- break;
- }
- ret=Function[Head.PROTO_NUM].funcaddr(&Conn,&Head);
- if(ret==-1) {
- ShowLog(0,"%s:Disconnect by server PROTO_NUM=%d,ret=%d",
- __FUNCTION__,Head.PROTO_NUM,ret);
- break;
- }
- }
- }
- freeconnect(&Conn);//关闭连接
- mthr_showid_del(ctx.tid);
- return NULL;
- }
复制代码 |
|