问题如上,我之前用Webreques和Webresponse写了一个程序,将xml文件传到web服务器,但当xml稍长时,就会出现time out问题,所以现在想用socket实现。但本人对socket不是很懂,不知道怎么下手,在网上搜索也没找到有用的资料。
请高手赐教。谢谢,功能类似于web客户端的功能,要能接受服务器端传来的信息,而且用socket实现。谢谢!!!

解决方案 »

  1.   

    尝试把 Webrequest 的 timeout 属性 时间弄大点,应该能解决。
    如果用socket 得实现HTTP 组件功能,比较麻烦,以下是我写的代码,可以参考一下:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Text.RegularExpressions;namespace WorkFrame
    {
        public class MyHttp
        {
            public static string HttpRequest(string url,string senddata,string method,string cookie)
            {
                StringBuilder responsedata = new StringBuilder();
                byte[] data = new byte[1024];
                string stringData;
                Uri uri = new Uri(url);
                IPHostEntry gist = Dns.GetHostByName(uri.Host);            IPAddress ip = gist.AddressList[0];     //得到IP
                IPEndPoint ipEnd = new IPEndPoint(ip, 80);//默认80端口号            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//使用tcp协议 stream类型 
                try
                {
                    socket.Connect(ipEnd);
                }
                catch (SocketException e)
                {
                    throw(new Exception("Connect "+url+" failed:"+e.Message));
                }
                Byte[] B = System.Text.Encoding.ASCII.GetBytes(senddata);            StringBuilder buf = new StringBuilder();
                buf.Append(method+" ").Append(uri.LocalPath).Append(" HTTP/1.1\r\n");
                buf.Append("Accept: */*\r\n");
                buf.Append("Referer: "+url+"\r\n");
                buf.Append("Accept-Language: zh-cn\r\n");
                buf.Append("Content-Type: application/x-www-form-urlencoded\r\n");
                buf.Append("UA-CPU: x86\r\n");
                buf.Append("Accept-Encoding: gzip, deflate\r\n");
                buf.Append("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; WPS; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\n");
                buf.Append("Host: "+uri.Host+"\r\n");
                buf.Append("Content-Length: "+B.Length+"\r\n");
                buf.Append("Connection: Keep-Alive\r\n");
                buf.Append("Cache-Control: no-cache\r\n");
                buf.Append("Cookie:"+cookie+"\r\n");
                buf.Append("\r\n");
                buf.Append(senddata);
                byte[] ms = System.Text.UTF8Encoding.ASCII.GetBytes(buf.ToString());            socket.Send(ms);            int recv = -1;
                do
                {
                    recv = socket.Receive(data);
                    stringData = Encoding.ASCII.GetString(data, 0, recv);//如果请求的页面meta中指定了页面的encoding为gb2312则需要使用对应的Encoding来对字节进行转换
                    responsedata.Append(stringData);            } while (recv <1024);            socket.Shutdown(SocketShutdown.Both);
                socket.Close();            string result = responsedata.ToString();
                string encode = GetEncodeFromResponse(result);
                if (string.IsNullOrEmpty(encode))
                {
                    encode = "ASCII";
                }
                Encoding encoding = Encoding.GetEncoding(encode);
                byte[] asciibyte=Encoding.ASCII.GetBytes(result);
                byte[] encodebyte = Encoding.Convert(Encoding.ASCII,encoding,asciibyte);            return encoding.GetString(encodebyte);
            }        public static string GetCookieFromResponse(string responsePage)
            {
                StringBuilder cookie = new StringBuilder();
                Regex regex = new Regex(@"Set-Cookie: .* Path=/");
                MatchCollection matches = regex.Matches(responsePage);
                foreach (Match item in matches)
                {
                    int length = item.Groups.Count;
                    for (int i = 0; i < length; i++)
                    {
                        cookie.Append(item.Groups[i].Value.Replace("Set-Cookie: ", "") + ";");
                    }
                }            return cookie.ToString();
            }        private static string GetEncodeFromResponse(string responsePage)
            {
                string encode = "";
                Regex regex = new Regex(@"charset=\S*\r\n");
                Match m = regex.Match(responsePage);
                if (m.Groups.Count > 0)
                {
                    return m.Groups[0].Value.Replace("charset=","").Replace("\r\n","");
                }
                return "";
            }
        }
    }
      

  2.   

    不了解socket最好不要用它来进行传输.那才叫不爽呢,慢的很
      

  3.   

    socket会慢?http不慢?
    http也是基于tcp的好不好.
      

  4.   

    要驾御Socket要投入很多精力时间,要想长久稳定更非易事。
      

  5.   


    设置WebRequest的Timeout属性即可
      

  6.   

    www.cnblogs.com/hanguoji/archive/2006/08/09/472004.html
      

  7.   

    我已经设置了WebRequest的TimeOut属性了。
    程序是在datar = objresponse.GetResponseStream();这句出现Time Out异常的,不明白是什么原因
      

  8.   

    而且我用socket写,在同一个地方出现异常
      

  9.   


    这里的timeout用的就是webrequest的timeout,你把时间再放大一点试试呢
      

  10.   

    我放大到1000000,还是出现异常。我都快吐血了,更让我崩溃的是用socket写的程序,也在receive数据时卡住了。
    不是服务器的问题,因为我用短一点的数据,就不会卡住,而且回复很快
      

  11.   


    尝试过用BeginGetResponse()异步调用吗?
      

  12.   


    你不需要直接用socket了,出错的原因不在于webrequest
      

  13.   

    我试一下:出错的原因在哪?是没用BeginGetResponse()吗?
      

  14.   

    我是建议你尝试一下使用BeginGetResponse()代替GetResponse(),试一下看看。
      

  15.   

    BeginGetResponse()在什么时候调用呀?它的作用是什么?用这个后,还需要写WebResponse objresponse =objrequest.GetResponse();datar = objresponse.GetResponseStream();这两句吗?
    谢谢!!
      

  16.   

    传输一个XML文件只用同步的SOCKET就可以了吧?没上面说的要什么异步,加锁,解锁之类的这么麻烦吧?
      

  17.   

    BeginGetResponse()
    代替
    WebResponse objresponse =objrequest.GetResponse();
    具体使用方法你参考一下MSDN吧,这是异步的调用方法。
      

  18.   

    不是传输xml文件,是一个xml格式的string.我是用string来传递的
    现在,用socket写的有回应了,但速度相当慢
      

  19.   

       看下你的服务端在解析xml的时候,是不是耗的时间太长了。或者你依据请求消息而返回的内容太大了。
        应该不是Http访问还是socket访问的问题。
      

  20.   

    我用html的form提交同样的xml字串,证明是好的,回复非常快。
    高手帮帮忙呀!!!
      

  21.   

    我用BeginGetResponse()异步调用还是会出现:The operation has timed out 错误
      

  22.   

    你是发送一个xml字符串?方便的话把你的关键代码发上来吧
      

  23.   

    好的
    这是WebRequest同步调用的代码:
    public String POST_TO_DMC(String url, String ServerName, String Version, String UserName, String Psd, String AcknowledgementsTo)
            data)
    {
                String strRec = null;
                try
                {
                    String poststr = null;
                    poststr += "Servername=" + ServerName;
                    poststr += "&Version=" + Version;
                    poststr += "&Username=" + UserName;
                    poststr += "&Password=" + Psd;
                    poststr+="&AcknowledgementsTo"+AcknowledgementsTo;
                    poststr += "&XML=" + data;                Encoding UTF8 = Encoding.UTF8;                Byte[] bytePost = UTF8.GetBytes(poststr);                Stream datas, datar;              
                    HttpWebRequest objrequest = (HttpWebRequest)WebRequest.Create(url); 
                    objrequest.Timeout = 1000000;                objrequest.KeepAlive = true;
                    objrequest.Credentials = CredentialCache.DefaultCredentials;
                    objrequest.Method = "POST";
                    //MessageBox.Show(poststr.Length.ToString());
                    objrequest.ContentLength = bytePost.LongLength;
                    objrequest.ContentType = "application/x-www-url-encoded";
                    datas = objrequest.GetRequestStream();//Create request Stream
                    datas.Write(bytePost, 0, bytePost.Length);//Send data
                    datas.Close();                HttpWebResponse objresponse = (HttpWebResponse)objrequest.GetResponse();
                    datar = objresponse.GetResponseStream();//程序走到这一步,就会跳到catch块处理
                    StreamReader r = new StreamReader(datar);
                    strRec = r.ReadToEnd();                datar.Close();
                    r.Close();
                    objresponse.Close();            }
                catch (ArgumentNullException Ex)
                {
                    MessageBox.Show("Message : " + Ex.Message);
                }
                catch (NullReferenceException Ex)
                {
                    MessageBox.Show("Message : " + Ex.Message);
                }
                catch (Exception Ex)
                {
                    MessageBox.Show("Source : " + Ex.Source+"Message : "+Ex.Message);//报异常:The Operation has timed out            }
                return strRec;
            }
    谢谢0009
      

  24.   

    函数定义是这样: public String POST_TO_DMC(String url, String ServerName, String Version, String UserName, String Psd, String AcknowledgementsTo,String data)
    我测试的错误data:
     String data = "<!DOCTYPE DMConnect SYSTEM \"DMConnect.dtd\"><DMConnect>";
     data+="<CreateMailing><AcknowledgementsTo><EmailAddress>[email protected]</EmailAddress>";
     data+="<Option>9</Option></AcknowledgementsTo><MailingType>StandardMailing</MailingType>";
     data+="<ClientName>APAC_Sales</ClientName><SiteName>Hans_Practise</SiteName>";
     data+="<CampaignName>Ryan_QuickSend</CampaignName><MailingName>DeskTopMsgTest</MailingName>";
     data+="<ToList><ListName>ListTest</ListName></ToList><Filter></Filter>";
     data+="<Subject>This is a test!!</Subject><MessageContent><TextBody><BodyText><![CDATA[Hi everyone:Welocome to Epsilon!\r\nName\r\n]]></BodyText></TextBody>";
     data+="<HtmlBody><BodyText><![CDATA[<html><head><title>This is a test!</title><br /</head><body>Welcome to Epsilon</body></html>]]></BodyText></HtmlBody></MessageContent>"; data+="<HtmlOpenRateFlag>1</HtmlOpenRateFlag><AutosenseFlag>1</AutosenseFlag><CookieOptionFlag>0</CookieOptionFlag></CreateMailing></DMConnect>";
    谢谢大家
      

  25.   

    同样的,用socket写在同一个地方出现了同样错误:
     public static string HttpRequest(String url, String ServerName, String Version, String UserName, String Psd, String senddata)
            {
                String result=null;
                try{
                     String poststr = null;
                     poststr += "Servername=" + ServerName;
                     poststr += "&Version=" + Version;
                     poststr += "&Username=" + UserName;
                     poststr += "&Password=" + Psd;
                     poststr += "&XML=" + senddata;
                     byte[] data = new byte[1024];
                     string stringData;
                     Uri uri = new Uri(url);
                     IPHostEntry gist = Dns.GetHostByName(uri.Host);                 IPAddress ip = gist.AddressList[0];    //得到IP 
                     IPEndPoint ipEnd = new IPEndPoint(ip, 80);//默认80端口号                  Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//使用tcp协议 stream类型                      socket.Connect(ipEnd);
                     
                     Byte[] B = System.Text.Encoding.UTF8.GetBytes(poststr);                 StringBuilder buf = new StringBuilder();
                     buf.Append("POST " + " ").Append(uri.LocalPath).Append(" HTTP/1.0\r\n");
                     buf.Append("Content-Type: application/x-www-form-urlencoded\r\n");
                     buf.Append("Host: " + uri.Host + "\r\n");
                     buf.Append("Content-Length: " + B.Length + "\r\n");
                     buf.Append("\r\n");
                     buf.Append(poststr);
                     buf.Append("\r\n");
                     byte[] ms = System.Text.UTF8Encoding.UTF8.GetBytes(buf.ToString());                 socket.Send(ms);                int i=socket.Receive(data);//走到这步就不会往下走了
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();                result = Encoding.UTF8.GetString(data);
      
                catch (SocketException fe)
                {
                    MessageBox.Show(fe.Message);//报异常,而且13分钟才有回应
                }
                return result;
            } 
      

  26.   


                    poststr += "Servername=" + HttpUtility.UrlEncode(ServerName);
                    poststr += "&Version=" + HttpUtility.UrlEncode(Version);
                    poststr += "&Username=" + HttpUtility.UrlEncode(UserName);
                    poststr += "&Password=" + HttpUtility.UrlEncode(Psd);
                    poststr += "&AcknowledgementsTo" + HttpUtility.UrlEncode(AcknowledgementsTo);
                    poststr += "&XML=" + HttpUtility.UrlEncode(data);参数是要编码的。但是我也看不出来其它地方有问题,我本地模拟测试结果是没问题的。
      

  27.   

    我已经用 byte[] ms = System.Text.UTF8Encoding.UTF8.GetBytes(buf.ToString());这一句编码了,而且我是用二进制传输的
      

  28.   

    用这种方法,有什么长度上面的限制吗?因为如果这里面的data比较小,服务器是正常的
      

  29.   

    呵呵--多亏你的意见:字符串要进行unicode编码,第二是我将string都变成了stringbuilder.
    然后它就好了