eventstream挖矿
Ⅰ flex错误:Error #2044: 未处理的NetStatusEvent是怎么回事
用red5做一个录像程序时,前台的flex一直报这个错,完整的错误信息是:Error #2044: 未处理的 NetStatusEvent:。 level=error, code=NetStream.Record.NoAccess at myWebSite/netStatus()[C:\Users\ASUS\Adobe Flash Builder 4\myWebSite\src\myWebSite.mxml:23]myWebSite.mxml的第23行是netStream=new NetStream(conn);这个错误是在方法:private function netStatus(e:NetStatusEvent):void{ trace(e.info.code); if(e.info.code=="NetConnection.Connect.Success"){ isConnectSuccess=true; netStream=new NetStream(conn); netStream.client=new StreamClient(); netStream.attachAudio(Microphone.getMicrophone()); netStream.attachCamera(Camera.getCamera()); state.text="已经开始录像";}}中报的,netStream=new NetStream(conn);就是报错的行。这个函数是作为连接时的回调函数:conn.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
Ⅱ win7怎样使用kernel streaming
内核流(Kernel Streaming)驱动模型在多媒体方面应用的比较多,支持内核流模型的驱动能够
向系统报告它的性能,以及能够将数据高效,通用的传递。通俗的说,就是可以将摄像头的数据直接传递到显卡中显示,而不需要通过应用层.它可以避免数据在应用层和内核层之间的传递,但是这对于上层来说是透明的;并且采用WDM 内核流模型还可以实现设备无关性,使得程序有很好的移植性和通用性。一般来说,QQ摄像头就是使用基于WDM内核流的组件来实现的。所以可以在打开摄像头的时候轻易的更换为给对方播放影音文件(在上层使用相同的组件和流程,仅仅更换了source filter)。在这里需要指明的是,minidriver一般是可以和硬件设备相关,但是也不一样会和硬件设备相关,它在内核层同样可以调用其他的组件,例如可以实现虚拟摄像头之类的应用。
一般来说,硬件设备会提供一个KsProxy组件,这个组件能够完成一些相应的扩展功能,同时,也可以将数据进行不同类别的传送。上层应用程序能够控制底层数据的流向,而不是将数据拷贝到应用层,然后再传递给内核层处理(这个和DirectX的处理有相似的地方,因为DirectShow曾经也是DirectX的一员)。
虽然现在微软对于流内核结构进行了调整,新的流类型采用的是AVStream(下一次在叙述AVStream框架)。但是从目前来看,很多情况下仍然采用目前的方式来处理数据。
下面通过源代码和数据类型的形式来讲解一下这个驱动程序的框架结构。会尽量屏蔽代码中关于具体设备的细节,专注于描述stream class的流程和结构:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1. 驱动程序的入口点:
NTSTATUS DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING
RegistryPath)
{
HW_INITIALIZATION_DATA HwInitData;
RtlZeroMemory( &HwInitData, sizeof(HW_INITIALIZATION_DATA) );
HwInitData.HwInitializationDataSize = sizeof(HwInitData); // 结构大小
HwInitData.HwInterrupt = NULL; // 硬件回调
HwInitData.HwReceivePacket = MyReceivePacket; // 控制回调
HwInitData.HwCancelPacket = MyCancelOnePacket; // 取消回调
HwInitData.HwRequestTimeoutHandler = MyTimeoutHandler; // 超时回调
HwInitData.DeviceExtensionSize = sizeof(MY_EXTENSION); // 设备扩展
HwInitData.PerStreamExtensionSize = sizeof(STREAMEX); // 流扩展
HwInitData.PerRequestExtensionSize = sizeof(IRB); // SRB大小
HwInitData.FilterInstanceExtensionSize = 0; // 安装大小
HwInitData.BusMasterDMA = FALSE; // 总线DMA
HwInitData.Dma24BitAddresses = FALSE; // DMA地址
HwInitData.BufferAlignment = sizeof(ULONG) - 1; //
HwInitData.TurnOffSynchronization = TRUE;
HwInitData.DmaBufferSize = 0;
// 注册流端口驱动和回调函数
return (StreamClassRegisterAdapter(DriverObject, RegistryPath, &HwInitData));
}
这里可以看得出,驱动入口点基本上只是向stream class注册回调函数和信息。此处的设备
扩展和流扩展需要我们自己定义。
超时回调函数和取消回调函数本身并没有做太过于特殊的事情,关键在于控制命令回调函数,它是接收上层,也就是stream class 发送的控制包,下面会详细的讲解控制命令回调函数:
2. MyReceivePacket函数:
VOID
MyReceivePacket(IN PHW_STREAM_REQUEST_BLOCK pSrb)
{
PIO_STACK_LOCATION IrpStack;
PMY_EXTENSION pDevExt = (PMY_EXTENSION) pSrb->HwDeviceExtension;
PAGED_CODE();
pSrb->Status = STATUS_SUCCESS;
switch (pSrb->Command) {
case SRB_INITIALIZE_DEVICE: // 初始化设备
break;
case SRB_INITIALIZATION_COMPLETE: // 初始化设备完成
break;
case SRB_GET_STREAM_INFO:// 获取设备信息
break;
case SRB_OPEN_STREAM: // 打开流
break;
case SRB_CLOSE_STREAM: // 关闭流
break;
case SRB_SURPRISE_REMOVAL: // 移除设备
break;
case SRB_UNKNOWN_DEVICE_COMMAND: // 未知的命令
break;
case SRB_UNINITIALIZE_DEVICE: // 卸载设备
break;
case SRB_GET_DATA_INTERSECTION: // 获取格式和范围
break;
case SRB_CHANGE_POWER_STATE: // 改变电源状态
break;
case SRB_GET_DEVICE_PROPERTY: // 获取设备属性
break;
case SRB_SET_DEVICE_PROPERTY: // 设置设备属性
break;
case SRB_PAGING_OUT_DRIVER: // ?
break;
default:
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension,
pSrb);
}
可以看出来的是,上层会通过向这个函数发送命令包,来控制设备的行为。这个端口驱动需要
自己决定从什么拷贝来数据,或者怎么向上层回复。
这里stream class的命令中,需要关注地方并不多,由于设备可能会是USB设备/1394设备/网络
组件/图像采集卡,所以很难统一的给出一份具体的代码.但是通过下面的几个命令的讲解,大家
应该很容易的构建出具体设备的代码来:
2.1 初始化命令: 在设备的初始化阶段,stream class 会依次发送下面的命令
SRB_INITIALIZE_DEVICE->SRB_GET_STREAM_INFO->SRB_INITIALIZATION_COMPLETE
一般来说,SRB_INITIALIZE_DEVICE命令主要是初始化设备扩展和属性结构的初始化,
SRB_GET_STREAM_INFO命令则是向注册表写入自己的属性,并提供相应的另一组回调函数给
Stream class,便于接受更微观的控制;SRB_INITIALIZATION_COMPLETE命令一般是一个完成回调
的方式。
下面的代码会揭示在SRB_GET_STREAM_INFO命令时候,一般会进行的处理:
typedef struct _HW_STREAM_HEADER {
ULONG NumberOfStreams; // 支持的流的数目
ULONG SizeOfHwStreamInformation; // 结构大小
ULONG NumDevPropArrayEntries; // 支持的属性数组大小
PKSPROPERTY_SET DevicePropertiesArray; // 属性数组
ULONG NumDevEventArrayEntries; // 支持的事件数组大小
PKSEVENT_SET DeviceEventsArray; // 事件数组
PKSTOPOLOGY Topology; //
PHW_EVENT_ROUTINE DeviceEventRoutine; // 超时时间
ULONG Reserved[2]; // 保留
} HW_STREAM_HEADER, *PHW_STREAM_HEADER;
typedef struct _HW_STREAM_INFORMATION {
ULONG NumberOfPossibleInstances; // 设备支持的流的数量
KSPIN_DATAFLOW DataFlow; // 数据流的方向
BOOLEAN DataAccessible; // 数据释放是否能够被看到
ULONG NumberOfFormatArrayEntries; // 支持的属性信息
PKSDATARANGE* StreamFormatsArray; // 属性信息数组
PVOID ClassReserved[4];
ULONG NumStreamPropArrayEntries; // 流媒体的支持属性数组的下标
PKSPROPERTY_SET StreamPropertiesArray;// 属性数组
ULONG NumStreamEventArrayEntries;
PKSEVENT_SET StreamEventsArray;
GUID* Category; // Pin范围
GUID* Name; // Pin的名字
ULONG MediumsCount;
const KSPIN_MEDIUM* Mediums; // 媒体类型
BOOLEAN BridgeStream; // 允许流进行桥接?
ULONG Reserved[2];
} HW_STREAM_INFORMATION, *PHW_STREAM_INFORMATION;
VOID MyGetStreamInfo(IN PHW_STREAM_REQUEST_BLOCK Srb)
{
PHW_STREAM_HEADER StreamHeader = &(Srb->CommandData.StreamBuffer->StreamHeader);
PMY_EXTENSION pDevExt = (PMY_EXTENSION) Srb->HwDeviceExtension;
PHW_STREAM_INFORMATION StreamInfo = &(Srb->CommandData.StreamBuffer->StreamInfo);
PAGED_CODE();
ASSERT (Srb->NumberOfBytesToTransfer >=
sizeof (HW_STREAM_HEADER) +
sizeof (HW_STREAM_INFORMATION));
RtlZeroMemory(StreamHeader,
sizeof (HW_STREAM_HEADER) +
sizeof (HW_STREAM_INFORMATION));
StreamHeader->NumberOfStreams = 1;
StreamHeader->SizeOfHwStreamInformation = sizeof(HW_STREAM_INFORMATION);
StreamHeader->NumDevPropArrayEntries = pDevExt->ulPropSetSupported;
StreamHeader->DevicePropertiesArray = &pDevExt->VideoProcAmpSet;
StreamInfo->NumberOfPossibleInstances = 1;
StreamInfo->DataFlow = KSPIN_DATAFLOW_OUT;
StreamInfo->DataAccessible = TRUE;
StreamInfo->NumberOfFormatArrayEntries = pDevExt->ModeSupported;
StreamInfo->StreamFormatsArray = &pDevExt->MyStrmModes[0];
StreamInfo->NumStreamPropArrayEntries = NUMBER_VIDEO_STREAM_PROPERTIES;
StreamInfo->StreamPropertiesArray = (PKSPROPERTY_SET) VideoStreamProperties;
StreamInfo->Name = (GUID *) &PINNAME_VIDEO_CAPTURE;
StreamInfo->Category = (GUID *) &PINNAME_VIDEO_CAPTURE;
Srb->CommandData.StreamBuffer->StreamHeader.Topology = &Topology;
Srb->Status = STATUS_SUCCESS;
}
2.2 打开和关闭流: SRB_OPEN_STREAM/SRB_CLOSE_STREAM 命令,此处需要注意的就是一个协商的
过程了,因为此处上层和下层需要来协商进行哪种数据类型的传递。
下面的代码片段屏蔽了硬件的具体相关细节,主要描述和stream class相关的部分:
VOID MyOpenStream(IN PHW_STREAM_REQUEST_BLOCK pSrb)
{
PIRB Irb;
ULONG nSize;
PMY_EXTENSION pDevExt;
PSTREAMEX pStrmEx;
PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormat =
(PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
&pKSDataFormat->VideoInfoHeader;
PAGED_CODE();
Irb = (PIRB) pSrb->SRBExtension;
pDevExt = (PMY_EXTENSION) pSrb->HwDeviceExtension;
pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
// 缓存流扩展
pDevExt->pStrmEx = pStrmEx;
pSrb->Status = STATUS_SUCCESS;
// 确定哪些编号流被打开了。这些编号表明在流信息结构的偏移数组中被调用的
// 流信息适配器
//
// So:
// 0 - Video data from camera
//
// 0 - 从硬件出来的视频数据
switch (pSrb->StreamObject->StreamNumber) {
case 0:
// 检查设备是否在使用
// 找出格式,他们正试图打开第一格式,此处一般采用的是循环对比的方式
// 来找到合适的媒体类型。
if (!AdapterVerifyFormat (pDevExt->ModeSupported, pDevExt->MyStrmModes, pKSDataFormat, pSrb->StreamObject->StreamNumber)) {
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_INVALID_PARAMETER;
return;
}
// 初始化流扩展
InitializeStreamExtension(pDevExt, pSrb->StreamObject, pStrmEx);
// 使用我们的安全版本
if (!NT_SUCCESS(RTL_SAFE_KS_SIZE_VIDEOHEADER(pVideoInfoHdrRequested, &nSize))) {
pSrb->Status = STATUS_INTEGER_OVERFLOW;
return;
}
pStrmEx->pVideoInfoHeader = ExAllocatePoolWithTag(NonPagedPool, nSize, 'macd');
if (pStrmEx->pVideoInfoHeader == NULL) {
ASSERT(pStrmEx->pVideoInfoHeader != NULL);
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
// 拷贝媒体信息头
RtlCopyMemory(
pStrmEx->pVideoInfoHeader,
pVideoInfoHdrRequested,
nSize);
// 分配硬件需要的资源
pSrb->Status = MyAllocateIsochResource(pDevExt, pSrb->SRBExtension, TRUE);
if (pSrb->Status) {
ExFreePool(pStrmEx->pVideoInfoHeader);
pStrmEx->pVideoInfoHeader = NULL;
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
// 提交控制回调/数据回调函数
pSrb->StreamObject->ReceiveDataPacket = (PHW_RECEIVE_STREAM_DATA_SRB) MyReceiveDataPacket;
pSrb->StreamObject->ReceiveControlPacket = (PHW_RECEIVE_STREAM_CONTROL_SRB) MyReceiveCtrlPacket;
if(pDevExt->bDevRemoved || pDevExt->bStopIsochCallback) {
pDevExt->bStopIsochCallback = FALSE;
pDevExt->bDevRemoved = FALSE;
}
// 初始化流扩展句柄信息
break;
default:
ASSERT(FALSE);
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_INVALID_PARAMETER;
return;
}
pSrb->StreamObject->HwClockObject.ClockSupportFlags = 0;
// 我们不使用DMA方式
pSrb->StreamObject->Dma = FALSE;
pSrb->StreamObject->StreamHeaderMediaSpecific = sizeof(KS_FRAME_INFO);
// PIO 必须设置为mini驱动缓冲区使用逻辑寻址,我们不打算控制这部分缓冲区
pSrb->StreamObject->Pio = FALSE;
// 将最后保存配置
(pDevExt, (PIRB) pSrb->SRBExtension);
ASSERT(pSrb->Status == STATUS_SUCCESS);
}
VOID MyCloseStream(IN PHW_STREAM_REQUEST_BLOCK pSrb)
{
PMY_EXTENSION pDevExt;
PSTREAMEX pStrmEx;
PIRB pIrb;
PAGED_CODE();
pSrb->Status = STATUS_SUCCESS;
pDevExt = (PMY_EXTENSION) pSrb->HwDeviceExtension;
ASSERT(pDevExt);
// 等待所有的未决工作完成
KeWaitForSingleObject( &pDevExt->PendingWorkItemEvent, Executive, KernelMode, FALSE, NULL );
pStrmEx = (PSTREAMEX)pDevExt->pStrmEx;
ASSERT(pStrmEx);
if(!pStrmEx ) {
StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
return;
}
// pDevExt->Irb可能被释放了,在HwUninitialize()中
// 由于某个原因,所以必须使用下面的
pIrb = (PIRB) pSrb->SRBExtension;
// 保存设备扩展信息
MySetPropertyValuesToRegistry(pDevExt);
// 释放硬件资源
MyFreeIsochResource (pDevExt, pIrb, TRUE);
if(pStrmEx->pVideoInfoHeader) {
ExFreePool(pStrmEx->pVideoInfoHeader);
pStrmEx->pVideoInfoHeader = NULL;
}
pStrmEx->hMasterClock = 0;
// 如果输入读,那么取消掉它们
if(pDevExt->PendingReadCount > 0) {
if( InterlockedExchange((PLONG)&pStrmEx->CancelToken, 1 ) == 0 ) {
MyCancelAllPackets(
pDevExt,
&pDevExt->PendingReadCount
);
}
}
pDevExt->pStrmEx = 0;
StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
}
2.3 属性设置: 属性设置这一部分实际上都是通过特定的属性表来实现的,它和硬件的相关性很大,一般采用DEFINE_KSPROPERTY_TABLE宏来实现对于属性的封装,这一部分可以查阅相应的资料即可实现。
Ⅲ stream和streamBuffer的区别
buffer
为数据缓冲对象,是一个类似数组结构的对象,可以通过指定开始写入的位置及写入的数据长度,往其中写入二进制数据
stream
是对buffer对象的高级封装,其操作的底层还是buffer对象,stream可以设置为可读、可写,或者即可读也可写,在nodejs中继承了EventEmitter接口,可以监听读入、写入的过程。具体实现有文件流,httpresponse等
Ⅳ 事件流是什么
事件流也叫数据流。数据流最初是通信领域使用的概念,代表传输中所使用的信息的数字编码信号序列。然而,我们所提到的数据流概念与此不同。这里提到的数据流具有以下两个特点能够持续产生大量的数据这类数据最早出现与传统的银行和股票交易领域,也在互联网监控、无线通信网等领域出现、需要以近实时的方式对更新数据流进行复杂分析如趋势分析、预测、监控等。事件流处理是数据流处理的一个子集,是一种特定的数据流处理。事件流处理与一般的数据流处理不同的是事件流处理通常是异步的,事件可能源自不同的地方,而且类型也可能各异,接收的顺序也可能差异很大。事件流处理需要使用事件属性、事件发生的时间以及事件中任何能推断的因果关系作为它的基础元素。事件流模型相对于传统静态数据处理模型主要有如下几方面的特征:
1、事件流中的事件元素在线到达;
2、系统无法控制将要处理的新到达的事件元素的顺序;
3、事件流模型中查询是相对静止不变的,而数据是时刻变化的;
4、从理论上说,事件流的潜在大小是无界的;系统能存储的数据相对事件流的大小则是非常有限的;
5、一旦事件流中的某个元素经过处理,要么被丢弃,要么被归档存储。但被丢弃的事件元素可能需要再次被访问。
Ⅳ 请各位java师哥师姐:"救命啊!救命啊!"急急急!
public static void main(int k, int[][] a) {
int n = 1;
for (int i = 1; i <= k; i++)
n *= 2;
for (int i = 1; i <= n; i++)
a[1][i] = i;
int m = 1;
for (int s = 1; s <= k; s++) {
n /= 2;
for (int t = 1; t <= n; t++)
for (int i = m + 1; i < 2 * m; i++)
for (int j = m + 1; j <= 2 * m; j++) {
a[i][j + (t - 1) * m * 2] = a[i - m][j + (t - 1) * m
* 2 - m];
a[i][j + (t - 1) * m * 2 - m] = a[i - m][j + (t - 1)
* m * 2];
m *= 2;
}
}
System.out.println("你输入了数字" + k);
for (int i = 0; i <= n - 1; i++)
for (int j = 0; j <= n - 1; j++)
System.out.println(a[i][j]);
}
程序我给你改完了,把这个加你的类里就行了,我就那闷你的两个for 循环里怎以都没定义变量呀。
Ⅵ java rtpstream怎么用
1.出现Local Data AddressDoes not belong to any of this hosts local interfaces错误:
主要问题是发送视频和音频的程序需要在服务器上运行,你可以选择Win2000 Server 或者Win2003 Server,问题就解决了。
2.传输声音和视频的方法如下:
a.传输声音或者视频文件
编译完AVTransmit2.java后,再命令提示符中输入命令:java AVTransmit2 file:test.wav 224.224.123.123 22222(注意文件的类型是.wav 或者.mov 、.mpg的文件,不可以是.mp3、.rmvb等其他不支持的文件。传输支持文件格式有限,我也没有办法,应该在添加相关的插件就行了,希望大家提供帮助),其中test.wav即传输的文件名,224.224.123.123为多播地址,22222为端口号.
接收方法:编译完AVReceive.java后,在命令提示符中输入命令:java AVReceive 224.224.123.123/22222即可接受到声音文件
b.传输麦克风的音频,在传输之前先检查电脑录音控制的选项是否为麦克风.(步骤:打开桌面任务栏上的音量控制,选择选项---->属性----->调节音量选择录音,之后在下面的音量控制属性中选中麦克风。单击确定。接着跳到录音控制,选择麦克风就行了)。使用的命令是:java AVTransmit2 dsound:// 224.224.123.123 22222,此时就开始传输声音了。
接收方法同上
c.传输摄相头视频,使用的命令为:java AVTransmit2 vfw://0 224.224.123.123 22222
接收方法同上
d.关于广播、组播和单播
广播:对于局域网广播你可以使用广播的地址,如你的子网掩码是255.255.225.0,即C类的默认子网掩码,你的广播地址可以是192.168.3.255。(注:我的局域网ip地址分配为192.168.3.X)。如子网掩码不同,你可以参照相关的网络常识自己推算。
接收时也使用多播地址来接受,假如发送方的机器地址为:192.168.3.46。发送时在发送放的机器上运行java AVTransmit2 file:test.wav 192.168.3.255 22222,接收时使用java AVReceive2 224.224.123.123 22222。才能完成接收.这和网上的说法不同,端口号不要填错,地址任意。按网上的说法,使用的接收地址应为为192.168.3.46,可是我没有成功,总是出现Local Data AddressDoes not belong to any of this hosts local interfaces的错误,而使用多播地址反而成功了。具体的参数我就不多介绍了,有问题可以给我留言。
组播:使用组播地址发送,组播地址接收即可
单播:假如你只想给某台机子发送,那么就在发送方输入命令,如:java AVTransmit2 file:test.wav 192.168.3.47 22222,这时你只会将声音流文件发送给47号计算机。而接受时还是使用多播地址,如java AVReceive2 224.224.123.123 22222。这是就听到声音了。
总之,使用RTP传输,在接受时都在使用多播地址,在发送时根据情况而定,至于ttl你可以不去管它。不只大家是怎么实现的,反正网上的资料让我变的很失望,真正的成功源于实践。下面摘取一段让大家欣赏(尽信书则不如无书)
网上摘取:
Transmitting Audio and Video over RTP
The AVTransmit2 class is very similar to the VideoTransmit, but uses RTP managers
to send the video and audio streams.
Since the media tracks are transmitted in multiple sessions, you'll need to
use one Player per track on the receive side. Using JMStudio, you can
start multiple Players from the "File" menu using the "New Window"
item. Then either:
use the "Open URL..." item to open one RTP session per track. The URL to use is:
rtp://<sourceIP>:<port>/media
Where <sourceIP> is the IP address of the RTP session and the port
number is the same one that is used on the transmitting side.
OR
Open RTP session and specify <sourcIP> and <port>
How to run this sample
1. Run AVTransmit2 with the required 3 command line parameters
For example, we can use any of the following:
- java AVTransmit2 file:clips/clip01mpg.mpg 224.112.112.112 22222
2. To receive the transmission on the client side use JMStudio:
- use open RTP session and specify group: 224.112.112.112 & port: 22222
AND use FILE -> New Window and open RTP sesssion with port 22224.
OR
- use open URL and specify: rtp://224.112.112.112:22222/video
AND use FILE -> New Window and open URL with 22224/audio
Notes:
You should run 1. then 2., otherwise AVTransmit2 will find the port number used.
You can also use the program to send only audio or video as follows:
- java AVTransmit2 javasound://0 224.112.112.112 22222 (audio only)
- java AVTransmit2 vfw://0 224.112.112.112 22222 (video only)
In such case create only one instance of JMStudio.
Use Unicast:
- java AVTransmit2 file:clip01.mpg 128.82.4.7 22222
Where 128.82.4.7 is the receicver address.
If the sender address is 128.82.4.9 it will use port 22222 as well
to send out data. In this case the receiver (e.g., JMStudio)
should specify the sender as: 128.82.4.9 22222.
Therefore to use unicast you should have two machines since
you can not use the same port for both sender and receiver.
Receiving Audio and Video using RTP
AVReceive2 uses the RTPManager API to receive RTP transmissions.
AVReceive2 performs the following tasks:
Open one RTP session per session address given.
Listen for the NewReceiveStreamEvent from the ReceiveStreamListener.
Create a JMF Player for each stream received for playback.
This sample program can be used in conjunction with JMStudio,
the AVTransmit2 sample or any other RTP compliant transmitter.
The IP address should be the address of the computer which transmits the data; or the multicast address if multicast is being used for the transmission.
The ports should be the same as what's being used by the transmitter.
How to run this sample
1. Run AVTransmit2 with the required 3 command line parameters
For example:
- java AVTransmit2 file:clips/clip01mpg.mpg 224.112.112.112 1234
2. Run AVReceive2 and specify the RTP session addresses to receive from.
For example:
- java AVReceive2 224.112.112.112/1234 224.112.112.112/1236
to simultaneously receive 2 different RTP sessions (video and audio).
Note: because of port reuse, it must run in this order, 1 then 2.
Ⅶ 获取的网页的stream转为string有什么方便的方法
Byte[] pageData = MyWebClient.DownloadData(tbUrl.Text); //从指定网站下载数据
string pageHtml = Encoding.Default.GetString(pageData); //把字节转化为字符串,注意编码方式
2、使用WebBrowser控件
//通过WebBrowser空间访问网页,然后获取网页数据
WebBrowser web = new WebBrowser();
web.Navigate(tbUrl.Text);
web.DocumentCompleted += new (web_DocumentCompleted); //当网页加载完成时触发该事件,获取网页数据
void web_DocumentCompleted(object sender, e){//获取该html页面内的Table标签的内容
WebBrowser web = (WebBrowser)sender;
HtmlElementCollection ElementCollection = web.Document.getElementsByTagName_r("Table");
foreach (HtmlElement item in ElementCollection) {
textBox1.AppendText(item.InnerText + "\n");} }3、使用HttpWebRequest/HttpWebResponse
HttpWebRequest httpReq;
HttpWebResponse httpResp;
Uri httpURL = new Uri(this.tbUrl.Text);
httpReq = (HttpWebRequest)WebRequest.Create(httpURL);
httpResp = (HttpWebResponse)httpReq.GetResponse();
Stream respStream = httpResp.GetResponseStream(); //得到数据流,再把数据流转化为特定的数据(图片,文本。。。)
谢谢亲~
Ⅷ 请教关于TcpClient的问题
TcpClient myClient;
Byte[] RecvBuffer = new Byte[1024];
用开始异步接受数据
myClient.GetStream().BeginRead(RecvBuffer, 0, 1024, new AsyncCallback(GetCommand), null);
private void GetCommand(IAsyncResult ar)
{
int intCount;
try
{
//Lock the Client Stream
lock (myClient.GetStream())
{
//Receive the Bytes
intCount = myClient.GetStream().EndRead(ar);
}
if (intCount < 1)
{
//If a value less than 1 received that means that
//client disconnected
myClient.Close();
//raise the Disconnected Event
}
//Do Something to Do with the Packet
}
//Restart
lock (myClient.GetStream())
{
myClient.GetStream().BeginRead(RecvBuffer, 0, 1024, new AsyncCallback(GetCommand), null);
}
}
catch (Exception ex)
{
}
}
这样就可以不断接收
Ⅸ 如何执行超时 / NSStream,有效地使方法同步等待
我有一个输入的流和输出流的蓝牙连接配件
我想要实现以下目标:
写入数据到 outputStream 等待,直到收到对题目: 下面的数据或直到 10 秒传递如果题目: 下面数据到达其他返回数据返回零
我试着所以执行此类似:
- (APDUResponse *)sendCommandAndWaitForResponse:(NSData *)request {
APDUResponse * result;
if (!deviceIsBusy && request != Nil) {
deviceIsBusy = YES;
timedOut = NO;
responseReceived = NO;
if ([[mySes outputStream] hasSpaceAvailable]) {
[NSThread detachNewThreadSelector:@selector(startTimeout) toTarget:self withObject:nil];
[[mySes outputStream] write:[request bytes] maxLength:[request length]];
while (!timedOut && !responseReceived) {
sleep(2);
NSLog(@"tick");
}
if (responseReceived && response !=nil) {
result = response;
response = nil;
}
[myTimer invalidate];
myTimer = nil;
}
}
deviceIsBusy = NO;
return result;
}
- (void) startTimeout {
NSLog(@"start Timeout");
myTimer = [NSTimer timerWithTimeInterval:10.0 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];
}
- (void)timerFireMethod:(NSTimer *)timer {
NSLog(@"fired");
timedOut = YES;
}
- (void)stream:(NSStream*)stream handleEvent:(NSStreamEvent)streamEvent
{
switch (streamEvent)
{
case :
// Process the incoming stream data.
if(stream == [mySes inputStream])
{
uint8_t buf[1024];
unsigned int len = 0;
len = [[mySes inputStream] read:buf maxLength:1024];
if(len) {
_data = [[NSMutableData alloc] init];
[_data appendBytes:(const void *)buf length:len];
NSLog(@"Response: %@", [_data description]);
response = [[APDUResponse alloc] initWithData:_data];
responseReceived = YES;
} else {
NSLog(@"no buffer!");
}
}
break;
... //code not relevant
}
}
所以理论是有 NSTimer 会设置一个布尔值时它射击,然后 handleEvent 委托方法也有设置另一个 boolean 类型的值如果收到的数据的一个单独的线程上运行。在方法中,我们有一段时间睡一觉,当这些 bool 之一设置时停止循环。
我遇到的问题在 '超时的情况下' 我的 timerFireMethod 不是是越来越叫。我的直觉是我是不实际正确设置计时器在一个单独的线程上。
任何人都可以看看究竟怎么在这里或建议的上述要求的更好实施吗?
解决方法 1:
而是施加不当同步方法本质上异步的问题,使您的方法 sendCommandAndWaitForResponse 异步。
它是可能要包装的"流写入"任务为异步操作/任务/方法。例如,你可能最终与并发子类的 NSOperation 与下面的接口:
typedef void (^DataToStreamCopier_completion_t)(id result);
@interface DataToStreamCopier : NSOperation
- (id) initWithData:(NSData*)sourceData
destinationStream:(NSOutputStream*)destinationStream
completion:(DataToStreamCopier_completion_t)completionHandler;
@property (nonatomic) NSThread* workerThread;
@property (nonatomic, ) NSString* runLoopMode;
@property (atomic, readonly) long long totalBytesCopied;
// NSOperation
- (void) start;
- (void) cancel;
@property (nonatomic, readonly) BOOL isCancelled;
@property (nonatomic, readonly) BOOL isExecuting;
@property (nonatomic, readonly) BOOL isFinished;
@end
您可以实现"超时"功能利用 cancel 方法。
您的方法 sendCommandAndWaitForResponse: 成为异步完成处理程序:
- (void)sendCommand:(NSData *)request
completion:(DataToStreamCopier_completion_t)completionHandler
{
DataToStreamCopier* op = [DataToStreamCopier initWithData:request
destinationStream:self.outputStream
completion:completionHandler];
[op start];
// setup timeout with block: ^{ [op cancel]; }
...
}
用法:
[self sendCommand:request completion:^(id result) {
if ([result isKindOfClass[NSError error]]) {
NSLog(@"Error: %@", error);
}
else {
// execute on a certain execution context (main thread) if required:
dispatch_async(dispatch_get_main_queue(), ^{
APDUResponse* response = result;
...
});
}
}];
警告:
不幸的,执行并发 NSOperation 子类正常使用雇用一个运行的循环的基本任务不是那么微不足道作为它应该是。那里将会出现微妙的并发问题,迫使您可以使用同步基元像锁或调度队列和其他几个技巧,使它真正可靠。
幸运的,换任何运行循环任务并发 NSOperation 子类基本上要求相同的"锅炉板"代码。所以,一旦你有一个通用的解决方案,了编码的工作量是只是复制和粘贴从"模板",然后为您的特定目的定制代码。
替代的解决方案:
严格地说,你甚至不需要一个子类, NSOperation 如果你不打算放入这些任务数 NSOperationQueue 。可以简单地将它发送入门并发操作 start 方法-有没有 NSOperationQueue 所需。然后,不使用类的子类 NSOperation 可以使您自己的实现比较简单,因为子类 NSOperation 本身有其自己微妙之处。
但是,你其实需要换行您运行循环驾驶"操作对象" NSStream 对象,因为执行需要保留状态,不能在一个简单的异步方法完成。
因此,您可以使用任何自定义的类,可以查看作为异步操作有 start 和 cancel 方法和有一种机制来通知调用站点完成基本任务。
也有更强大的手段来通知调用站点比完成处理程序。例如: 承诺或期货 (见 wiki 文章期货和承诺)。
假设作为一种手段,例如通知调用站点,实现您自己的"异步操作"类的承诺:
@interface WriteDataToStreamOperation : AsyncOperation
- (void) start;
- (void) cancel;
@property (nonatomic, readonly) BOOL isCancelled;
@property (nonatomic, readonly) BOOL isExecuting;
@property (nonatomic, readonly) BOOL isFinished;
@property (nonatomic, readonly) Promise* promise;
@end
你原来的问题会更多"同步"-尽管正在异步的窗台:
您 sendCommand 方法将成为:
注:假定承诺类的某些实现:
- (Promise*) sendCommand:(NSData *)command {
WriteDataToStreamOperation* op =
[[WriteDataToStreamOperation alloc] initWithData:command
outputStream:self.outputStream];
[op start];
Promise* promise = op.promise;
[promise setTimeout:100]; // time out after 100 seconds
return promise;
}
注:承诺已设置"超时"。这基本上注册一个计时器和一个处理程序。如果之前承诺的底层任务获取解决激发计时器,计时器块解析超时错误的诺言。如何 (和如果) 这实施取决于承诺图书馆。(在这里,我假设的 RXPromise 库,我在哪里作者。其他执行也可以实现这种功能)。
用法:
[self sendCommand:request].then(^id(APDUResponse* response) {
// do something with the response
...
return ...; // returns the result of the handler
},
^id(NSError*error) {
// A Stream error or a timeout error
NSLog(@"Error: %@", error);
return nil; // returns nothing
});
替代用法:
您可能会以不同的方式设置超时时间。现在,假设我们没有设置超时时间内的 sendCommand: 方法。
我们可以设置"外部"超时:
Promise* promise = [self sendCommand:request];
[promise setTimeout:100];
promise.then(^id(APDUResponse* response) {
// do something with the response
...
return ...; // returns the result of the handler
},
^id(NSError*error) {
// A Stream error or a timeout error
NSLog(@"Error: %@", error);
return nil; // returns nothing
});
使异步方法同步
通常,你不需要和不应该"转换"的异步方法的几种同步方法在应用程序代码中。这总是导致次优和效率低下的代码不必要地消耗系统资源,线程类似。
然而,你可能会想要这样做是有意义的单元测试中:
"同步"在单元测试中的异步方法的示例
测试您的实施时, 经常要"等待"(是同步) 的结果。你基础的任务实际上正在运行的循环,执行这一事实可能在相同的线程要等待结果的位置,不会使解决方案更简单。
但是,您可以轻松完成此与 RXPromise 图书馆利用 runLoopWait 方法该方法有效地进入运行的循环并没有等待解决的承诺:
-(void) {
Promise* promise = [self sendCommand:request];
[promise setTimeout:10];
[promise.then(^id(APDUResponse* response) {
// do something with the response
XCTAssertNotNil(response);
return ...; // returns the result of the handler
},
^id(NSError*error) {
// A Stream error or a timeout error
XCTestFail(@"failed with error: %@", error);
return nil; // returns nothing
}) runLoopWait]; // "wait" on the run loop
}
在这里,方法 runLoopWait 将输入一个运行的循环,并等待的承诺得到解决,由一个超时错误或底层任务已解决承诺的时候。承诺将不会阻塞主线程和不轮询运行的循环。它只是将留下运行的循环时承诺已得到解决。其他运行的循环事件将会像往常一样处理。
注:您可以安全地调用 从主线程不会阻止它。而这是绝对必要的因为你流委托方法可能太在主线程上执行 !
有其他方法通常在单元测试库,其中提供类似的功能来异步方法或操作,而进入运行的循环的结果"等待"中找到。
不建议使用其他方法以异步方法或操作的最终结果为"等待"。这些通常会派遣到私人的线程的方法,然后阻止它,直到结果可用。
有用资源
操作像类,将流复制到另一个流利用的承诺 (上要点) 的代码段: RXStreamToStreamCopier
Ⅹ 急求ATI-stream-sdk-v2.1-win7驱动,比特挖矿用的。。
推荐你在电脑上安装驱动人生6,可以为你检测电脑、打印机的硬件情况、系统环境以及驱动安装情况,并为你推荐合适的驱动以及更新;
并提供下载和安装,你根据提示进行操作即可
打印机可以通过局域网自动检测安装哟