基于C局域网视频聊天设计说明

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1绪论
视频监控是各行业重点部门或重要场所进行实时监控的物理基础,管理部门可通过它获得有效数据、图像或声音信息,对突发性异常事件的过程进行与时的监视和记忆,用以提供高效、与时地指挥和高度、布置警力、处理案件等。

本系统采用DirectShow网络组播技术实现了视频捕获、视频压缩、网络传输、视频解码和实时回放,减小了网络带宽占用,高效的传输视频数据,独立于硬件。

可扩展性好。

完全利用现有1P数据网络传输数据.不需要单独布线,显著降低了系统成本,缩短了系统开发周期,并且可以容易的实现远程监测
2 Windows服务
一个Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应用程序。

Windows服务程序虽然是可执行的,但是它不像一般的可执行文件通过双击就能开始运行了,它必须有特定的启动方式。

这些启动方式包括了自动启动和手动启动两种。

对于自动启动的Windows服务程序,它们在Windows启动或是重启之后用户登录之前就开始执行了。

而对于手动启动的Windows服务程序,你可以通过命令行工具的NET START 命令来启动它,或是通过控制面板中管理工具下的服务一项来启动相应的Windows服务程序。

同样,一个Windows服务程序也不能像一般的应用程序那样被终止。

因为Windows服务程序一般是没有用户界面的,所以你也要通过命令行工具或是下面图中的工具来停止它,或是在系统关闭时使得Windows服务程序自动停止。

因为Windows服务程序没有用户界面,为了能使一个Windows服务程序能够正常并有效的在系统环境下工作,程序员必须实现一系列的方法来完成其服务功能。

Windows服务程序的应用围很广,典型的Windows服务程序包含了硬件控制、应用程序监视、系统级应用、诊断、报告、Web和文件系统服务等功能。

2.1添加文件监视服务
将生成的服务名为Webcamservice的服务添加视频监视功能:
➢首先,在C盘创建文件夹w
➢将程序生成的debug中的文件复制到w文件夹
➢在C/windows/搜索installutil.exe执行文件,将其复制到w文件夹
➢启动cmd,打开命令提示符窗体键入如图2-1所示
图2-1 添加服务功能➢用net start命令启动服务Webcamservice如图2-2所示
图2-2启动Webcamservice
3项目的设计原理
3.1 DirectShow技术
采用网络摄像机的远程视频监控具有录像时间长、图像质量好、查询速度快等优点,目前应用非常广泛。

对于网络摄像机传输的视频数据,需要专门的Filter 来处理并在DirectShow 的框架下或回放,或保存。

监控服务器通过Internet/Intranet 轮询网络摄像机获取视频。

本文以视频数据接收Filter 的设计过程介绍基于DirectShow 的视频数据流的传输以与通过自定义的通讯协议的数据解析过程和Filter 程序设计与实现过程。

DirectShow[1]是微软公司在ActiveMovie 和Video for Windows 的基础上推出的基于COM 的流媒体处理的开发包,与DirectX 开发包一起发布。

DirectShow 为多媒体流的捕捉和回放以与二次开发提供了强有力的支持。

运用DirectShow,可以很方便地从支持WDM 驱动模型的采集卡上采集数据,并且调用其API 函数进行后期处理。

它广泛地支持各种媒体格式,包括Asf,Mpeg,Avi,Dv,Mp3,Wave等等,使得多媒体数据的回放变得轻而易举。

DirectShow 是一个开放的框架,因此只要有合适的Filter 来分析和解码,可以支持任何格式。

3.2 TCP/IP协议
在TCP/IP协议组分两种协议:网络层的协议,应用层的协议
➢网络层协议
网络层协议管理离散的计算机间的数据传输。

这些协议是在系统表层以下工作的。

比如,IP协议为用户和远程计算机提供了信息包的传输方法。

它是在许多信息的基础上工作的,好比说是机器的IP地址。

在机器IP地址和其它信息的基础上,IP确保信息包能正确地到达目的机器。

通过这一过程,IP和其它网络层的协议共同用于数据传输。

如果没有网络工具,用户就看不到在系统里工作的IP。

➢应用层协议
相反地,应用层协议用户是可以看得到的。

比如,文件传输协议(FTP)用户是看得到的。

用户为了传输一个文件请求一个和其它计算机的连接,连接建立后,就开始传输文件。

在传输时,用户和远程计算机的交换的一部分是能看到的。

➢IP
IP层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层---TCP或UDP层;相反,IP层也把从TCP或UDP层接收来的数据包传送到更低层。

IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是按顺序发送的或者没有被破坏。

IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址
(目的地址)。

高层的TCP和UDP服务在接收数据包时,通常假设包中的源地址是有效的。

也可以这样说,IP地址形成了许多服务的认证基础,这些服务相信数据包是从一个有效的主机发送来的。

➢TCP
如果IP数据包中有已经封好的TCP数据包,那么IP将把它们向上传送到TCP层。

TCP 将包排序并进行错误检查,同时实现虚电路间的连接。

TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。

TCP将它的信息送到更高层的应用程序,例如Telnet的服务程序和客户程序。

应用程序轮流将信息送回TCP层,TCP层便将它们向下传送到IP层,设备驱动程序和物理介质,最后到接收方。

3.3 C/S架构
在网络连接模式中除对等网外,还有另一种形式的网络,即客户机/服务器网,Client/Server。

在客户机/服务器网络中,服务器是网络的核心,而客户机是网络的基础,客户机依靠服务器获得所需要的网络资源,而服务器为客户机提供网络必须的资源。

图3-1 c/s结构
4程序流程图与设计
4.1程序时序图与系统架构
本系统采用面向连接的客户/服务模型,服务器必须首先启动,否则客户进程的Connect ()系统调用将返回错误代码表示连接失败。

无连接的服务进程也必须首先启动以指定本地的套接字地址否则客户进程的数据服务请求传送不到服务器进程。

面向连接的c/s时序图如图4-1所示
图4-1 程序时序图
系统由服务器终端采集传输系统和客户端接收系统两部分组,系统构架如图4-2所示
图4-2 系统架构
4.2程序设计分析
服务器 发送数据
<--------------------------
<-------------------------
确认发送数据
<---------------------------
请求建立连接
客户
4.2.1任务目标
服务器端程序目标:服务器服务器端服务程序进行数据采集(捕捉摄像头捕获数据),提供IP端口实现数据流的传输。

客户端程序目标:客户端程序通过IP协议与服务器端通信,接收并回放服务器端采集的视频数据流。

4.2.2程序描述
Socket类:
socket之间的连接可以分为三种类型:客户端连接,监听连接以与服务器端连接。

客户端连接是指由客户端的socket提出连接请求,要连接的目标是服务器端的socket。

为此,客户端的socket必须首先描述它要连接的服务器端socket(主要是指服务器端socket的地址和端口号),然后再定位所要连接的服务器端socket,找到以后,就向服务器端 socket请求连接。

当然,服务器端的socket此时未必正好处于准备好状态,不过,服务器端的 socket会自动维护客户请求连接的队列,然后在它认为合适的时候向客户端socket发出"允许连接" (accept)的信号,这时客户端socket与服务器端socket的连接就建立了。

监听连接,服务器端 socket并不定位具体的客户端socket,而是处于等待连接的状态。

当服务器端socket监听到或者说接收到客户端socket的连接请求,它就响应客户端socket的请求建立一个新的socket句柄并与客户端连接,而服务器端socket继续处于监听状态,还可以接收其它客户端socket的连接请求。

服务器端连接,是指当服务器端socket接收到客户端socket的连接请求后,就把服务器端socket的描述发给客户端,一旦客户端确认了此描述,连接就建立了。

在本文中的聊天程序用的就是监听连接,即服务器设置连接个数后进行监听,客户端进行对服务器端的连接,这样就可以进行相互通信了。

TcpService类
namespace TCP
{
internalclass TcpServer : IDisposable
{
// This is not the max number of connections you can have, it's the number
// that can queue up waiting for you to Accept them. If more than MAXCONNECTION
// more clients try to connect while you are servicing another, OnConnect is
// probably taking too long.
constint MAXCONNECTIONS = 3;
#region Member variables
private ArrayList m_aryClients;
private Socket m_sockListener;
privatevolatilebool m_bShuttingDown;
private ManualResetEvent ShutDownReady;
#endregion
// Return an array of the ip addresses assigned to this pc publicstatic IPAddress [] GetAddresses()
{
IPAddress [] aryLocalAddr = null;
string strHostName = "";
// NOTE: DNS lookups are nice and all but quite time consuming.
strHostName = Dns.GetHostName();
#if USING_NET11
IPHostEntry ipEntry = Dns.GetHostByName( strHostName ); #else
IPHostEntry ipEntry = Dns.GetHostEntry( strHostName );
#endif
aryLocalAddr = ipEntry.AddressList;
// Verify we got an IP address.
if( aryLocalAddr == null || aryLocalAddr.Length < 1 )
{
thrownew Exception( "Unable to get local address" );
}
return aryLocalAddr;
}
public TcpServer(int nPortListen)
{
_TcpServer(nPortListen, GetAddresses()[0]);
}
public TcpServer(int nPortListen, IPAddress ip)
{
_TcpServer(nPortListen, ip);
}
// Shut down the listener
publicvoid Dispose()
{
// Shutting down is a real PITA. You can't close the listener
// while there is an outstanding async call active. And you can't
// cancel the async call. Grr. As a workaround, this routine
// makes a connection to the port. The OnConnect routine, recognizing // that we are in shutdown, doesn't create a new async call.
TcpClient t = null;
// Only want one thread to be preforming shutdown at a time.
lock (this)
{
// Have we already shutdown?
if (!m_bShuttingDown)
{
m_bShuttingDown = true;
// Disconnect each client
foreach (SockWrapper s in m_aryClients)
{
try
{
s.Client.Shutdown(SocketShutdown.Both); s.Client.Close();
}
catch {}
}
m_aryClients = null;
// Connect to the port to trigger the async listener
IPEndPoint ep = (IPEndPoint)m_sockListener.LocalEndPoint;
t = new TcpClient(ep.Address.ToString(), ep.Port); }
}
if (t != null)
{
// Listen for the async listener to let go. This must be done
// outside the crit section since the listener needs to lock it.
ShutDownReady.WaitOne(3000, false);
lock (this)
{
// close everything down
m_sockListener.Close();
m_sockListener = null;
t.Close();
ShutDownReady.Close();
ShutDownReady = null;
}
}
}
~TcpServer()
{
// If Dispose is not called against our class and the destructor is // called, some of the member variables in this class have already // been disposed. Such being the case, there's no way to clean up // nicely. Moral: Always call Dispose.
//Dispose();
}
// Send to all connected clients
publicvoid SendToAll(MemoryStream m)
{
_SendToAll(m.GetBuffer(), (int)m.Length);
}
publicvoid SendToAll(byte [] b)
{
_SendToAll(b, b.Length);
}
publicint Connections
{
get { return m_aryClients.Count; }
}
publicevent TcpConnected Connected;
publicevent TcpConnected Disconnected;
publicevent TcpReceive DataReceived;
publicevent TcpSend Send;
privatevoid _TcpServer(int nPortListen, IPAddress ip)
{
try
{
// Initialize member vars
m_aryClients = new ArrayList(5);
ShutDownReady = new ManualResetEvent(false);
m_bShuttingDown = false;
// Create the listener socket in this machine's IP address
m_sockListener = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
m_sockListener.Bind( new IPEndPoint( ip, nPortListen ) );
m_sockListener.Listen( MAXCONNECTIONS );
// Setup a callback to be notified of connection requests
m_sockListener.BeginAccept( new AsyncCallback( OnConnectRequest ), m_sockListener );
}
catch
{
m_bShuttingDown = true;
throw;
}
}
privatevoid _SendToAll(byte [] b, int iLength)
{
lock (this)
{
if (!m_bShuttingDown)
{
foreach (SockWrapper s in m_aryClients)
{
_SendOne(s, b, iLength);
}
}
}
}
privatevoid _SendOne(SockWrapper s, byte [] b, int iLength)
{
try
{
bool bSend = true;
if (Send != null)
Send(this, ref s.obj, ref bSend);
if (bSend)
s.Client.Send(b, iLength, SocketFlags.None);
}
catch
{
// Ignore the error. If the client is dead, OnReceiveData
// will be called to close the connection. I would remove it
// anyway, except bad things happen if you remove an entry
// from a list while using foreach.
}
}
// Client has connected
privatevoid OnConnectRequest( IAsyncResult ar )
{
// Get the listener and client
Socket listener = (Socket)ar.AsyncState;
Socket client = listener.EndAccept( ar );
lock (this)
{
if (!m_bShuttingDown)
{
// Wrap the client and add it to the array
SockWrapper s = new SockWrapper(client);
m_aryClients.Add( s );
// Fire the Connected event
if (Connected != null)
Connected(this, ref s.obj);
// Set up an async wait for packets from the client
AsyncCallback receiveData = new AsyncCallback( OnReceivedData );
s.Client.BeginReceive( s.byBuff, 0, s.byBuff.Length, SocketFlags.None, receiveData, s );
// (Re)Setup a callback to be notified of connection requests
listener.BeginAccept(new AsyncCallback( OnConnectRequest ) , listener );
}
else
{
// If we are in shutdown mode, DON'T add
// the connection to the array, DON'T setup
// the async listen, and DO set the event
// to say we are done.
ShutDownReady.Set();
}
}
}
// Client has sent data, or has disconnected
privatevoid OnReceivedData( IAsyncResult ar )
{
// Socket was the passed in object
SockWrapper s = (SockWrapper)ar.AsyncState;
lock (this)
{
if (!m_bShuttingDown)
{
// Check if we got any data
try
{
int nBytesRec = s.Client.EndReceive( ar );
if( nBytesRec > 0 )
{
if (DataReceived != null)
DataReceived(this, ref s.obj, ref s.byBuff, nBytesRec);
// Restablish the callback
AsyncCallback receiveData = new AsyncCallback( OnReceivedData );
s.Client.BeginReceive( s.byBuff, 0, s.byBuff.Length, SocketFlags.None, receiveData, s );
}
else
{
// If no data was received then the connection is probably dead
RemoveConnection(s);
}
}
catch
{
RemoveConnection(s);
}
}
}
}
// Remove a connection from the list of active connections privatevoid RemoveConnection(SockWrapper s)
{
try
{
s.Client.Shutdown( SocketShutdown.Both );
s.Client.Close();
}
catch {}
// Remove it from the array
try
{
m_aryClients.Remove( s );
}
catch {}
// Fire the Disconnected event
if (Disconnected != null)
Disconnected(this, ref s.obj);
}
// Wrapper for each client (stored in m_aryClients)
internalclass SockWrapper
{
// The buffer is used by receive
public Socket Client;
publicbyte [] byBuff;
publicobject obj;
public SockWrapper(Socket client)
{
Client = client;
byBuff = newbyte[256];
obj = newobject();
}
}
}
publicdelegatevoid TcpConnected(Object sender, refobject o); publicdelegatevoid TcpSend(Object sender, refobject o, refbool b);
publicdelegatevoid TcpReceive(Object sender, refobject o, refbyte [] b, int ByteCount); }
WebCamService 类:
namespace WebCamService
{
publicclass WebCamService : ServiceBase
{
#region Required Service Related Methods
private System ponentModel.Container components = null;
public WebCamService()
{
InitializeComponent();
}
privatevoid InitializeComponent()
{
components = new System ponentModel.Container();
this.ServiceName = "WebCamService";
}
protectedoverridevoid Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#endregion
[STAThread]
publicstaticvoid Main(string[] args)
{
= "Main thread";
WebCamService ServiceToRun = new WebCamService() ;
if ( Debugger.IsAttached )
{
ServiceToRun.Run();
}
else
{
ServiceToRun.CanPauseAndContinue = false; ServiceBase.Run(ServiceToRun);
}
}
#region Member Variables
privateconstint MAXOUTSTANDINGPACKETS = 3;
///<summary>
/// The thread will run the job.
/// The job is the Method Run() below
///</summary>
protected Thread thread = null;
private ManualResetEvent ConnectionReady;
privatevolatilebool bShutDown;
privatevolatileint iConnectionCount;
#endregion
///<summary>
/// Set things in motion so your service can do its work.
///为了服务器可以工作而设置的选项
///</summary>
protectedoverridevoid OnStart(string[] args)
{
ThreadStart starter = new ThreadStart(Run);//实例化进程
thread = new Thread(starter);
thread.Start();
}
///<summary>
/// Stop this service.
///停止服务
/// The Run() Method tests for this thread state each second ///每秒都为这个进程启动方法测试
///</summary>
protectedoverridevoid OnStop()
{
// Set exit condition
//设置退出状态
bShutDown = true;
// Need to get out of wait
//需要退出等待
ConnectionReady.Set();
}
publicvoid Run()
{
constint VIDEODEVICE = 0; // zero based index of video capture device to use constint FRAMERATE = 15; // Depends on video device caps. Generally 4-30. constint VIDEOWIDTH = 640; // Depends on video device caps
constint VIDEOHEIGHT = 480; // Depends on video device caps
constlong JPEGQUALITY = 30; // 1-100 or 0 for default
constint TCPLISTENPORT = 399;
Capture cam = null;
TcpServer serv = null;
ImageCodecInfo myImageCodecInfo;
EncoderParameters myEncoderParameters;
// Set up logging
//建立日志记录
StreamWriter sw = File.AppendText("d:\WebCam.log");
try
{
// Set up member vars
ConnectionReady = new ManualResetEvent(false);
bShutDown = false;
// Set up tcp server
//建立TCP服务
iConnectionCount = 0;
serv = new TcpServer(TCPLISTENPORT, TcpServer.GetAddresses()[3]); serv.Connected += new TcpConnected(Connected);
serv.Disconnected += new TcpConnected(Disconnected);
serv.DataReceived += new TcpReceive(Receive);
serv.Send += new TcpSend(Send);
myEncoderParameters = null;
myImageCodecInfo = GetEncoderInfo("image/jpeg");
if (JPEGQUALITY != 0)
{
// If not using the default jpeg quality setting
//如果不适用默认的JPEG质量设置
EncoderParameter myEncoderParameter;
myEncoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, JPEGQUALITY);
myEncoderParameters = new EncoderParameters(1);
myEncoderParameters.Param[0] = myEncoderParameter;
}
cam = new Capture(VIDEODEVICE, FRAMERATE, VIDEOWIDTH, VIDEOHEIGHT);
// Initialization succeeded. Now, start serving up frames
//初始化成功,现在,启动服务器发送帧
DoIt(cam, serv, sw, myImageCodecInfo, myEncoderParameters);
}
catch(Exception ex)
{
try
{
sw.WriteLine(String.Format("{0}: Failed on startup {1}", DateTime.Now.ToString(), ex));
}
catch {}
}
finally
{
// Cleanup
//清除
if (serv != null)
{
serv.Dispose();
}
if (cam != null)
{
cam.Dispose();
}
sw.Close();
}
}
// Start serving up frames
// 启动服务器松帧
privatevoid DoIt(Capture cam, TcpServer serv, StreamWriter sw, ImageCodecInfo myImageCodecInfo, EncoderParameters myEncoderParameters)
{
MemoryStream m = new MemoryStream(20000);
Bitmap image = null;
IntPtr ip = IntPtr.Zero;
do
{
// Wait til a client connects before we start the graph
//发送图像之前等待客户端连接
ConnectionReady.WaitOne();
cam.Start();
// While not shutting down, and still at least one client
//当不关闭并且至少有一个客户端连接
while ((!bShutDown) && (serv.Connections > 0))
{
try
{
// capture image
//图像俘获
ip = cam.GetBitMap();
image = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, ip);
image.RotateFlip(RotateFlipType.RotateNoneFlipY);
// save it to jpeg using quality options
//保存为JPEG(默认的格式选项)
m.Position = 10;
image.Save(m, myImageCodecInfo, myEncoderParameters);
// Send the length as a fixed length string
//作为固定的字符串长度发送长度
m.Position = 0;
m.Write(Encoding.ASCII.GetBytes( (m.Length - 10).ToString("d8") + "\r\n"), 0, 10);
// send the jpeg image
//发送格式为GPEG格式的图像
serv.SendToAll(m);
// Empty the stream
//清空流
m.SetLength(0);
// remove the image from memory
//从存移出所发送的图像
image.Dispose();
image = null;
}
catch(Exception ex)
{
try
{
sw.WriteLine(DateTime.Now.ToString());
sw.WriteLine(ex);
}
catch {}
}
finally
{
if (ip != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(ip);
ip = IntPtr.Zero;
}
}
}
// Clients have all disconnected. Pause, then sleep and wait for more
//客户端不连接,中断,等待更多的发送
cam.Pause();
sw.WriteLine("Dropped frames: " + cam.m_Dropped.ToString());
} while ( !bShutDown );
}
class PacketCount : IDisposable
{
privateint m_PacketCount;
privateint m_MaxPackets;
public PacketCount(int i)
{
m_MaxPackets = i;
m_PacketCount = 0;
}
publicbool AddPacket()
{
bool b;
lock (this)
{
b = m_PacketCount < m_MaxPackets; if (b)
{
m_PacketCount++;
}
else
{
Debug.WriteLine("Max outstanding Packets reached"); }
}
return b;
}
publicvoid RemovePacket()
{
lock (this)
{
if (m_PacketCount > 0)
{
m_PacketCount--;
}
else
{
Debug.WriteLine("Packet count is messed up");
}
}
}
publicint Count()
{
return m_PacketCount;
}
#region IDisposable Members
publicvoid Dispose()
{
#if DEBUG
if (m_PacketCount != 0)
{
Debug.WriteLine("Packets left over: " + m_PacketCount.ToString());
}
#endif
}
#endregion
}
// A client attached to the tcp port
//客户端与TCP端口建立连接
privatevoid Connected(object sender, refobject t)
{
lock (this)
{
t = new PacketCount(MAXOUTSTANDINGPACKETS);
iConnectionCount++;
if (iConnectionCount == 1)
{
ConnectionReady.Set();
}
}
}
// A client detached from the tcp port
//客户端与TCP端口撤销连接
privatevoid Disconnected(object sender, refobject t)
{
lock (this)
{
iConnectionCount--;
if (iConnectionCount == 0)
{
ConnectionReady.Reset();
}
}
}
privatevoid Receive(Object sender, refobject o, refbyte [] b, int ByteCount) {
PacketCount pc = (PacketCount)o;
pc.RemovePacket();
}
privatevoid Send(Object sender, refobject o, refbool b)
{
PacketCount pc = (PacketCount)o;
b = pc.AddPacket();
}
// Find the appropriate encoder
// 查找合适的编码器
private ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); for(j = 0; j < encoders.Length; ++j)
{
if(encoders[j].MimeType == mimeType)
return encoders[j];
}
returnnull;
}
}
}
Webclient类:
namespace WebCamClient
{
///<summary>
/// Summary description for Form1.
///</summary>
publicclass Form1 : System.Windows.Forms.Form
{
DoImages doImages;
staticint m_Count;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.TextBox txtServer;
private System.Windows.Forms.Button btnPress;
private bel label1;
private System.Windows.Forms.TextBox txtMessage;
private System.Windows.Forms.TextBox txtPort;
private bel label2;
private bel label3;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.TextBox txtFrames;
private System ponentModel.IContainer components;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}
///<summary>
/// Clean up any resources being used.
///</summary>
protectedoverridevoid Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
if (doImages != null)
{
doImages.Done = true;
doImages = null;
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///<summary>
/// Required method for Designer support - do not modify /// the contents of this method with the code editor.
///</summary>
privatevoid InitializeComponent()
{
this ponents = new System ponentModel.Container(); this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.btnPress = new System.Windows.Forms.Button();
this.txtServer = new System.Windows.Forms.TextBox();
bel1 = new bel();
this.txtMessage = new System.Windows.Forms.TextBox();
this.txtPort = new System.Windows.Forms.TextBox();
bel2 = new bel();
this.txtFrames = new System.Windows.Forms.TextBox();
bel3 = new bel();
this.timer1 = new System.Windows.Forms.Timer(this ponents);
((System
ponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
= "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(508, 227);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// btnPress
//
this.btnPress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnPress.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnPress.Location = new System.Drawing.Point(278, 322);
= "btnPress";
this.btnPress.Size = new System.Drawing.Size(96, 35);
this.btnPress.TabIndex = 1;
this.btnPress.Tag = "1";
this.btnPress.Text = "Start";
this.btnPress.Click += new System.EventHandler(this.btnPress_Click);
//
// txtServer
//
this.txtServer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom |
System.Windows.Forms.AnchorStyles.Left)));
this.txtServer.Location = new System.Drawing.Point(19, 279);
= "txtServer";
this.txtServer.Size = new System.Drawing.Size(115, 21);
this.txtServer.TabIndex = 3;
this.txtServer.Text = "192.168.0.3";
//
// label1
//
bel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
bel1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); bel1.Location = new System.Drawing.Point(19, 236);
= "label1";
bel1.Size = new System.Drawing.Size(144, 43);
bel1.TabIndex = 4;
bel1.Text = "Enter server name or ip address";
//
// txtMessage
//
this.txtMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtMessage.Location = new System.Drawing.Point(10, 374);
= "txtMessage";
this.txtMessage.ReadOnly = true;
this.txtMessage.Size = new System.Drawing.Size(488, 21);
this.txtMessage.TabIndex = 5;
//
// txtPort
//
this.txtPort.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.txtPort.Location = new System.Drawing.Point(192, 279);
= "txtPort";
this.txtPort.Size = new System.Drawing.Size(58, 21);
this.txtPort.TabIndex = 6;
this.txtPort.Text = "399";
//
// label2
//
bel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
bel2.Location = new System.Drawing.Point(192, 253);
= "label2";
bel2.Size = new System.Drawing.Size(86, 25);
bel2.TabIndex = 7;
bel2.Text = "Port Number";
//
// txtFrames
//
this.txtFrames.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.txtFrames.Location = new System.Drawing.Point(298, 279);
= "txtFrames";
this.txtFrames.ReadOnly = true;
this.txtFrames.Size = new System.Drawing.Size(76, 21);
this.txtFrames.TabIndex = 8;
//
// label3
//
bel3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
bel3.Location = new System.Drawing.Point(298, 253);
= "label3";
bel3.Size = new System.Drawing.Size(57, 18);
bel3.TabIndex = 9;
bel3.Text = "Frames";
//
// timer1
//
this.timer1.Interval = 1000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AcceptButton = this.btnPress;
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.CancelButton = this.btnPress;
this.ClientSize = new System.Drawing.Size(508, 402);
this.Controls.Add(bel3);
this.Controls.Add(this.txtFrames);
this.Controls.Add(bel2);
this.Controls.Add(this.txtPort);
this.Controls.Add(this.txtMessage);
this.Controls.Add(bel1);
this.Controls.Add(this.txtServer);
this.Controls.Add(this.btnPress);
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
= "Form1";
this.Text = "WebClient";
((System
ponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
///<summary>
/// The main entry point for the application.
///</summary>
[STAThread]
staticvoid Main()
{
= "Main";
Application.Run(new Form1());
}
privatevoid btnPress_Click(object sender, System.EventArgs e)
{
// If the button says 'Start'
if ((string)btnPress.Tag == "1")
{
// Create a new thread to receive the images
try
{
m_Count = 0;
timer1.Enabled = true;
txtMessage.Text = "";
doImages = new DoImages(this, Convert.ToInt32(txtPort.Text)); ThreadStart o = new ThreadStart(doImages.ThreadProc);
Thread thread = new Thread( o );
="Imaging";
thread.Start();
}
catch (Exception ex)
{
txtMessage.Text = ex.Message;
return;
}
// Reset the button tag and description
btnPress.Tag = "2";
btnPress.Text = "Stop";
}
else
{
Stop();
timer1.Enabled = false;
txtFrames.Text = m_Count.ToString();
}
}
privatevoid Stop()
{
// Inform the thread it should stop
doImages.Done = true;
doImages = null;
// Reset the button tag and description
btnPress.Tag = "1";
btnPress.Text = "Start";
}
privatevoid timer1_Tick(object sender, System.EventArgs e)
{
txtFrames.Text = m_Count.ToString();
}
//
======================================================================================= =========
publicclass DoImages
{
// Abort indicator
publicbool Done;
// Form to write to
private Form1 m_f;
// Client connection to server
private TcpClient tcpClient;
// stream to read from
private NetworkStream networkStream;
public DoImages(Form1 f, int nPort)
{
Done = false;
m_f = f;
// Connect to the server and get the stream
tcpClient = new TcpClient(m_f.txtServer.Text, nPort);
tcpClient.NoDelay = false;
tcpClient.ReceiveTimeout = 5000;
tcpClient.ReceiveBufferSize = 20000;
networkStream = tcpClient.GetStream();
}
publicvoid ThreadProc()
{
string s;
int iBytesComing, iBytesRead, iOffset;
byte [] byLength = newbyte[10];
byte [] byImage = newbyte[1000];
MemoryStream m = new MemoryStream(byImage);
do
{
try
{
// Read the fixed length string that
// tells the image size
iBytesRead = networkStream.Read(byLength, 0, 10);
if (iBytesRead != 10)
{
m_f.txtMessage.Text = "No response from host"; m_f.Stop();
break;。

相关文档
最新文档