聂磊's profile学习园地BlogLists Tools Help

聂磊 聂磊

Occupation
Location
No list items have been added yet.

学习园地

学习可是件严肃的事情,来不得半点马虎!
January 14

Flex/AS 3 memory leak

从目前情况看,Flex 3(AS3)存在严重的memoy leak(内存泄露)问题,这些问题中一部分可以合适的编码方式来避免,还有一些问题目前只有等待Flex SDK更新了。

感觉Flex 的商业应用目前只能在初级阶段。

      列举一些产生memoy leak的情景。

  (1)Event Listeners

                Listening to parent objects does cause memory leaks

                e.g.

                    override protected function mouseDownHandler(…):void {
                     systemManager.addEventListener(“mouseUp”, mouseUpHandler);

              you can:

                1.Removing the addEventListener (when dispose).

                  systemManager.removeEventListener(“mouseUp”, mouseUpHandler);

                2. Use of weak reference listeners

                  override protected function mouseDownHandler(…):void {
                  systemManager.addEventListener(“mouseUp”, mouseUpHandler, false, 0, true);

              These do not block garbage collection(generally do not cause memory leaks):

    1. Weak References
    2. Self References
    3. References to Child Objects

                    weak reference event listener  e.g.

                      someObject.addEventListener(MouseClick.CLICK, handlerFunction, false, 0, true);

                   Self References  e.g.

                       this.addEventListener(MouseClick.CLICK, handlerFunction);

                   childObject event listener e.g.

        private var childObject:UIComponent = new UIComponent;
        addChild(childObject);
        childObject.addEventListener(MouseEvent.CLICK, clickHandler);

           建议对所有addEventListener都要removeEventListener,或是使用Weak References .

 

         Reference :

          http://blogs.adobe.com/aharui/2007/03/garbage_collection_and_memory.html

           http://www.dreamingwell.com/articles/archives/2008/05/understanding_m.php    

        

(2)   static members

           e.g.

          Class (或MXML)中有:

           public static var _eventService : MyService=new MyService();

          在dispose时,需要设置:

          _eventService =null;

        

(3)module (未解决)

          moduleLoader unloadModule后

         ModuleInfo 并不会被GC.

         Garbage Collection in a MultiCore Modular Pipes Application

        这篇文章介绍了一种GC策略,感觉对于ModuleInfo 的GC无效。

 

(4)CSS Style

          module 中如果使用了shell的CSS定义或是<mx:Style> 这样的定义,那么这个module将不能GC.

          弹出的窗口应该是同样的结果.

         解决方法,使用动态CSS文件

       module   init中

         StyleManager.loadStyleDeclarations("css/myStyle.swf");

      module  dispose中

         StyleManager.unloadStyleDeclarations("css/myStyle.swf");  

 

(5)TextInput/Textarea(未解决)

          如果module中有window使用了TextInput/Textarea控件,不点击没有问题,只要点上去,那么很遗憾了,module和所在窗体将不能被GC.

         这个BUG非常严重,目前还没有解决方法。

         memory leak when using TextInput and TextArea when click the keyboard这里面附加的解决方法无效。

        通过profiler分析,应该和Focusmanager有关,只有一点击就不会释放。

 

(6)CursorManager.setCursor

        使用了

          cursorID = CursorManager.setCursor(iconClosed);

         dispose时要

           CursorManager.removeCursor(cursorID);

 

(7)Bitmap

           如果使用Bitmap,结束时需要调用其dispose方法,否则内存消耗巨大。

var bmp:Bitmap  =new Bitmap();

........

if (bmp.bitmapData!=null) {
bmp.bitmapData.dispose();
}

 

(8) 其他

          binding也疑似有memor leak 问题。

         ......

         感觉Flex/AS 3离商业开发还有很长的路要走

January 04

S900两种硬启动

方法1 开机状态下按下 音量down+确认键+reset键(笔槽内的小红点),进入三色屏,三色屏提示1,2,3选择,按音量up键 便可进入reset。之后机子自动重启一次,然后屏幕调整,请注意:使用手写笔,按照屏幕提示在十字键位置点击,不可乱按!否则永远进不了下一步!

方法2 关机状态下 按下 音量down+确认键+电源键,进入三色屏,后操作同上。
July 20

visudo

sudo passwd root

设置root密码再试试
June 23

Flex使用XMLSocket与后台通信

一;flash 直接 使用 XMLSocket 链接 Java 后台(或其他后台)。直接打开flash,不在网页里头的话,就不需要考虑安全性的问题了,当然这不实用。只是个简单的XMLSocket的例子。

mxml文件代码

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="init()">
<mx:Script>
   <![CDATA[
    private var socket:XMLSocket = null;
    private var response:XML;
    private var host:String;
    private var port:uint;
    private function init():void{
     host = "localhost";
     port = 9000;   
     socket = new XMLSocket();
     configureListeners(socket);   
     socket.connect(host, port);
    }

private function configureListeners(dispatcher:IEventDispatcher):void{
     //给 socket 添加事件
     dispatcher.addEventListener(Event.CLOSE, closeHandler);
             dispatcher.addEventListener(Event.CONNECT, connectHandler);
             dispatcher.addEventListener(DataEvent.DATA, dataHandler);
             dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
             dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
             dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
             
                }

private function connectHandler(event:Event):void{
     socket.send("<test/>\n");
         if (socket.connected)
         {
           // 发送 请求

           }
         else
         {
            // 处理 连接失败
           }
    }

private function dataHandler(event:DataEvent):void{
     var response:XML = new XML(event.data);   

}

.....

]]>
</mx:Script>
<mx:Button x="182" y="173" label="Send" click="Onsend()"/>

</mx:Application>

代码限于篇幅不完整,但是基本的都有了,我这里 首先 创建了一个 xmlsocket,添加事件监听后, 我首先执行的是 socket.connect(host, port); ,这句是连接到指定的端口,它连接成功后的回调事件是Event.CONNECT,可以看到 我在 Event.CONNECT 的 事件里面 socket.send("<test/>\n"); 这是 端口连接成功后 尝试发送 消息,后面跟着判断 是否连接成功, 如果连接成功,再发送 真正的消息。消息发送成功后的回调事件是 DataEvent.DATA 。

至于java后台那边只是做一个 监听,处理 socket,就不再讲述了,

2,网页里的flash 使用xmlsocket。

网页里面就需要考虑安全性的问题,因为默认是不允许访问的,但是我们给他一个安全文件让它可以访问,具体步骤是;

还是看 上面的代码,socket.connect(host, port); 这句话,其实质是 向java 后台发送了一个 内容为 <policy-file-request/> 的字符串, 所以 只要接收到这个消息, 那说明是 flash 第一次 访问到 端口。java我们这样写;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Listener extends Thread{

public void run()
{
   try {
    ServerSocket serverSocket = new ServerSocket(9000);
    while(true)
    {
     Socket socket = serverSocket.accept();
     System.out.println(" runing on Listener");
     BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
     PrintWriter pw = new PrintWriter(socket.getOutputStream());    
     char[] by = new char[22];
                    br.read(by,0,22);
                    String head = new String(by);
                    System.out.println("head = " + head + "");
                    if("<policy-file-request/>".equals(head))    
                    {
      // 首次连接,给 flash返回 安全标志
      String xml = "<cross-domain-policy>";
      xml += "<allow-access-from domain=\"localhost\" to-ports=\"9000\" />";
      xml += "</cross-domain-policy>";
      pw.print(xml + "\0");
      pw.flush();     
      System.out.println(xml);
                    }
     else
     {
      // 进到 这里的消息,肯定都是 flash那边我们自己发的消息过来的,这里再继续处理消息。我把socket交给另外一个线程去读取处理
      PushThread thread = new PushThread(socket);
      thread.start();
     }
    }
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
}

}

在看 上面写的 mxml 里面的代码, 在 第一次 connect 之后 我还做了个 socket.send("<test/>\n");
就有意义了, 因为 socket.connect 这个连接不会有安全性问题,这个连接后 java给flash返回了安全标志,然后flash这边要再确认下,这个安全标志是否有效,所以我 socket.send("<test/>\n"); 再测试了下,如果能连接上, 则再发送真正有用的消息。

tomcat默认密码

 
在X:\tomact5.5\conf\tomact_user.xml     
Xml代码
< ?xml     version=' 1.0'     encoding=' utf-8'?>         
 <tomcat-users>         
         <role     rolename=" tomcat"/>         
         <role     rolename=" role1"/>         
         <role     rolename=" manager"/>         
         <role     rolename=" admin"/>         
         <user     username=" tomcat"     password=" tomcat"     roles=" tomcat"/>         
         <user     username=" both"     password=" tomcat"     roles=" tomcat,role1"/>         
         <user     username=" role1"     password=" tomcat"     roles=" role1"/>         
后面加上一条就可以了            

<user     username=" admin"     password=" admin"     roles=" admin,manager"/>         
 < /tomcat-users>       
后加的是意思是设置admin和manager的用户名和密码为admin

MySQL 1130 错误

登入mysql后,更改 "mysql" 数据库里的 "user" 表里的 "host" 项,从"localhost"改称"%"

【转】Flash Socket安全问题的全面解析

 

1、问题描述

      将flash 发布为html格式后,加载页面后,swf 无法与服务器 进行socket 通信。Flash端显示的错误为:
securityErrorHandler信息: [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048"]

      在服务器端显示的信息是由客户端尝试进行连接,但是无法接受数据 。接受的数据显示为空。

2.问题原因:

        最新的Flash player 9.0.124.0,当flash文件 要进行socket通信的时候,需要向服务器端获取crossdomain.xml 文件。如果找不到就出现客户端无法连接服务器的现象。

了解flash发起socket通信的三个过程

      当封装在页面的flash发起socket通信请求的时候会先寻找服务器端的843端口,获取Crossdomain.xml文件,当服务器没有开启 843的时候,flashPlayer会检查发起请求的swf文件中中有没有使用Security.loadPolicyFile来加载策略文件 Crossdomain.xml,如果还是没有就会看这个发起请求的swf要连接的目标端口有没有策略文件。如果都没有那么连接失败,返回如上的出错提示。

为什么老版本的Flash player没有这个问题?

      从一些官方的一些资料中了解了一下。以前的Flash Player无论你采用urlRequest的http请求方式或者xmlsocket socket方式,他们都共用一个安全策略文件。这个策略文件只要你放在主域的目录下就行了。而现在不行了,现在的策略文件如果你使用http请求方式那么需要把策略文件放在目录下面,如果你使用socket请求方式就必须通过socket端口来接收这个策略文件。

      对应调用的方式为:
      http请求——》Security.loadPolicyFile(“http://www.xxx.com/crossdomain.xml ”)
      socket或xmlsocket请求——》Security.loadPolicyFile(“xmlsocket://www.xxx.com:port”)

怎么将Socke策略文件发给Flash Player

      Flash Player在你的socket.connect("domain",port)运行 之前,会按照前面描述的三个过程向你的socket服务器的843端口(据说Adobe已经向相关管理机构申请保留843端口给Flash Player用)发送一个字符串 "<policy-file-request/>",这个时候如果你有一个服务在监听843端口那么收到这个字符串之后,直接按照XML格式发回策略文件就解决了。(注意发回的时候记得加一个截止字符"\0")

    当然你也可以不用843端口自己设置一个端口。因为Flash Player如果在843端口得不到信息,就会检查你是否在你的Flash文件里面自己添加了指定的获取通道,你可以定义一个自己的端口。不过这个时候你不能用http方式,而要用xmlsocket方式。(相当于自动帮你新建了一个xmlsocket对象,然后链接你指定的主机和端口)。比如你想用 1234端口可以在你的Flash里面加这一句 Security.loadPolicyFile(“xmlsocket://www.xxx.com:1234”),需要注意的是这一句要加在你的 socket.connect前面。

    还有最后一个办法,就是在你的socket连接端口监听这个请求。比如你用的是 socket.connect("192.168.1.100",8888),那么在你的服务器加一段接收字符串"<policy-file- request/>"的代码,当接到这个字符串时将策略文家按照xml格式发到客户端。

关于策略文件的格式(可以在Flash CS3帮助里面的Flash Player安全性——》控制权限概述中找到)

1、针对web应用的策略文件

下面的示例显示了一个策略文件,该文件允许访问源自 *.iflashigame.com 和 192.0.34.166 的 SWF 文件。

<?xml version="1.0"?>
<cross-domain-policy>
    <allow-access-from domain="*.iflashigame.com" />
    <allow-access-from domain="192.0.34.166" />
</cross-domain-policy>

注意事项:
      默认情况下,策略文件必须命名为 crossdomain.xml,并且必须位于服务器的根目录中。但是,SWF 文件可以通过调用 Security.loadPolicyFile() 方法检查是否为其它名称或位于其它目录中。跨域策略文件仅适用于从其中加载该文件的目录及其子目录。因此,根目录中的策略文件适用于整个服务器,但是从任意子目录加载的策略文件仅适用于该目录及其子目录。

      策略文件仅影响对其所在特定服务器的访问。例如,位于 https://www.adobe.com:8080/crossdomain.xml 的策略文件只适用于在端口 8080 通过 HTTPS 对 www.adobe.com 进行的数据加载调用。

2、针对Socket的策略文件

<cross-domain-policy>
   <allow-access-from domain="*" to-ports="507" />
   <allow-access-from domain="*.example.com" to-ports="507,516" />
   <allow-access-from domain="*.example2.com" to-ports="516-523" />
   <allow-access-from domain="www.example2.com" to-ports="507,516-523" />
   <allow-access-from domain="www.example3.com" to-ports="*" />
</cross-domain-policy>

这个策略文件是指定允许哪些域的主机通过那些端口链接。

参考文章

flash xmlsocket policy 问题
Policy file changes in Flash Player 9
Setting up a socket policy file server
Understanding Flash Player 9 April 2008 Security Update compatibility

获取策略文件的Java服务器端代码

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SecurityXMLServer implements Runnable {

   private ServerSocket server;
   private BufferedReader reader;
   private BufferedWriter writer;
   private String xml;
   
   public SecurityXMLServer()
   {
     String path = "policyfile文件路径";
     //此处的换成相应的读取xml文档的方式如dom或sax
     //xml = readFile(path, "UTF-8");
       /**
         注意此处xml文件的内容,为纯字符串,没有xml文档的版本号
        */
     xml="<cross-domain-policy> "
        +"<allow-access-from domain=\"*\" to-ports=\"1025-9999\"/>"
     +"</cross-domain-policy> ";
     System.out.println("policyfile文件路径: " + path);
     System.out.println(xml);
     
     //启动843端口
     createServerSocket(843);
     new Thread(this).start();
   }

   //启动服务器
   private void createServerSocket(int port)
   {
     try {
       server = new ServerSocket(port);
       System.out.println("服务监听端口:" + port);
     } catch (IOException e) {
       System.exit(1);
     }
   }

   //启动服务器线程
   public void run()
   {
     while (true) {
       Socket client = null;
       try {
        //接收客户端的连接
         client = server.accept();

         InputStreamReader input = new InputStreamReader(client.getInputStream(), "UTF-8");
         reader = new BufferedReader(input);
         OutputStreamWriter output = new OutputStreamWriter(client.getOutputStream(), "UTF-8");
         writer = new BufferedWriter(output);

         //读取客户端发送的数据
         StringBuilder data = new StringBuilder();
         int c = 0;
         while ((c = reader.read()) != -1)
         {
           if (c != '\0')
             data.append((char) c);
           else
             break;
         }
         String info = data.toString();
         System.out.println("输入的请求: " + info);
         
         //接收到客户端的请求之后,将策略文件发送出去
         if(info.indexOf("<policy-file-request/>") >=0)
         {
           writer.write(xml + "\0");
           writer.flush();
           System.out.println("将安全策略文件发送至: " + client.getInetAddress());
         }
         else
         {
           writer.write("请求无法识别\0");
           writer.flush();
           System.out.println("请求无法识别: "+client.getInetAddress());
         }
         client.close();
       } catch (Exception e) {
         e.printStackTrace();
         try {
           //发现异常关闭连接
           if (client != null) {
             client.close();
             client = null;
           }
         } catch (IOException ex) {
           ex.printStackTrace();
         } finally {
           //调用垃圾收集方法
           System.gc();
         }
       }
     }
   }
   
   //测试主函数
   public static void main(String[] args)
   {
     new SecurityXMLServer();
   }
}

Mysql的2003错误

在一台新的server上装了MySQL,发现本地可以访问,远程无法访问,报2003错误。
尝试了若干种解决方案,发现是Windows的firewall的原因,注意是操作系统的防火墙,
不是杀毒软件的防火墙!
解决方案:
1.关掉Windows Firewall,此举有风险,操作需谨慎!
2.Add Exceptions Port
May 14

如何改变MySQL数据文件路径

首先在数据库里看一下数据库里当前数据文件的存放路径:

mysql> show variables like '%dir%';
+----------------------------+----------------------------+
| Variable_name | Value |
+----------------------------+----------------------------+
| basedir | / |
| character_sets_dir | /usr/share/mysql/charsets/ |
| datadir | /data/mysql/ |
| innodb_data_home_dir | |
| innodb_log_arch_dir | |
| innodb_log_group_home_dir | ./ |
| innodb_max_dirty_pages_pct | 90 |
| slave_load_tmpdir | /tmp/ |
| tmpdir | /tmp/ |
+----------------------------+----------------------------+

如果你觉得这个路径可以的话,就不用去修改了。如果觉得不满意的话,也可以修改。

1:service mysql stop

关闭数据库

2:vi /etc/rc.d/init.d/mysql

3: 把 datadir=/var/lib/mysql 这里改成你想要的。就OK了

4:service mysql start

April 17

python中的字符串操作

#Python字符串操作
'''1.复制字符串'''
#strcpy(sStr1,sStr2)
sStr1 = 'strcpy'
sStr2 = sStr1
sStr1 = 'strcpy2'
print sStr2
'''2.连接字符串'''
#strcat(sStr1,sStr2)
sStr1 = 'strcat'
sStr2 = 'append'
sStr1 += sStr2
print sStr1
'''3.查找字符'''
#strchr(sStr1,sStr2)
sStr1 = 'strchr'
sStr2 = 'r'
nPos = sStr1.index(sStr2)
print nPos
'''4.比较字符串'''
#strcmp(sStr1,sStr2)
sStr1 = 'strchr'
sStr2 = 'strch'
print cmp(sStr1,sStr2)
'''5.扫描字符串是否包含指定的字符'''
#strspn(sStr1,sStr2)
sStr1 = '12345678'
sStr2 = '456'
#sStr1 and chars both in sStr1 and sStr2
print len(sStr1 and sStr2)
'''6.字符串长度'''
#strlen(sStr1)
sStr1 = 'strlen'
print len(sStr1)
'''7.将字符串中的小写字符转换为大写字符'''
#strlwr(sStr1)
sStr1 = 'JCstrlwr'
sStr1 = sStr1.upper()
print sStr1
'''8.追加指定长度的字符串'''
#strncat(sStr1,sStr2,n)
sStr1 = '12345'
sStr2 = 'abcdef'
n = 3
sStr1 += sStr2[0:n]
print sStr1
'''9.字符串指定长度比较'''
#strncmp(sStr1,sStr2,n)
sStr1 = '12345'
sStr2 = '123bc'
n = 3
print cmp(sStr1[0:n],sStr2[0:n])
'''10.复制指定长度的字符'''
#strncpy(sStr1,sStr2,n)
sStr1 = ''
sStr2 = '12345'
n = 3
sStr1 = sStr2[0:n]
print sStr1
'''11.字符串比较,不区分大小写'''
#stricmp(sStr1,sStr2)
sStr1 = 'abcefg'
sStr2 = 'ABCEFG'
print cmp(sStr1.upper(),sStr2.upper())
'''12.将字符串前n个字符替换为指定的字符'''
#strnset(sStr1,ch,n)
sStr1 = '12345'
ch = 'r'
n = 3
sStr1 = n * ch + sStr1[3:]
print sStr1
'''13.扫描字符串'''
#strpbrk(sStr1,sStr2)
sStr1 = 'cekjgdklab'
sStr2 = 'gka'
nPos = -1
for c in sStr1:
if c in sStr2:
nPos = sStr1.index(c)
break
print nPos

'''14.翻转字符串'''
#strrev(sStr1)
sStr1 = 'abcdefg'
sStr1 = sStr1[::-1]
print sStr1
'''15.查找字符串'''
#strstr(sStr1,sStr2)
sStr1 = 'abcdefg'
sStr2 = 'cde'
print sStr1.find(sStr2)
'''16.分割字符串'''
#strtok(sStr1,sStr2)
sStr1 = 'ab,cde,fgh,ijk'
sStr2 = ','
sStr1 = sStr1[sStr1.find(sStr2) + 1:]

本文来自: (www.91linux.com) 详细出处参考:http://www.91linux.com/html/article/program/python/20081127/13983.html