63分,一个客户端下线,导致服务器以为另一个客户端也会下线。 本帖最后由 liulin2017 于 2012-07-30 12:23:26 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1 如果怀疑CSpanTime,可以直接用time()这个函数,time(NULL)就是取自1970年1月1日0点到当前的秒数,两次之差就是时间间隔,比CSpanTime方便。2 debug时看另一个客户端的theLastTalkTime有没有变化。如果没有变化,就是每次更新值的时候没保存。“一个客户端故意下线, 导致服务器以为另一个客户端也会下线,我跟踪代码了。另一个客户端一直在发心跳包”。另一个客户端在发,服务器收到没有?如果收到了,那就是超时检测有问题。如果没有收到,那是你close socket的时候,不小心影响到了这个客户端。不过,如果socket 断了,心跳应该发不出去。所以,最后的应该是超时的时间计算的问题。按上面说的,每次打印出theLastTalkTime值。 大致问题在这:if(iter!=pThis->on_line_userMap.end()) { //找到,更新时间 iter->second->theLastTalkTime=GetCurrentTime(); }如果没找到,你应该new一个user出来,否则这个socket一直给你发消息,你不处理他,自然就下线了。还有,iter->second->theLastTalkTime=GetCurrentTime();之后,下次循环回来,你看数值记住没有? 如果做服务器端编程,建议使用libUV(windows下是IOCP,高效)或libevent(Windows下是select,一般几千用户够用)。libUV使用最简单,不过建议用vc2010来编译。基本上看上两天就会用了,再看看sample。livUV有源码,先学会使用,再学习他的源码,进步很快。你现在这个处理模型不是很好,线程间容易出问题。 问题我已经解决了,不是算你的那个,而是find的参数传错了我问其他问题请教服务器编程,是不是都不需要自己写,而是借助第三方的库 特供调试多线程代码使用:#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef WIN32 #include <windows.h> #include <io.h>#else #include <unistd.h> #include <sys/time.h> #include <pthread.h> #define CRITICAL_SECTION pthread_mutex_t #define _vsnprintf vsnprintf#endif//Log{#define MAXLOGSIZE 20000000#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))#include <time.h>#include <sys/timeb.h>#include <stdarg.h>char logfilename1[]="MyLog1.log";char logfilename2[]="MyLog2.log";char logstr[16000];char datestr[16];char timestr[16];char mss[4];CRITICAL_SECTION cs_log;FILE *flog;#ifdef WIN32void Lock(CRITICAL_SECTION *l) { EnterCriticalSection(l);}void Unlock(CRITICAL_SECTION *l) { LeaveCriticalSection(l);}#elsevoid Lock(CRITICAL_SECTION *l) { pthread_mutex_lock(l);}void Unlock(CRITICAL_SECTION *l) { pthread_mutex_unlock(l);}#endifvoid LogV(const char *pszFmt,va_list argp) { struct tm *now; struct timeb tb; if (NULL==pszFmt||0==pszFmt[0]) return; if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0; ftime(&tb); now=localtime(&tb.time); sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday); sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec ); sprintf(mss,"%03d",tb.millitm); printf("%s %s.%s %s",datestr,timestr,mss,logstr); flog=fopen(logfilename1,"a"); if (NULL!=flog) { fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr); if (ftell(flog)>MAXLOGSIZE) { fclose(flog); if (rename(logfilename1,logfilename2)) { remove(logfilename2); rename(logfilename1,logfilename2); } flog=fopen(logfilename1,"a"); if (NULL==flog) return; } fclose(flog); }}void Log(const char *pszFmt,...) { va_list argp; Lock(&cs_log); va_start(argp,pszFmt); LogV(pszFmt,argp); va_end(argp); Unlock(&cs_log);}//Log}int main(int argc,char * argv[]) { int i;#ifdef WIN32 InitializeCriticalSection(&cs_log);#else pthread_mutex_init(&cs_log,NULL);#endif for (i=0;i<10000;i++) { Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__); }#ifdef WIN32 DeleteCriticalSection(&cs_log);#else pthread_mutex_destroy(&cs_log);#endif return 0;} 求最简单的USB通信实现代码 APP的InitInstance()是做什么的? 求助:CRichEditCtrl编辑框 如何设置背景色透明度呢 关于Visual stdio 6.0 执行的问题! 很简单的一个问题! Directshow 播放多路视频 ip helper api相关的那个三个头文件,有的能不能发一份给我,必重谢!!! 为什么总是少加一条记录 每次WM_PAINT消息来了,都是利用GDI从硬盘读取位图,来重绘窗口区域,为什么重绘这么流畅的? this指针 使用SendMessage给按钮发信息,被遮挡后不响应 关于模板类型的简单问题!
2 debug时看另一个客户端的theLastTalkTime有没有变化。如果没有变化,就是每次更新值的时候没保存。“一个客户端故意下线, 导致服务器以为另一个客户端也会下线,我跟踪代码了。另一个客户端一直在发心跳包”。另一个客户端在发,服务器收到没有?如果收到了,那就是超时检测有问题。如果没有收到,那是你close socket的时候,不小心影响到了这个客户端。不过,如果socket 断了,心跳应该发不出去。
所以,最后的应该是超时的时间计算的问题。按上面说的,每次打印出theLastTalkTime值。
if(iter!=pThis->on_line_userMap.end())
{
//找到,更新时间
iter->second->theLastTalkTime=GetCurrentTime();
}
如果没找到,你应该new一个user出来,否则这个socket一直给你发消息,你不处理他,自然就下线了。
还有,iter->second->theLastTalkTime=GetCurrentTime();之后,下次循环回来,你看数值记住没有?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define _vsnprintf vsnprintf
#endif
//Log{
#define MAXLOGSIZE 20000000
#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
char logstr[16000];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb; if (NULL==pszFmt||0==pszFmt[0]) return;
if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
flog=fopen(logfilename1,"a");
if (NULL==flog) return;
}
fclose(flog);
}
}
void Log(const char *pszFmt,...) {
va_list argp; Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
int main(int argc,char * argv[]) {
int i;
#ifdef WIN32
InitializeCriticalSection(&cs_log);
#else
pthread_mutex_init(&cs_log,NULL);
#endif
for (i=0;i<10000;i++) {
Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);
}
#ifdef WIN32
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}