网络编程——实战篇

理论过后是实战,不知道理论的内容是否会太枯燥,对我来说,是获益菲浅,大学自学的计算机网络知识已经在摇不可及的世界,只留下我在现实的海洋之中苟延残喘。

理论上来说,要实现两台pc之间的通讯,socket是必要条件,然而理论上的东西往往会不自觉的让人产生出一种恐惧感,感谢前辈们的伟大工作,通过他们的努力,我们可以在对象的海洋中,自由选择各种对象,拿来主义的思想在这里得到了发扬光大,在socket层,我们有socket类,在tcp层,我们有TcpClientTcpListener等,在http层,我们还有httpwebrequesthttpwebresponse对象,哦,应有竟有,而且这也不是最后的晚餐。你还可以通过webservice,其通过基于xmlsoap来描述对象,每一个层上的对象都是对该层协议的诠释,至于你具体用哪个,还要看你的应用,毕竟一样东西不可能让任何人都喜欢。

最近整上了一个基于NETCF下的mobile应用,以前一直做cs方面的开发,忽然需要通过小小的手机传送数据对我来说是一个莫大的挑战,因为神秘而产生莫大的兴趣,因为手机是通过gprs发送数据,而中国移动这家伙又是按流量收费,所以数据量的一点一滴都要记在我们程序员身上,在这种情况下,其实通过socket直接发送数据,是最理想的方式,然而需要控制或者说编码的地方也会更多,考虑到编码的简便性,也因为时间上的紧张(总时间只有1个半月,对于高手来说当然足足有余,而对于像我这样的菜鸟,实在有点为难,而且我们公司也没有这方面的资源),最终选择了较为容易控制的httpwebrequesthttpwebresponse

在了解数据传送的过程中,也接触过多种方式,下面分别以实例代码,一一解释,当然这些代码也并非由我发明,也是前辈们的资源,只是稍加修饰,在此感谢他们,名字就说不上来了:(

让我们从最基本的socket开始说起,那是在一个很早很早的时候,在一个很远很远的地方……

Socket的故事

客户端

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Net.Sockets;

using System.Net;

 

namespace SocketClient

{

    public partial class FrmSocketClient : Form

    {

        Socket socket;

        int numbyte = 1024;//一次接收到的字节数

 

        public FrmSocketClient()

        {

            InitializeComponent();

        }

 

        private void btnConnect_Click(object sender, EventArgs e)

        {

            try

            {

                string ip = this.txtRemoIP.Text;

                string port = this.txtRemoport.Text;

                IPAddress serverIp = IPAddress.Parse(ip);

                int serverPort = Convert.ToInt32(port);

                IPEndPoint iep = new IPEndPoint(serverIp, serverPort);

                //IPHostEntry host = Dns.GetHostByAddress(iep.Address);

                IPHostEntry host = Dns.GetHostEntry(iep.Address);

                string HostName = host.HostName;

                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                socket.Connect(iep);

                IPEndPoint tempRemoteIP = (IPEndPoint)socket.LocalEndPoint;

                statusStrip1.Items[0].Text = "端口:" + tempRemoteIP.Port.ToString() + "正在监听......";

                statusStrip1.Items[1].Text = "与远程计算机[" + HostName + "] " + ip + ":" + port + "建立连接!";

            }

            catch

            {

                statusStrip1.Items[0].Text = "无法连接到目标计算机!";

            }

            #region

 

            //byteMessage = Encoding.ASCII.GetBytes(textBox1.Text + "99");

            //socket.Send(byteMessage);

            //byte[] bytes = new byte[1024];

            //socket.Receive(bytes);

            //string str = Encoding.Default.GetString(bytes);

            //MessageBox.Show("接收到:" + str);

            //socket.Shutdown(SocketShutdown.Both);

            //socket.Close();

 

            #endregion

        }

 

        private void btnSend_Click(object sender, EventArgs e)

        {

            try

            {

                statusStrip1.Items[1].Text = "正在发送信息!";

                string message = this.txtsend.Text;

                SendInfo(message);

            }

            catch //异常处理

            {

                statusStrip1.Items[0].Text = "无法发送信息到目标计算机!";

            }

        }

 

        private void SendInfo(string message)

        {

            #region

            //string ip = this.txtip.Text;

            //string port = this.txtport.Text;

 

            //IPAddress serverIp = IPAddress.Parse(ip);

            //int serverPort = Convert.ToInt32(port);

            //IPEndPoint iep = new IPEndPoint(serverIp, serverPort);

            //byte[] byteMessage;

 

            //socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //socket.Connect(iep);

            #endregion

 

            byte[] byteMessage = Encoding.ASCII.GetBytes(message + "#"); ///x99/x99

            socket.Send(byteMessage);

            //远端信息

            EndPoint tempRemoteEP = socket.RemoteEndPoint;

            IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP;

            string rempip = tempRemoteIP.Address.ToString();

            string remoport = tempRemoteIP.Port.ToString();

            //IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address);

            IPHostEntry host = Dns.GetHostEntry(tempRemoteIP.Address);

            string HostName = host.HostName;

 

            //发送信息

            string time1 = DateTime.Now.ToString();

            listboxsend.Items.Add("(" + time1 + ") " + HostName + ":");

            listboxsend.Items.Add(message);

 

            //发送完了,直接接收

            StringBuilder sb = new StringBuilder();

            while (true)

            {

                statusStrip1.Items[1].Text = "正在等待接收信息...";

                byte[] bytes = new byte[numbyte];

                int recvbytes = socket.Receive(bytes);

                string strmsg = Encoding.Default.GetString(bytes);

                string time2 = DateTime.Now.ToString();

                listboxRecv.Items.Add("(" + time2 + ") " + HostName + "");

                listboxRecv.Items.Add(strmsg);

                sb.Append(strmsg);

                if (sb.ToString().IndexOf("#") > -1)   ///x99/x99

                {

                    break;

                }

            }

            statusStrip1.Items[1].Text = "接收信息完毕!";

            //

            //代码解码

            //CodeParse(sb.ToString());

            //

            socket.Shutdown(SocketShutdown.Both);

            socket.Close();

        }

    }

}

服务器端

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Threading;

using System.Net;

using System.Net.Sockets;

 

namespace GeoMobileServer

{

    public partial class FrmAsyncServer : Form

    {

        public FrmAsyncServer()

        {

            InitializeComponent();

        }

 

        public static ManualResetEvent allDone = new ManualResetEvent(false);

        private Thread th;

        private bool listenerRun = true;

        Socket listener;

        private const int MAX_SOCKET = 10;

 

        //得到本机IP地址

        public static IPAddress GetServerIP()

        {

            IPHostEntry ieh = Dns.GetHostByName(Dns.GetHostName());

            return ieh.AddressList[0];

        }

 

        //侦听方法

        private void Listen()

        {

            try

            {

                int nPort = int.Parse(this.txtLocalPort.Text);

                IPAddress ServerIp = GetServerIP();

                IPEndPoint iep = new IPEndPoint(ServerIp, nPort);

                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                listener.Bind(iep);

                listener.Listen(10);

                statusStrip1.Items[0].Text = "端口:" + this.txtLocalPort.Text + "正在监听......";

 

                while (listenerRun)

                {

                    allDone.Reset();

                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

                    allDone.WaitOne();

                }

            }

            catch (System.Security.SecurityException)

            {

                MessageBox.Show("防火墙安全错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

            }

        }

 

        //异步回调函数

        public void AcceptCallback(IAsyncResult ar)

        {

            Socket listener = (Socket)ar.AsyncState;

            Socket client = listener.EndAccept(ar);

            allDone.Set();

            StateObject state = new StateObject();

            state.workSocket = client;

 

            //远端信息

            EndPoint tempRemoteEP = client.RemoteEndPoint;

            IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP;

            string rempip = tempRemoteIP.Address.ToString();

            string remoport = tempRemoteIP.Port.ToString();

            //IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address);

            IPHostEntry host = Dns.GetHostEntry(tempRemoteIP.Address);

            string HostName = host.HostName;

            statusStrip1.Items[1].Text = "接受[" + HostName + "] " + rempip + ":" + remoport + "远程计算机正确连接!";

            string hostInfo = "[" + HostName + "] " + rempip + ":" + remoport;

            //this.listboxRemohost.Items.Add("[" + HostName + "] " + rempip + ":" + remoport);

            this.listboxRemohost.Invoke(UpdateRemoHost, new object[] { hostInfo });

            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(readCallback), state);

        }

 

        public delegate void UpdateRemoHostHandler(string hostInfo);

        public UpdateRemoHostHandler UpdateRemoHost;

        public void UpdateRemoHostMethod(string hostInfo)

        {

            this.listboxRemohost.Items.Add(hostInfo);

        }

        public delegate void UpdateReceiveMsgHandler(string time, string hostName, string msg);

        public UpdateReceiveMsgHandler UpdateReceiveMsg;

        public void UpdateReceiveMsgMethod(string time, string hostName, string msg)

        {

            this.listboxRecv.Items.Add("(" + time + ") " + hostName + "");

            this.listboxRecv.Items.Add(msg);

        }

 

        //异步接收回调函数

        public void readCallback(IAsyncResult ar)

        {

            StateObject state = (StateObject)ar.AsyncState;

            Socket handler = state.workSocket;

            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)

            {

                string strmsg = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);

                state.sb.Append(strmsg);

                string content = state.sb.ToString();

                //远端信息

                EndPoint tempRemoteEP = handler.RemoteEndPoint;

                IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP;

                string rempip = tempRemoteIP.Address.ToString();

                string remoport = tempRemoteIP.Port.ToString();

                //IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address);

                IPHostEntry host = Dns.GetHostEntry(tempRemoteIP.Address);

                string HostName = host.HostName;

                statusStrip1.Items[1].Text = "正在接收[" + HostName + "] " + rempip + ":" + remoport + "的信息...";

                string time = DateTime.Now.ToString();

                //listboxRecv.Items.Add("(" + time + ") " + HostName + "");

                //listboxRecv.Items.Add(strmsg);

                this.listboxRecv.Invoke(UpdateReceiveMsg, new object[] { time, HostName, strmsg });

                if (content.IndexOf("#") > -1)  ///x99/x99

                {

                    statusStrip1.Items[1].Text = "信息接收完毕!";

                    //

                    //接收到完整的信息

                    //MessageBox.Show("接收到:" + content);

                    //string msg = poweryd.CodeParse(content);

                    string msg = content;

                    Send(handler, msg);//异步发送

                    //Send(content);//用单独的socket发送

                }

                else

                {

                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(readCallback), state);

                }

            }

        }

 

        //异步发送

        private void Send(Socket handler, String data)

        {

            byte[] byteData = Encoding.ASCII.GetBytes(data);

            handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);

            //handler.Send(byteData);

        }

 

        #region  //用单独的socket发送

 

        private void Send(string data)

        {

            //string ip = this.txtRemoIP.Text;

            //string port = this.txtRemoport.Text;

            //IPAddress serverIp = IPAddress.Parse(ip);

            //int serverPort = Convert.ToInt32(port);

            //IPEndPoint iep = new IPEndPoint(serverIp, serverPort);

            //Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //socket.Connect(iep);

            //byte[] byteMessage = Encoding.ASCII.GetBytes(data);

            //socket.Send(byteMessage);

            //socket.Shutdown(SocketShutdown.Both);

            //socket.Close();            

        }

 

        #endregion

 

        private void Stop()

        {

            try

            {

                listenerRun = false;

                th.Abort();

                th = null;

                listener.Close();

            }

            catch { }

        }

 

        //异步发送回调函数

        private static void SendCallback(IAsyncResult ar)

        {

            try

            {

                Socket handler = (Socket)ar.AsyncState;

                int bytesSent = handler.EndSend(ar);

                MessageBox.Show("发送成功!");

                handler.Shutdown(SocketShutdown.Both);

                handler.Close();

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.ToString());

            }

        }

 

        private void btnListen_Click(object sender, EventArgs e)

        {

            th = new Thread(new ThreadStart(Listen));//Listen过程来初始化线程实例     

            th.Start();//启动此线程

            this.btnListen.Enabled = false;

        }

 

        private void btnClosenet_Click(object sender, EventArgs e)

        {

            try

            {

                listenerRun = false;

                th.Abort();

                th = null;

                listener.Close();

                statusStrip1.Items[0].Text = "与客户端断开连接!";

                statusStrip1.Items[1].Text = "";

            }

            catch

            {

                MessageBox.Show("连接尚未建立,断开无效!", "警告");

            }

        }

 

        private void btnExit_Click(object sender, EventArgs e)

        {

            try

            {

                listenerRun = false;

                th.Abort();

                th = null;

                listener.Close();

                statusStrip1.Items[0].Text = "与客户端断开连接!";

                statusStrip1.Items[1].Text = "";

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.Message);

            }

            finally

            {

                Application.Exit();

            }

        }

 

        //异步传递的状态对象

        public class StateObject

        {

            public Socket workSocket = null;

            public const int BufferSize = 1024;

            public byte[] buffer = new byte[BufferSize];

            public StringBuilder sb = new StringBuilder();

        }

 

        private void FrmAsyncServer_Load(object sender, EventArgs e)

        {

            UpdateRemoHost = new UpdateRemoHostHandler(UpdateRemoHostMethod);

            UpdateReceiveMsg = new UpdateReceiveMsgHandler(UpdateReceiveMsgMethod);

        }

    }

}

         代码不用过多解释,最深刻的认识无非是自己单步执行几次,就能了解大概的运作机理了。这里需要注意的一点是因为服务器端采用的是异步执行方式,每收到一个客户端请求,都在服务端后台新建一进程,考虑到进程间的数据安全,是无法直接对主窗体上的UI控件进行调用,这里采用的是通过委托的方式。如下所示:

         public delegate void UpdateRemoHostHandler(string hostInfo);

    public UpdateRemoHostHandler UpdateRemoHost;

    public void UpdateRemoHostMethod(string hostInfo)

    {

        this.listboxRemohost.Items.Add(hostInfo);

}

而调用的时候,发生了一点小小的变化:

this.listboxRemohost.Invoke(UpdateRemoHost, new object[] { hostInfo });

TCP

Tcp层上主要用到两个对象:TcpListener 类和TcpClient对象。对它们我没有过多的了解,这里粘贴一段msdn上的代码,通过它也能帮助理解个中滋味。

static void Connect(String server, String message)

        {

            try

            {

                //   Create   a   TcpClient.  

                //   Note,   for   this   client   to   work   you   need   to   have   a   TcpServer    

                //   connected   to   the   same   address   as   specified   by   the   server,   port  

                //   combination.  

                Int32 port = 9050;

                TcpClient client = new TcpClient(server, port);

 

                //   Translate   the   passed   message   into   ASCII   and   store   it   as   a   Byte   array.  

                Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);

 

                //   Get   a   client   stream   for   reading   and   writing.  

                //     Stream   stream   =   client.GetStream();  

                NetworkStream stream = client.GetStream();

 

                //   Send   the   message   to   the   connected   TcpServer.    

                stream.Write(data, 0, data.Length);

                Console.WriteLine("Sent:   {0}", message);

 

                //   Receive   the   TcpServer.response.  

                //   Buffer   to   store   the   response   bytes.  

                data = new Byte[256];

 

                //   String   to   store   the   response   ASCII   representation.  

                String responseData = String.Empty;

 

                //   Read   the   first   batch   of   the   TcpServer   response   bytes.  

                Int32 bytes = stream.Read(data, 0, data.Length);

                responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

                Console.WriteLine("Received:   {0}", responseData);

 

                //while (true)

                //{

                //    input = Console.ReadLine();//从键盘读取数据

                //    if (input == "text")//结束标记

                //    {

                //        break;

                //    }

                //    server.SendTo(Encoding.ASCII.GetBytes(input), Remote);//将数据发送到指定的终结点Remote

                //    data = new byte[1024];

                //    recv = server.ReceiveFrom(data, ref Remote);//Remote接受数据

                //    stringData = Encoding.ASCII.GetString(data, 0, recv);

                //    Console.WriteLine(stringData);

                //}

                //   Close   everything.  

                client.Close();

            }

            catch (ArgumentNullException e)

            {

                Console.WriteLine("ArgumentNullException:   {0}", e);

            }

            catch (SocketException e)

            {

                Console.WriteLine("SocketException:   {0}", e);

            }

 

            Console.WriteLine("/n   Press   Enter   to   continue...");

            Console.ReadLine();

        }

HttpWebRequestHttpWebResponse的断背情节

         客户端

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost/MobileHttpServer/DataUpload.aspx");

            string postData = "TextBox1=" + "aa" + "&TextBox2=" + "bb" + "&TextBox3=" + "cc" + "&TextBox4=" + "dd";

            ASCIIEncoding encoding = new ASCIIEncoding();

            byte[] byte1 = encoding.GetBytes(postData); //最终编码后要上传的数据

            // Set the content type of the data being posted.

            req.ContentType = "application/x-www-form-urlencoded";

            req.Method = "post";  //post上传方式

            // Set the content length of the string being posted.

            req.ContentLength = byte1.Length;

            Stream newStream = req.GetRequestStream();

            newStream.Write(byte1, 0, byte1.Length);

客户端的代码真的很简单,你可以在服务端制作这样一个网页,然后自己在页面的Page_Load事件中看看到底发生了什么鲜为人知的故事,哦,这是秘密,各位看官还是自己动手吧。

如果服务器端返回数据的话,我们可以在客户端用下面的代码进行接收

            //在这里对接收到的页面内容进行处理

               WebResponse wr = req.GetResponse();

            Stream stream = wr.GetResponseStream();

            byte[] res = new byte[1024];

            int bytesnum = stream.Read(res, 0, res.Length);

            string txt = System.Text.UTF8Encoding.Default.GetString(res);

在我的任务计划书中,明确指出需要能够传送图片、声音等各种文件,喔,这时候,首先想到的就是把各种文件序列化成二进制流,然后再发送,不过如果你继续用上面这段代码的话,服务端一点反映都没有,哦,上帝啊,这是什么逻辑,同样是二进制,为什么区别就这么大呢。还好,茫茫大海中总有我们需要的东西可以现成拿来,可以不用让你费劲心机了,通过查看源代码,也能明白一些个中道理。

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Net;

 

/************************************************************************/

/* wwHttp这个类里面,不仅仅可以传送文件AddPostFile方法,还可以传送变量AddPostKey方法。

 

这样,如果我们要通过代理服务器传送文件,就可以编写如下的代码了:

wwHttp ww = new wwHttp();

ww.ProxyAddress = "202.132.156.124";  

ww.PostMode = 2;

ww.AddPostKey("testKey","test");

ww.AddPostFile("myfile",@"D:/Temp/Java/JavaStart/JavaStart2.jar"); 

string shtml = ww.GetUrlEvents("http://localhost/UploadFileWeb/WebForm1.aspx",409600);

Console.Write(shtml);

小结:

()通过Web Services传文件。

()如果不需要使用代理,使用WebClient

()如果需要使用代理,使用扩展得到的类wwHttp

/************************************************************************/

namespace HttpWebClient

{

    public class wwHttp

    {

        /// <summary>

        /// Fires progress events when using GetUrlEvents() to retrieve a URL.

        /// </summary>

        public event OnReceiveDataHandler OnReceiveData;

 

        // *** member properties

        //string cPostBuffer = "";

        MemoryStream oPostStream;

        BinaryWriter oPostData;

 

        int nPostMode = 1;

 

        int nConnectTimeout = 30;

        string cUserAgent = "West Wind HTTP .NET";

 

        string cUsername = "";

        string cPassword = "";

 

        string cProxyAddress = "";

        string cProxyBypass = "";

        string cProxyUsername = "";

        string cProxyPassword = "";

 

        bool bThrowExceptions = false;

        bool bHandleCookies = false;

 

        string cErrorMsg = "";

        bool bError = false;

 

        HttpWebResponse oWebResponse;

        HttpWebRequest oWebRequest;

        CookieCollection oCookies;

 

        string cMultiPartBoundary = "-----------------------------7cf 2a 327f 01ae";

 

        /// <summary>

        /// Determines how data is POSTed when cPostBuffer is set.

        /// 1 - UrlEncoded

        /// 2 - Multi-Part form vars

        /// 4 - XML (raw buffer content type: text/xml)

        /// </summary>

        public int PostMode

        {

            get { return this.nPostMode; }

            set { this.nPostMode = value; }

        }

 

        /// <summary>

        ///  User name used for Authentication.

        ///  To use the currently logged in user when accessing an NTLM resource you can use "AUTOLOGIN".

        /// </summary>

        public string Username

        {

            get { return this.cUsername; }

            set { cUsername = value; }

        }

 

        /// <summary>

        /// Password for Authentication.

        /// </summary>

        public string Password

        {

            get { return this.cPassword; }

            set { this.cPassword = value; }

        }

 

        /// <summary>

        /// Address of the Proxy Server to be used.

        /// Use optional DEFAULTPROXY value to specify that you want to IE's Proxy Settings

        /// </summary>

        public string ProxyAddress

        {

            get { return this.cProxyAddress; }

            set { this.cProxyAddress = value; }

        }

 

        /// <summary>

        /// Semicolon separated Address list of the servers the proxy is not used for.

        /// </summary>

        public string ProxyBypass

        {

            get { return this.cProxyBypass; }

            set { this.cProxyBypass = value; }

        }

 

        /// <summary>

        /// Username for a password validating Proxy. Only used if the proxy info is set.

        /// </summary>

        public string ProxyUsername

        {

            get { return this.cProxyUsername; }

            set { this.cProxyUsername = value; }

        }

 

        /// <summary>

        /// Password for a password validating Proxy. Only used if the proxy info is set.

        /// </summary>

        public string ProxyPassword

        {

            get { return this.cProxyPassword; }

            set { this.cProxyPassword = value; }

        }

 

        /// <summary>

        /// Timeout for the Web request in seconds. Times out on connection, read and send operations.

        /// Default is 30 seconds.

        /// </summary>

        public int Timeout

        {

            get { return this.nConnectTimeout; }

            set { this.nConnectTimeout = value; }

        }

 

        /// <summary>

        /// Error Message if the Error Flag is set or an error value is returned from a method.

        /// </summary>

        public string ErrorMsg

        {

            get { return this.cErrorMsg; }

            set { this.cErrorMsg = value; }

        }

 

        /// <summary>

        /// Error flag if an error occurred.

        /// </summary>

        public bool Error

        {

            get { return this.bError; }

            set { this.bError = value; }

        }

 

        /// <summary>

        /// Determines whether errors cause exceptions to be thrown. By default errors

        /// are handled in the class and the Error property is set for error conditions.

        /// (not implemented at this time).

        /// </summary>

        public bool ThrowExceptions

        {

            get { return bThrowExceptions; }

            set { this.bThrowExceptions = value; }

        }

 

        /// <summary>

        /// If set to a non-zero value will automatically track cookies. The number assigned is the cookie count.

        /// </summary>

        public bool HandleCookies

        {

            get { return this.bHandleCookies; }

            set { this.bHandleCookies = value; }

        }

 

        public CookieCollection Cookies

        {

            get { return this.oCookies; }

            set { this.Cookies = value; }

        }

 

        public HttpWebResponse WebResponse

        {

            get { return this.oWebResponse; }

            set { this.oWebResponse = value; }

        }

 

        public HttpWebRequest WebRequest

        {

            get { return this.oWebRequest; }

            set { this.oWebRequest = value; }

        }

 

        public void wwHTTP()

        {

            //

            // TODO: Add constructor logic here

            //

 

        }

 

        /// <summary>

        /// Adds POST form variables to the request buffer.

        /// HttpPostMode determines how parms are handled.

        /// 1 - UrlEncoded Form Variables. Uses key and value pairs (ie. "Name","Rick") to create URLEncoded content

        /// 2 - Multi-Part Forms - not supported

        /// 4 - XML block - Post a single XML block. Pass in as Key (1st Parm)

        /// other - raw content buffer. Just assign to Key.

        /// </summary>

        /// <param name="Key">Key value or raw buffer depending on post type</param>

        /// <param name="Value">Value to store. Used only in key/value pair modes</param>

        public void AddPostKey(string Key, byte[] Value)

        {

            if (this.oPostData == null)

            {

                this.oPostStream = new MemoryStream();

                this.oPostData = new BinaryWriter(this.oPostStream);

            }

 

            if (Key == "RESET")

            {

                this.oPostStream = new MemoryStream();

                this.oPostData = new BinaryWriter(this.oPostStream);

            }

 

            switch (this.nPostMode)

            {

                case 1:

                    this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes(

                         Key + "=" + System.Web.HttpUtility.UrlEncode(Value) + "&"));

                    break;

                case 2:

                    this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes(

                        "--" + this.cMultiPartBoundary + "/r/n" +

                        "Content-Disposition: form-data; name=/"" + Key + "/"/r/n/r/n"));

                    this.oPostData.Write(Value);

                    this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes("/r/n"));

                    break;

                default:

                    this.oPostData.Write(Value);

                    break;

            }

        }

 

        public void AddPostKey(string Key, string Value)

        {

            this.AddPostKey(Key, Encoding.GetEncoding(1252).GetBytes(Value));

        }

 

        /// <summary>

        /// Adds a fully self contained POST buffer to the request.

        /// Works for XML or previously encoded content.

        /// </summary>

        /// <param name="PostBuffer"></param>

        public void AddPostKey(string FullPostBuffer)

        {

            this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes(FullPostBuffer));

        }

 

        public bool AddPostFile(string Key, string FileName)

        {

            byte[] lcFile;

 

            if (this.nPostMode != 2)

            {

                this.cErrorMsg = "File upload allowed only with Multi-part forms";

                this.bError = true;

                return false;

            }

 

            try

            {

                FileStream loFile = new FileStream(FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);

                lcFile = new byte[loFile.Length];

                loFile.Read(lcFile, 0, (int)loFile.Length);

                loFile.Close();

            }

            catch (Exception e)

            {

                this.cErrorMsg = e.Message;

                this.bError = true;

                return false;

            }

 

            this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes(

                "--" + this.cMultiPartBoundary + "/r/n" +

                "Content-Disposition: form-data; name=/"" + Key + "/" filename=/"" +

                new FileInfo(FileName).Name + "/"/r/n/r/n"));

            this.oPostData.Write(lcFile);

            this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes("/r/n"));

            return true;

        }

 

        /// <summary>

        /// Return a the result from an HTTP Url into a StreamReader.

        /// Client code should call Close() on the returned object when done reading.

        /// </summary>

        /// <param name="Url">Url to retrieve.</param>

        /// <param name="WebRequest">An HttpWebRequest object that can be passed in with properties preset.</param>

        /// <returns></returns>

        protected StreamReader GetUrlStream(string Url, HttpWebRequest Request)

        {

            try

            {

                this.bError = false;

                this.cErrorMsg = "";

 

                if (Request == null)

                    Request = (HttpWebRequest)System.Net.WebRequest.Create(Url);

 

                Request.UserAgent = this.cUserAgent;

                Request.Timeout = this.nConnectTimeout * 1000;

 

                // *** Save for external access

                this.oWebRequest = Request;

 

                // *** Handle Security for the request

                if (this.cUsername.Length > 0)

                    if (this.cUsername == "AUTOLOGIN")

                        Request.Credentials = CredentialCache.DefaultCredentials;

                    else

                        Request.Credentials = new NetworkCredential(this.cUsername, this.cPassword);

 

                // *** Handle Proxy Server configuration

                if (this.cProxyAddress.Length > 0)

                {

                    if (this.cProxyAddress == "DEFAULTPROXY")

                    {

                        Request.Proxy = new WebProxy();

                        Request.Proxy = WebProxy.GetDefaultProxy();

                    }

                    else

                    {

                        WebProxy loProxy = new WebProxy(this.cProxyAddress, true);

                        if (this.cProxyBypass.Length > 0)

                        {

                            loProxy.BypassList = this.cProxyBypass.Split(';');

                        }

 

                        if (this.cProxyUsername.Length > 0)

                            loProxy.Credentials = new NetworkCredential(this.cProxyUsername, this.cProxyPassword);

 

                        Request.Proxy = loProxy;

                    }

                }

 

                // *** Handle cookies - automatically re-assign

                if (this.bHandleCookies)

                {

                    Request.CookieContainer = new CookieContainer();

                    if (this.oCookies != null && this.oCookies.Count > 0)

                    {

                        Request.CookieContainer.Add(this.oCookies);

                    }

                }

 

                // *** Deal with the POST buffer if any

                if (this.oPostData != null)

                {

                    Request.Method = "POST";

                    switch (this.nPostMode)

                    {

                        case 1:

                            Request.ContentType = "application/x-www-form-urlencoded";

                            // strip off any trailing & which can cause problems with some

                            // http servers

                            //       if (this.cPostBuffer.EndsWith("&"))

                            //        this.cPostBuffer = this.cPostBuffer.Substring(0,this.cPostBuffer.Length-1);

                            break;

                        case 2:

                            Request.ContentType = "multipart/form-data; boundary=" + this.cMultiPartBoundary;

                            this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes("--" + this.cMultiPartBoundary + "/r/n"));

                            break;

                        case 4:

                            Request.ContentType = "text/xml";

                            break;

                        default:

                            goto case 1;

                    }

 

                    Stream loPostData = Request.GetRequestStream();

                    //loPostData.Write(lcPostData,0,lcPostData.Length);

                    this.oPostStream.WriteTo(loPostData);

 

                    byte[] buffer = new byte[this.oPostStream.Length];

                    buffer = this.oPostStream.ToArray();

                    //Console.Write(Encoding.GetEncoding(1252).GetString(buffer, 0, buffer.Length));

 

                    //*** Close the memory stream

                    this.oPostStream.Close();

                    this.oPostStream = null;

 

                    //*** Close the Binary Writer

                    this.oPostData.Close();

                    this.oPostData = null;

 

                    //*** Close Request Stream

                    loPostData.Close();

 

                    // *** clear the POST buffer

                    //this.cPostBuffer = "";

                }

 

                // *** Retrieve the response headers

                HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();

 

                // ** Save cookies the server sends

                if (this.bHandleCookies)

                {

                    if (Response.Cookies.Count > 0)

                    {

                        if (this.oCookies == null)

                        {

                            this.oCookies = Response.Cookies;

                        }

                        else

                        {

                            // ** If we already have cookies update the list

                            foreach (Cookie oRespCookie in Response.Cookies)

                            {

                                bool bMatch = false;

                                foreach (Cookie oReqCookie in this.oCookies)

                                {

                                    if (oReqCookie.Name == oRespCookie.Name)

                                    {

                                        oReqCookie.Value = oRespCookie.Name;

                                        bMatch = true;

                                        break; //

                                    }

                                } // for each ReqCookies

                                if (!bMatch)

                                    this.oCookies.Add(oRespCookie);

                            } // for each Response.Cookies

                        }  // this.Cookies == null

                    } // if Response.Cookie.Count > 0

                }  // if this.bHandleCookies = 0

 

                // *** Save the response object for external access

                this.oWebResponse = Response;

 

                Encoding enc;

                try

                {

                    if (Response.ContentEncoding.Length > 0)

                        enc = Encoding.GetEncoding(Response.ContentEncoding);

                    else

                        enc = Encoding.GetEncoding(1252);

                }

                catch

                {

                    // *** Invalid encoding passed

                    enc = Encoding.GetEncoding(1252);

                }

 

                // *** drag to a stream

                StreamReader strResponse = new StreamReader(Response.GetResponseStream(), enc);

                return strResponse;

            }

            catch (Exception e)

            {

                if (this.bThrowExceptions)

                    throw e;

 

                this.cErrorMsg = e.Message;

                this.bError = true;

                return null;

            }

        }

 

        /// <summary>

        /// Return a the result from an HTTP Url into a StreamReader.

        /// Client code should call Close() on the returned object when done reading.

        /// </summary>

        /// <param name="Url">Url to retrieve.</param>

        /// <returns></returns>

        public StreamReader GetUrlStream(string Url)

        {

            HttpWebRequest oHttpWebRequest = null;

            return this.GetUrlStream(Url, oHttpWebRequest);

        }

 

        /// <summary>

        /// Return a the result from an HTTP Url into a StreamReader.

        /// Client code should call Close() on the returned object when done reading.

        /// </summary>

        /// <param name="Request">A Request object</param>

        /// <returns></returns>

        public StreamReader GetUrlStream(HttpWebRequest Request)

        {

            return this.GetUrlStream(Request.RequestUri.AbsoluteUri, Request);

        }

 

        /// <summary>

        /// Return a the result from an HTTP Url into a string.

        /// </summary>

        /// <param name="Url">Url to retrieve.</param>

        /// <returns></returns>

        public string GetUrl(string Url)

        {

            StreamReader oHttpResponse = this.GetUrlStream(Url);

            if (oHttpResponse == null)

                return "";

 

            string lcResult = oHttpResponse.ReadToEnd();

            oHttpResponse.Close();

 

            return lcResult;

        }

 

        /// <summary>

        /// Return a the result from an HTTP Url into a string.

        /// </summary>

        /// <param name="Url">Url to retrieve.</param>

        /// <returns></returns>

        public byte[] GetUrlBytes(string Url)

        {

            StreamReader oHttpResponse = this.GetUrlStream(Url);

 

            if (oHttpResponse == null)

            {

                return null;

            }

 

            string lcResult = oHttpResponse.ReadToEnd();

            oHttpResponse.Close();

 

            return null;

        }

 

        /// <summary>

        /// Retrieves URL with events in the OnReceiveData event.

        /// </summary>

        /// <param name="Url"></param>

        /// <param name="BufferSize"></param>

        /// <returns></returns>

        public string GetUrlEvents(string Url, long BufferSize)

        {

            StreamReader oHttpResponse = this.GetUrlStream(Url);

            if (oHttpResponse == null)

                return "";

 

            long lnSize = BufferSize;

            if (this.oWebResponse.ContentLength > 0)

                lnSize = this.oWebResponse.ContentLength;

            else

                lnSize = 0;

 

            Encoding enc = Encoding.GetEncoding(1252);

            StringBuilder loWriter = new StringBuilder((int)lnSize);

            char[] lcTemp = new char[BufferSize];

            OnReceiveDataEventArgs oArgs = new OnReceiveDataEventArgs();

            oArgs.TotalBytes = lnSize;

 

            lnSize = 1;

            int lnCount = 0;

            long lnTotalBytes = 0;

 

            while (lnSize > 0)

            {

                lnSize = oHttpResponse.Read(lcTemp, 0, (int)BufferSize);

                if (lnSize > 0)

                {

                    loWriter.Append(lcTemp, 0, (int)lnSize);

                    lnCount++;

                    lnTotalBytes += lnSize;

 

                    // *** Raise an event if hooked up

                    if (this.OnReceiveData != null)

                    {

                        /// *** Update the event handler

                        oArgs.CurrentByteCount = lnTotalBytes;

                        oArgs.NumberOfReads = lnCount;

                        oArgs.CurrentChunk = lcTemp;

                        this.OnReceiveData(this, oArgs);

 

                        // *** Check for cancelled flag

                        if (oArgs.Cancel)

                            goto CloseDown;

                    }

                }

            } // while

 

CloseDown:

            oHttpResponse.Close();

 

            // *** Send Done notification

            if (this.OnReceiveData != null && !oArgs.Cancel)

            {

                // *** Update the event handler

                oArgs.Done = true;

                this.OnReceiveData(this, oArgs);

            }

 

            //   return lcHtml;

            return loWriter.ToString();

        }

 

        public delegate void OnReceiveDataHandler(object sender, OnReceiveDataEventArgs e);

        public class OnReceiveDataEventArgs

        {

            public long CurrentByteCount = 0;

            public long TotalBytes = 0;

            public int NumberOfReads = 0;

 

            public char[] CurrentChunk;

            public bool Done = false;

            public bool Cancel = false;

        }

    }

}

其实微软有一个现成的类:WebClient可以实现文件上传等功能,不过这个类在NETCF下不受支持,没办法,只好采用替代品了,还好有人替我们完成了这样的工作J

微软的消息队列(MSMQ

这个就暂时不说了,涉及的内容较多,留待以后单独进行说明。

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值