经过很长时间的修改我的服务器版本从1.0修改到3.6,从一个客户端一个线程到现在的异步方式处理网络,不过在服务器软件开发方面的经验依然不足,希望园子里面的服务器方面的专家些能给些建议:

 

先介绍一下:该服务器的客户端分为PC客户端和车载终端,以下称作客户端和终端。服务器的Session部分需要分别保存客户端和终端状态。以下是我设计的服务器的网络部分:

 

程序运行后通过运行HandleCarHandleUserStartListen函数启动线程来分别接收来自终端和客户端的数据,终端收到一包数据后处理数据:

 

 

由于终端没隔10秒发送一包数据,因此数据量很大,在AnylizeGpsData(state,bufData)中,要通过数据库里面该终端所属线路查找该线路的所有用户(通过Session里面的Socket),然后将数据转发到客户端,并将数据保存到数据库。现在的处理是来一包数据就要去找在线用户,估计这里有问题。

 

现在程序运行起了,出现了一下问题:

1.       现在终端的连接数已经有220(PC客户端很少,可以忽略),当服务器运行1-2天内存就达1个多G,而且运行中观察发现时间越长占用内存越大。

2.       程序里面通过基类的事件通知UI,及时得到上线离线等一些消息,在程序运行几分钟后UI就死掉(线程安全已经考虑)。

3.       数据库是用的SQL Server 2005,当时间越长SQL Server占内存越大,1-2天后内存也达到了1个多G,和前面一样时间越长占内存越大。

 

如前面所说,是否是下面原因引起:

1.       收到一包数据写入数据库一条数据不可避免,但是在转发数据的时候,每次都查询了数据库,加重了数据库的负担?

2.       当一个终端连接上来后创建对象时使用的反射,会不会加重内存负担?

3.       现在的服务器要求是能使终端数量达到2000个,在设计方面应该怎么改进?

4.       占用内存是怎么产生的?如何清理内存?

 

QQ: 279295329

MSN: zhusimu@msn.com

 

posted @ 2009-04-06 17:22 Simens 阅读(1823) 评论(12) 编辑
 
刚刚碰到对DataTable的操作,记录一下两个方法,或许对你有用
 
/// <summary>
/// 给已有DataTable的首列加上序号列
/// </summary>
/// <param name="srcTable">源数据表</param>
/// <returns>结果数据表</returns>
private DataTable GetDataTable(DataTable srcTable)
{
    DataTable dstntnTable = new DataTable();
    dstntnTable.Columns.Add("Id", typeof(Int32));
    for (int i = 0; i < srcTable.Columns.Count; i++)
        dstntnTable.Columns.Add(srcTable.Columns[i].ColumnName, srcTable.Columns[i].DataType);
    int srcColCount = srcTable.Columns.Count;
    int srcRowCount = srcTable.Rows.Count;
    int dstntnRowCount = 0;
    for (int j = 0; j < srcRowCount; j++)
    {
        DataRow newRow = dstntnTable.NewRow();
        newRow[0] = (++dstntnRowCount);
        for (int k = 0; k < srcColCount; k++)
            newRow[k + 1] = srcTable.Rows[j][k];
        dstntnTable.Rows.Add(newRow);
    }
    return dstntnTable;
}
 
/// <summary>
/// 取出指定数据表中指定列数据并在首列加上编号列
/// </summary>
/// <param name="srcTable">源数据表</param>
/// <param name="para">需要取出源数据表的列名</param>
/// <returns>结果数据表</returns>
private DataTable GetDataTable(DataTable srcTable, params string[] para)
{
    DataTable dstntnTable = new DataTable();
    dstntnTable.Columns.Add("Id", typeof(Int32));
    for (int i = 0; i < para.Length; i++)
        dstntnTable.Columns.Add(para[i], srcTable.Columns[para[i]].DataType);
    int srcRowCount = srcTable.Rows.Count;
    int dstntnRowCount = 0;
    for (int j = 0; j < srcRowCount; j++)
    {
        DataRow newRow = dstntnTable.NewRow();
        newRow["Id"] = (++dstntnRowCount);
        for (int k = 0; k < para.Length; k++)
            newRow[para[k]] = srcTable.Rows[j][para[k]];
        dstntnTable.Rows.Add(newRow);
    }
    return dstntnTable;
}
posted @ 2009-02-18 15:55 Simens 阅读(894) 评论(4) 编辑

  快过年了,估计园子里面的朋友们都有想回家的冲动了吧,到年终了我也来写个总结,分享下去年的经历。
  我是去年3月份进入现在所在的公司的,公司是个小公司,做车载GPS设备的,人有40,50人吧,研发部10个人,硬件部6个,软件部4个,我是软件部其中一个。进公司的时候软件部只有两个人,其中一个本来不是做开发的,听说原来申请的职位是做管理方面的,公司缺人就拉进来了。另外一个是做VB开发。产品解决方案是Win CE的硬件设备+.net软件平台。由于所购买的解决方案中软件平台是.net开发,我和我同学是学.net的,他离开公司就推荐我进去了,现在看来都惭愧,在学校的时候也没怎么玩过,和我寝室的同学都很上进,别人看电影,打游戏,我们研究技术,可是在我看来我没多大长进。
  刚进去就是负责编写一个服务器程序:道理很简单,就是将客户端的命令通过服务器端发送到车载终端,或者将车载终端的数据通过服务器端回传到客户端或者数据库,车载终端是通过GPRS网络来通信的。服务器的功能就是转发数据和分解存储数据。可是原来基本没接触过服务器程序,好在有网络和一些朋友或者同学,并研究前员工留下的资料,花了一段时间,总算把服务器程序拼出来了,看起来公司里面就我稍微懂点.net的东西。那时程序的版本是1.0是自己定的,也就是一个线程对应一个客户端或者车载终端的连接,分别进行处理,将所有连接保存到hashtable里面。总是感觉这种做法很欠妥,什么原因我也难以搞明白,估计是基础知识不扎实,后来经过在网上到处搜寻,都说.net下网络应用异步性能比较好,于是我开始琢磨将原来的程序用异步的方式重构,花了一段时间也搞定了,和多线程优势还没体现出来,唯一我感觉的好处就是异步好控制一些。我所用的异步还是最基本的收发数据方式。中间协议修改过一次版本2.0,现在用异步重构后我的版本变成3.0了,估计版本改得太大了,以后的小改动。波波折折的基本能使服务器运行起来,其中有不少问题慢慢修改也比较稳定了,因为连接的数量不多不还没超过100个终端的情况,静观其变吧。在改程序的过程中发现,web开发里面经常都分曾,我想如果我的程序如果分层不是也可以吗,于是我又重构了一次,这次是将UI,网络收发数据处理,数据库操作分开,版本又被我改成3.5了,呵呵,和vs2008的framework版本一样了。目前运行还比较正常,原来全是利用TCP方式收发,讨论后又得将车载终端和服务器端改成UDP方式,因为UDP速度更快,这是过了年来的事情了。
  09年的计划:做一个自己的网站或者博客,坚持web和win32两手抓,域名都买好了:
http://www.lib4net.com/ 名字都能猜出来是想做个和.net相关的。

  PS:我是博客园的忠实读者,虽然我很少发表文章,但我基本天天都会逛上一阵,因为我很菜,不好意思拿出来显摆。希望能交到更多朋友,学到更多知识。

posted @ 2009-01-20 11:09 Simens 阅读(2622) 评论(23) 编辑
  今天看《Pro Net 2.0 Windows Forms And Custom Cortrols In C#》时看到枚举一节,发现了在一个枚举里面需要合并多个值,看到了用到了”|”运算符,原来没怎么注意,今天想了一下为什么用”|”呢?
  MSDN里面看到了这样一句话:“用2的幂(即 1248 等)定义枚举常量。这意味着组合的枚举常量中的各个标志都不重叠。”
  于是写了一个例子:

        [FlagsAttribute]
        
enum Colors_1
        
{
            Red 
= 1, Green = 2, Blue = 4, Yellow = 8
        }
;
        
//测试
        private void button1_Click(object sender, EventArgs e)
        
{
            Colors_1 color_1 
= Colors_1.Red | Colors_1.Green | Colors_1.Blue 
| Colors_1.Yellow;

            
string strResult = color_1.ToString() + " " + ((int)color_1)
.ToString();
            MessageBox.Show(strResult);
        }

输出结果:


咦!  1 + 2 + 4 + 8 = 15 刚刚等于15,难道这是巧合?
全部显示出来了,安逸!

再写个例子试试:

        [FlagsAttribute]
        
enum Colors_2
        
{
            Red 
= 1, Green = 2, Blue = 3, Yellow = 4
        }
;
        
//测试
        private void button1_Click(object sender, EventArgs e)
        
{
            Colors_2 color_2 
= Colors_2.Red | Colors_2.Green | Colors_2.Blue
 
| Colors_2.Yellow;

            
string strResult = color_2.ToString() + " " + ((int)color_2).ToString();
            MessageBox.Show(strResult);
        }

输出结果:

晕,怎么没把颜色全部显示出来呀?
咦!3 + 4 = 7 刚好显示枚举值为3,4的两种颜色

再写一个例子呢?

        //测试
        private void button1_Click(object sender, EventArgs e)
        
{
            Colors_1 c 
= (Colors_1)Enum.Parse(typeof(Colors_1), "7");
            MessageBox.Show(c.ToString() 
+ " " + ((int)c).ToString());
        }

输出结果:

居然会自动转换成相应的枚举值,厉害!

 再来我加个枚举为7的值:

        [FlagsAttribute]
        
enum Colors_1
        
{
            Red 
= 1, Green = 2, Blue = 4, Yellow = 8, Seven = 7
        }
;
        
//测试
        private void button1_Click(object sender, EventArgs e)
        
{
            Colors_1 c 
= (Colors_1)Enum.Parse(typeof(Colors_1), "7");
            MessageBox.Show(c.ToString() 
+ " " + ((int)c).ToString());
        }

输出结果:

印证了MSDN那句话,只有将枚举值设置为0,2,4,8…..这样的只才会叠加,枚举会自动判断当前值,如果枚举里面有这个值当然就显示这个值了;如果没有就做匹配用加法看看那几个数加起来刚好是这个枚举值,但如果有几个数字加起来都等于这个值怎么办呢?还没遇到呢,目前这是我的理解,希望大牛些指教!
posted @ 2008-07-12 15:55 Simens 阅读(2909) 评论(14) 编辑
posted @ 2008-07-12 15:34 Simens 阅读(2145) 评论(8) 编辑
  
    转眼间毕业快一年多了,想想这段时间以来的经历及现在的苦恼,我决定把自己的一些想法跟博客园里面的朋友们分享一下,我现在很迷茫,希望朋友们些能给我一些指点或者建议,不知道我的路在何方?
    大三的时候开始学习.net,当时看见周围几个同学学得火热,马上也要毕业找工作了,感觉要学点专业技术才行,于是也就跟着学.net了。大学里面我学的东西很单一,毕业时还借书证时才发现自己借书总数还没超过50本,这50本书大部分是讲.net的,由于大部分书所讲的内容都差不多,以至后来对.net书籍都没多大兴趣了。学了点.net的基础知识浑浑噩噩的就毕业了。
   毕业后找到的第一份和.net开发相关的工作是家日本公司,这让我有机会尝试了一次用.net来做一个测量汽车转向角的程序,我之所以叫它程序没叫软件,在我看看我做的这个程序顶多算一个小工具而已。这个程序就是调用AD卡生产商提供的接口来控制机械设备的移动,里面用到了两个线程同时移动设备的情况。这是我认为最复杂的情况了。可悲,到现在都没有把多线程的使用搞透彻,只知道基本使用而已。整个程序就一个函数就算完成了,公司里面也就我知道一点.net皮毛,还是硬着头皮把它做完了,没想到那程序在使用过程中一直还不错。
   可能算运气好吧,浑浑噩噩的又进了第二家公司。一来分配的任务是做服务器调度软件开发。我的天!从来没做过这东西,怎么办呢?还好公司买的解决方案里面有一个用C#做的服务器程序,我不知道看了多少遍,终于莫清了来龙去脉。也没做过,只有依葫芦画瓢了。很是不巧,公司又只有我会点C#,没办法啊,要活命!还好这个东东催得不是很急,这画瓢一画就是4个月,哎,昨天联机调试转发数据成功了。大麻烦还在后面呢,图像数据的接受和转发还没做呢,郁闷。
   看起来算是比较成功了,但我总感觉我做的这东西不能算正真的软件。面向对象现在都弄清楚,但自己好像又很了解似的:无非就是把几个对象抽象出来组合组合,再继续组合就要用到高级点的设计模式了。其实我什么也不懂。
   估计本人很愚笨,学.net这么久了还没做过像样点的软件。
   我也想把开发学好,一个人学真的很费劲,看的书已经不少了,为什么感觉没多大进步呢?也许是方法不对吧,再这样下去恐怕也没什么大的提升,但我想在技术的道路上走远一些,各位朋友:能给我提点建议吗?

MSN: zhusimu@msn.com
posted @ 2008-07-11 15:26 Simens 阅读(2160) 评论(50) 编辑
posted @ 2008-06-26 22:20 Simens 阅读(1412) 评论(12) 编辑