利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
2005-03-14 23:43
453 查看
在《多样、互动的WinForm UI设计与开发思路》一文中,我提到过把Flash作为控件嵌入到WinForm程序中以提高软件的互动效果并降低开发难度这样一种思路。但这样一个系统,我们往往不希望随应用程序打包,或者让用户看到,很多很多的FLASH文件。其中一个办法就是把flash文件作为资源嵌入到系统中。但这样又出现一个问题,Flash Player只有一个Movie属性用于指定当前播放的媒体,而这个字符串属性只能是本地文件或者一个URL。我们可以在运行时把资源里的flash释放到一个临时目录,但这样一来失去了打包的意义,二来无法保护flash文件。
我们希望最好的解决方案,就是Flash Player提供类似于DataSet.ReadXml()这样的方法,既可以从指定名字的Xml文件读取数据,又可以从一个数据流(Stream)读数据。但是找遍了Flash Player的所有参数,似乎只有MovieData这个属性有点接近,如果我们能直接把Flash文件的内容赋值给它就好了。不过目前我还没有找到关于这个属性的资料 -_-
另外一个思路,就是在我们的程序运行的时候,动态建立一个自己的http服务器,可以直接从资源中读取内容。事实上,对于大部分要求文件或url形式的内容,都可以通过建立虚拟http服务器来模拟。但实现起来要费点功夫,而且http会在本机留下缓存,安全性不高。
最后在whoo的《从内存播放Flash》一文找到了另外一种方法,就是通过命名管道(Named Pipe)。
首先我们看看命名管道为什么能够解决这个问题。这要从它的运行机制讲起。当一个命名管道被建立起来后,它的服务端和客户端之间的数据交流,就完全是通过和操作文件一样的方式来进行,即CreateFile(),ReadFile()和WriteFile()三个函数。也就是说客户端可以像读取文件一样,来读取管道里的数据。
我们通过调用Win32 API 既可创建管道。这里先简单讲一下服务器端的处理流程:
1、通过CreateNamedPipe()函数创建一个命名管道,如果成功,会返回这个管道实例的句柄。
2、管道创建成功后,调用ConnectNamedPipe()函数等到客户端连接。
3、如果有客户端连接进来,可以通过对文件的操作来交换数据,例如ReadFile()和WriteFile()。
在.NET里我们不必用这些Win32 API函数来读写文件,直接用System.IO命名空间下的类即可(将文件读写的内存指针指向管道句柄即可)。
注:目前该方法只针对在Flash Player播放器打开 \\.\pipe\testPipe 才有效。如果您使用的是Flash Player 7.0,那么一定要用 \\?\pipe\testPipe才行。
至于在html页面或WinForm里的Flash Player控件,指定其Movie属性为"\\.\pipe\testPipe",目前尚无效。
以下是简单的例子:
using System;
using System.IO;
using System;
using System.Runtime.InteropServices;
namespace PipeServer
public class API
public const int INVALID_HANDLE_VALUE = -1;
public const int PIPE_ACCESS_INBOUND = 0x1;
public const int PIPE_ACCESS_OUTBOUND = 0x2;
public const int PIPE_ACCESS_DUPLEX = 0x3;
public const int PIPE_WAIT = 0x0;
public const int PIPE_UNLIMITED_INSTANCES = 255;
[DllImport("kernel32.dll", EntryPoint="CreateNamedPipe")]
public static extern int CreateNamedPipe (
string lpName,
int dwOpenMode,
int dwPipeMode,
int nMaxInstances,
int nOutBufferSize,
int nInBufferSize,
int nDefaultTimeOut,
ref SECURITY_ATTRIBUTES lpSecurityAttributes
);
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES public int nLength;
public int lpSecurityDescriptor;
public int bInheritHandle;
}
[DllImport("kernel32.dll", EntryPoint="ConnectNamedPipe")]
public static extern int ConnectNamedPipe (
int hNamedPipe,
ref OVERLAPPED lpOverlapped
);
[StructLayout(LayoutKind.Sequential)]
public struct OVERLAPPED public int Internal;
public int InternalHigh;
public int offset;
public int OffsetHigh;
public int hEvent;
}
[DllImport("kernel32.dll", EntryPoint="CloseHandle")]
public static extern int CloseHandle (
int hObject
);
[DllImport("kernel32.dll", EntryPoint="DisconnectNamedPipe")]
public static extern int DisconnectNamedPipe (
int hNamedPipe
);
}
}
我们希望最好的解决方案,就是Flash Player提供类似于DataSet.ReadXml()这样的方法,既可以从指定名字的Xml文件读取数据,又可以从一个数据流(Stream)读数据。但是找遍了Flash Player的所有参数,似乎只有MovieData这个属性有点接近,如果我们能直接把Flash文件的内容赋值给它就好了。不过目前我还没有找到关于这个属性的资料 -_-
另外一个思路,就是在我们的程序运行的时候,动态建立一个自己的http服务器,可以直接从资源中读取内容。事实上,对于大部分要求文件或url形式的内容,都可以通过建立虚拟http服务器来模拟。但实现起来要费点功夫,而且http会在本机留下缓存,安全性不高。
最后在whoo的《从内存播放Flash》一文找到了另外一种方法,就是通过命名管道(Named Pipe)。
首先我们看看命名管道为什么能够解决这个问题。这要从它的运行机制讲起。当一个命名管道被建立起来后,它的服务端和客户端之间的数据交流,就完全是通过和操作文件一样的方式来进行,即CreateFile(),ReadFile()和WriteFile()三个函数。也就是说客户端可以像读取文件一样,来读取管道里的数据。
我们通过调用Win32 API 既可创建管道。这里先简单讲一下服务器端的处理流程:
1、通过CreateNamedPipe()函数创建一个命名管道,如果成功,会返回这个管道实例的句柄。
2、管道创建成功后,调用ConnectNamedPipe()函数等到客户端连接。
3、如果有客户端连接进来,可以通过对文件的操作来交换数据,例如ReadFile()和WriteFile()。
在.NET里我们不必用这些Win32 API函数来读写文件,直接用System.IO命名空间下的类即可(将文件读写的内存指针指向管道句柄即可)。
注:目前该方法只针对在Flash Player播放器打开 \\.\pipe\testPipe 才有效。如果您使用的是Flash Player 7.0,那么一定要用 \\?\pipe\testPipe才行。
至于在html页面或WinForm里的Flash Player控件,指定其Movie属性为"\\.\pipe\testPipe",目前尚无效。
以下是简单的例子:
using System;
using System.IO;
using System;
using System.Runtime.InteropServices;
namespace PipeServer
public class API
public const int INVALID_HANDLE_VALUE = -1;
public const int PIPE_ACCESS_INBOUND = 0x1;
public const int PIPE_ACCESS_OUTBOUND = 0x2;
public const int PIPE_ACCESS_DUPLEX = 0x3;
public const int PIPE_WAIT = 0x0;
public const int PIPE_UNLIMITED_INSTANCES = 255;
[DllImport("kernel32.dll", EntryPoint="CreateNamedPipe")]
public static extern int CreateNamedPipe (
string lpName,
int dwOpenMode,
int dwPipeMode,
int nMaxInstances,
int nOutBufferSize,
int nInBufferSize,
int nDefaultTimeOut,
ref SECURITY_ATTRIBUTES lpSecurityAttributes
);
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES public int nLength;
public int lpSecurityDescriptor;
public int bInheritHandle;
}
[DllImport("kernel32.dll", EntryPoint="ConnectNamedPipe")]
public static extern int ConnectNamedPipe (
int hNamedPipe,
ref OVERLAPPED lpOverlapped
);
[StructLayout(LayoutKind.Sequential)]
public struct OVERLAPPED public int Internal;
public int InternalHigh;
public int offset;
public int OffsetHigh;
public int hEvent;
}
[DllImport("kernel32.dll", EntryPoint="CloseHandle")]
public static extern int CloseHandle (
int hObject
);
[DllImport("kernel32.dll", EntryPoint="DisconnectNamedPipe")]
public static extern int DisconnectNamedPipe (
int hNamedPipe
);
}
}
相关文章推荐
- 利用命名管道复制文件
- 测试wcf的http和tcp绑定以及非wcf的命名管道传输文件速度对比
- 利用命名管道方式使主机与虚拟机的串口通讯
- linux学习---linux基于文件的IPC(匿名管道pipe,命名管道mkfifo,普通文件,socket文件)
- linux下利用sed重命名文件
- SQL Server中的命名管道(named pipe)及其使用
- Linux中的pipe与named pipe(FIFO),即管道和命名管道
- 媒体文件audio 转 base64 编码 (利用 FileReader & Audio 对象)
- Linux匿名管道和命名管道模拟实现
- 利用Java反射机制模拟框架利用类加载器加载配置文件
- 利用 Flash 8 上传文件
- 利用命名管道实现进程之间的通信 .........
- 在中Visual Studio .NET 2003利用DirectShow播放媒体文件(四)
- 打开文件linux系统编程之管道(三):命名管道FIFO和mkfifo函数
- perl 利用管道读取压缩文件内容
- [音视媒体制作][教程]利用tmpgenc实现rm,rmvb格式文件的VCD制作
- linux 进程学习笔记-named pipe (FIFO)命名管道
- 利用Android的媒体库,遍历SD卡中的音乐文件,并用Service制作简单的音乐播放
- 利用HttpClient模拟form表单将文件上传到Servlet
- 利用命名管道实现进程之间的通信 .........