精华内容
下载资源
问答
  • <p>I checked <code>default_socket_timeout</code> on the server and increased it.I also tried <code>base64_econde</code> the string, but SOAP is already encoding it by itself. <p>My code: <pre><code>...
  • 上一篇文章说道在用python的suds库的时候,发的中文总是乱码(windows下还总是encode失败,真是杯具),无奈产品经理又死活都要求是中文,今天研究了一天,总算是搞定了。 说一下定位的过程。1.先拿一段php的soap代码...

    上一篇文章说道在用python的suds库的时候,发的中文总是乱码(windows下还总是encode失败,真是杯具),无奈产品经理又死活都要求是中文,今天研究了一天,总算是搞定了。 说一下定位的过程。

    1.先拿一段php的soap代码来看:

    $client = new SoapClient("http://ws.sb.com/messageservice.asmx?wsdl",Array('trace'=>True));

    // 参数转为数组形式传递

    $aryPara = array('sender' => 'dantezhu',

    'receiver' => 'dantezhu',

    'title' => 'OZ评论消息提醒',

    'msgInfo' => 'sss',

    'messageType'=>0);

    // 调用远程函数

    $ret = $client->SendRTX($aryPara);

    var_dump($ret);

    echo $client->__getLastRequest();

    ?>

    这段代码是能够正确的发送请求的,通过__getLastRequest打出发送包,如下:

    dantezhu

    dantezhu

    OZ评论消息提醒

    sss

    0

    对HTTP请求抓包截图如下:

    611359a1ddfbffea2a31404cb3501cb1.png

    2.再来看一下用suds的代码:

    from suds.client import Client

    def SendRtx(target,title,content):

    url = "http://ws.sb.com/messageservice.asmx?wsdl"

    client = Client(url)

    client.service.SendRTX(

    sender = 'dantezhu',

    receiver = target,

    title = title,

    msgInfo = content,

    messageType = 0

    )

    senddata = client.last_sent()

    recvdata = client.last_received()

    f = file('ss.txt','wb')

    f.write(str(senddata))

    f.close()

    print senddata

    print '--------------------------------'

    print recvdata

    SendRtx('dantezhu',u'OZ我的天','ss')

    发送包XML如下:

    dantezhu

    dantezhu

    OZ我的天

    ss

    0

    抓包截图如下:

    0c70ccd08e10d94e1cd895839a4cd766.png

    抓包文件如下: https://www.vimer.cn/wp-content/uploads/2010/09/soapdata 3.仔细对比,发现确实发送的XML是不一样的,但是看了半天也没有发现suds的client有能够手工修改的地方。于是最终决定用urllib或者httplib直接实现。 比较幸运的是找到了这个链接,里面针对不同的webservice提供了不同的方法: http://users.skynet.be/pascalbotte/rcx-ws-doc/postxmlpython.htm 我们只要模拟一下php的发送的XML,用python来发送就可以啦~ 而我们使用的webservice是.net2.0,所以代码如下:

    import urllib2

    import sys, httplib

    def SendRtx(target,title,content):

    SENDTPL = \

    '''<?xml version="1.0" encoding="UTF-8"?>

    dantezhu

    %s

    %s

    %s

    0

    '''

    SoapMessage = SENDTPL % (target,title,content)

    webservice = httplib.HTTP("ws.sb.com")

    webservice.putrequest("POST", "/messageservice.asmx")

    webservice.putheader("Host", "ws.sb.com")

    webservice.putheader("User-Agent", "Python Post")

    webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")

    webservice.putheader("Content-length", "%d" % len(SoapMessage))

    webservice.putheader("SOAPAction", "\"http://ws.sb.com/common/message/SendRTX\"")

    webservice.endheaders()

    webservice.send(SoapMessage)

    # get the response

    statuscode, statusmessage, header = webservice.getreply()

    print "Response: ", statuscode, statusmessage

    print "headers: ", header

    print webservice.getfile().read()

    SendRtx('dantezhu',"素材管理系统","您的单")

    展开全文
  • 服务器的初始化(监听阶段)(1)调用socket函数创建文件描述符(直接设置端口)或者使用bind函数绑定端 口号或者ip函数(端口占用则会绑定失败)(2)调用listen函数声明当前这个文件描述符做为一个服务器的文件...

    一:传输协议的两种方式

    1.1 TCP协议

    440156f523e63884db1d2935a8071195.png
    https://blog.csdn.net/m0_38121874/article/details/81990457

    ea05a91bc3fbbe5e495b8a085c56c3be.png

    1,服务器的初始化(监听阶段)

    (1)调用socket函数创建文件描述符(直接设置端口)或者使用bind函数绑定端 口号或者ip函数(端口占用则会绑定失败)

    (2)调用listen函数声明当前这个文件描述符做为一个服务器的文件描述,为accept做准备

    (3)调用accept函数阻塞等待客户端连接

    2,建立三次连接(三次握手)

    71a8911bb4739358f10235aaa22213c2.png

    位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)

    Sequence number(顺序号码) Acknowledge number(确认号码)

    第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

    第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

     实例:
    
    IP 192.168.1.116.3337 > 192.168.1.123.7788: S 3626544836:3626544836
    IP 192.168.1.123.7788 > 192.168.1.116.3337: S 1739326486:1739326486 ack 3626544837
    IP 192.168.1.116.3337 > 192.168.1.123.7788: ack 1739326487,ack 1
    
    第一次握手:192.168.1.116发送位码syn=1,随机产生seq number=3626544836的数据包到192.168.1.123,192.168.1.123由SYN=1知道192.168.1.116要求建立联机;
    
    第二次握手:192.168.1.123收到请求后要确认联机信息,向192.168.1.116发送ack number=3626544837,syn=1,ack=1,随机产生seq=1739326486的包;
    
    第三次握手:192.168.1.116收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,192.168.1.116会再发送ack number=1739326487,ack=1,192.168.1.123收到后确认seq=seq+1,ack=1则连接建立成功。

    3、数据传输的过程(数据发送)

    建立连接后,TCP协议提供全双工的通信服务。所谓全双工,意思是:在同一条链路中的同一时刻,通信双方可以同时写数据。相对的概念叫做半双工,即:在同一条链路中的同一时刻,只能由一方来写数据。

    (1)服务器从accept函数返回后立刻调用read函数读socket里的数据。读socket就像读管道一样,如果没有数据到达就阻塞等待。

    (2)客户端调用write函数发送请求给服务器,服务器收到后就向客户端回复ACK,并从read函数中返回,对客户端的请求进行处理。在此期间客户端调用read函数阻塞等待服务器的应答。

    (3)服务器调用write函数将处理结果发回客户端,客户端收到后就回复ACK。服务器再次调用read函数阻塞等待下一条请求,。

    (4)客户端从read函数中返回,并发送下一条请求,如此循环下去。

    45054eb5c2eb6cf90d8d50e4f65be12d.png

    4、断开连接的过程——四次挥手

    b47b071aa16af7a01384007f20c74ff8.png

    1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

    2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

    3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

    4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

    5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

    6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

    常见面试题

    【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?

    答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

    【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态

    答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

    【问题3】为什么不能用两次握手进行连接?

    答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

    现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

    【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办?

    TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

    https://blog.csdn.net/qq_38950316/article/details/81087809blog.csdn.net
    展开全文
  • 发送XML失败

    2018-11-02 15:49:42
    soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:loc="http://api.atdconnect.com/atd/3_4/locations"> <soapenv:Header> <wsse:Security soapenv:mustUnderstand...
  • 前言:前几天在B站上面,看到了一个使用C/C++...具体效果:注意:爬取过程中,出现了几个time out,但是也不影响整个爬虫的工作(出现异常的图片,可能会损坏,但是几百张失败一两次还是可以接受的),所以这里也就...

    前言:
    前几天在B站上面,看到了一个使用C/C++实现的网络爬虫,我没有看视频,只是看了评论,这位up主应该就是只使用语言本身提供的包实现的爬虫。但是,我对这种方式很有兴趣,所以我就来实现一个Java版本的,正好也是综合运用自己学习的知识。

    具体效果:

    8226f05e29bde9226a8226e74c7ae053.gif
    dbc0b6c336539f0ee2caab5590678037.png

    注意:爬取过程中,出现了几个time out,但是也不影响整个爬虫的工作(出现异常的图片,可能会损坏,但是几百张失败一两次还是可以接受的),所以这里也就不处理它了,我测试了一下,把超时时间调高一点,并且当前网络通畅的话,也就不会遇到这个问题了。

    3e6055576505eaf980eb575f21de3d32.png

    给爷爬

    这里给它取一个有趣的名字吧——给爷爬

    这里我主要是想引入一个URL队列的概念,它的工作模式如下:
    1.初始添加一个种子URL入队列。
    2.从URL队列中取出一个URL,进行处理,将获取到新的URL加入队列(如果有新的URL的话)。
    3.重复步骤2,直到队列为空。

    通常,我们刚学习爬虫(现在,我也没有学习多久,哈哈。),只是一股脑的爬,比如按照页码来一个一个的爬取,先遇到的先爬取,这里其实都是有一个队列的思想的(先进先出 FIFO)。

    527d88c186bf59b19e042d8d07f31ce4.png


    所以,这里我分了几个模块来处理,下面就来依次介绍这几个部分。

    Request类

    一个简单的实体类,实现url和name属性的封装。

    package dragon;public class Request {private String url;   // urlprivate String name;  // namepublic Request(String url, String name) {super();this.url = url;this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}@Overridepublic String toString() {return "Picture [name=" + name + ", url=" + url + "]";}}12345678910111213141516171819202122232425262728293031323334

    MessageUtil类

    因为是使用语言本身提供的Socket来处理的,没有引入更高级的类库,所以处理起来相对麻烦一下。比如,需要自己手工构造HTTP请求报文、手工HTTP解析响应报文。不过,这里的请求报文,它的结构很简单,这个网站也没有什么反爬机制,用来练手很合适。

    package dragon;import java.nio.charset.StandardCharsets;/** * 构造一个适当的请求报文 * */public class MessageUtil {private final static String UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "+ "Chrome/86.0.4240.80 Safari/537.36 Edg/86.0.622.48";private final static char CR = '';private final static char LF = '';private final static char BLANK = ' ';public static byte[] getRequestMsg(String path, String host, String referer) {StringBuilder msgBuilder = new StringBuilder();msgBuilder.append("GET").append(BLANK).append(path).append(BLANK).append("HTTP/1.0").append(CR).append(LF)          .append("User-Agent:").append(BLANK).append(UA).append(CR).append(LF)  .append("Host:").append(BLANK).append(host).append(CR).append(LF)  .append("Upgrade-Insecure-Requests:").append(BLANK).append(1).append(CR).append(LF)  .append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9").append("")  .append(CR).append(LF);String msg = msgBuilder.toString();return msg.getBytes(StandardCharsets.UTF_8);}}1234567891011121314151617181920212223242526272829

    PageDownloader类

    使用套接字发送请求报文,接收响应报文。因为HTTP是建立在TCP之上的,所以请求报文和响应报文,也就是对应了套接字的OutputStream和InputStream了。但是,要注意这里使用的不是Socket,而是SSLSocket。因为,这个图片网站使用的是https协议,如果使用Socket的话,是无法建立连接的。这里,只要这样使用就行了,关于SSLSocket的详细情况,我也不是太了解。因为平时处理网络,都是使用高级api,它们会屏蔽这些细节的。
    这里需要了解HTTP和HTTPS的区别,SSLSocket就是安全层套接字。
    HTTP:Hyper Text Transport Protocol
    HTTPS:Hyper Text Transport Protocol Over SecureSocket Layer

    这个类的作用是下载html文件,它首先发送一个请求报文,然后接收响应报文。但是响应报文,是含有首部的,尽管我们平时是看不见的,所以这里返回的不只是html文件本身了,因此这里你需要了解一下HTTP报文的结构。

    daa29440452d16a9588fc87e85db8962.png

    所以我这里定义了一个方法:readMsgHeader(),直接读取首部并简单丢弃,不做处理。

    package dragon;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.MalformedURLException;import java.net.URL;import javax.net.ssl.SSLSocket;import javax.net.ssl.SSLSocketFactory;/** * 下载页面 * */public class PageDownloader {private static SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();// 利用工厂来创建SSLSocket安全套接字private final static int TIMEOUT = 10*1000;public String getHtml(String link, String cs) {URL url = null;try {url = new URL(link);} catch (MalformedURLException e1) {e1.printStackTrace();}String host = url.getHost();            // 获取主机 Hostint port = url.getPort() != -1 ? url.getPort() : 443;  // 获取端口号String path = url.getPath(); // 请求路径try (SSLSocket socket = (SSLSocket) factory.createSocket(host, port)) {socket.setSoTimeout(TIMEOUT);   // 设置超时时间// 启用所有密码组String[] supported = socket.getSupportedCipherSuites();socket.setEnabledCipherSuites(supported);// 获取输出流和输入流OutputStream output = new BufferedOutputStream(socket.getOutputStream());InputStream input = new BufferedInputStream(socket.getInputStream());// 使用输出流发送请求数据byte[] requestMsg = MessageUtil.getRequestMsg(path, host, link);output.write(requestMsg);output.flush();  // 刷新输出流,不然未发送请求,导致无法接收到响应// 过滤报文首部数据try {readMsgHeader(input);} catch (Exception e) {e.printStackTrace();System.out.println("连接发生异常,退出当前连接下载!");return null;}try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {int len = 0;byte[] b = new byte[2048];        while ((len = input.read(b)) != -1) {        out.write(b, 0, len);            }        return out.toString(cs);}} catch (IOException e) {e.printStackTrace();}return null;}/** * 读取报文头部,但是不做处理,只是简单的过滤头部的信息 * @throws Exception  * */private void readMsgHeader(InputStream in) throws Exception {StringBuilder sb = new StringBuilder();while (true) {int c = in.read();if (c != -1) {if (c != '') {sb.append((char)c);} else {int len = sb.length();if (len == 1) {break; // 读取到最后一行 ,退出循环。} else {sb.delete(0, len);}}} else {throw new Exception("连接发生异常!");}}}}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596

    UrlDownloader类

    用于下载图片的类,它的功能和前面的PageDownloader类基本相似,但是它是将获取的图片数据持久化到本地。

    package dragon;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.MalformedURLException;import java.net.URL;import java.net.UnknownHostException;import javax.net.ssl.SSLSocket;import javax.net.ssl.SSLSocketFactory;public class UrlDownloader implements Runnable {private static SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();// 利用工厂来创建SSLSocket安全套接字private final static int TIMEOUT = 10*1000;private Request request;private String filePath;public UrlDownloader(Request request, String filePath) {this.request = request;this.filePath = filePath;}@Overridepublic void run() {String link = request.getUrl();URL url = null;try {url = new URL(link);} catch (MalformedURLException e1) {e1.printStackTrace();}String host = url.getHost();            // 获取主机 Hostint port = url.getPort() != -1 ? url.getPort() : 443;  // 获取端口号String path = url.getPath(); // 请求路径try (SSLSocket socket = (SSLSocket) factory.createSocket(host, port)) {socket.setSoTimeout(TIMEOUT);   // 设置超时时间// 启用所有密码组String[] supported = socket.getSupportedCipherSuites();socket.setEnabledCipherSuites(supported);// 获取输出流和输入流OutputStream output = new BufferedOutputStream(socket.getOutputStream());InputStream input = new BufferedInputStream(socket.getInputStream());// 使用输出流发送请求数据byte[] requestMsg = MessageUtil.getRequestMsg(path, host, "https://www.showmeizi.com");output.write(requestMsg);output.flush();  // 刷新输出流,不然未发送请求,导致无法接收到响应// 过滤报文首部数据try {readMsgHeader(input);} catch (Exception e) {e.printStackTrace();System.out.println("连接发生异常,退出当前连接下载!");return ;}// 读取响应报文数据部,即图片本身的二进制数据try (OutputStream outputFile = new BufferedOutputStream(new FileOutputStream(new File(filePath, request.getName())))) {int len = 0;byte[] b = new byte[2048];        while ((len = input.read(b)) != -1) {        outputFile.write(b, 0, len);            }}} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}System.out.println("资源:" + link + " 抓取完成!");}/** * 读取报文头部,但是不做处理,只是简单的过滤头部的信息 * @throws Exception  * */private void readMsgHeader(InputStream in) throws Exception {StringBuilder sb = new StringBuilder();while (true) {int c = in.read();if (c != -1) {if (c != '') {sb.append((char)c);} else {int len = sb.length();if (len == 1) {break; // 读取到最后一行 ,退出循环。} else {sb.delete(0, len);}}} else {throw new Exception("连接发生异常!");}}}}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108

    DataCrawler类

    整个给爷爬的主要逻辑都在这个类里面了。这部分,就是关于网页结构的知识了。

    爬虫的轨迹是如下的:首先从根路径开始,获取根路径所在html页面的所有标题页(只获取第一页的所有标题页用于演示),然后对于每一个标题页提取所有的图片链接信息,最后依次下载每一条链接,总体上逻辑还是很简单的。

    package dragon;import java.util.LinkedList;import java.util.Queue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 准备不使用外部依赖,仅仅依靠语言本身的功能完成一个简单的数据采集任务。 * 用来检验自己这段时间的网络学习的成果,并加深对于 网络、协议、web的理解。 * */public class DataCrawler {// 用于存储待抓取数据url的队列private static Queue queue = new LinkedList<>();private static String filePath = "D:/DBC/Test";public static void main(String[] args) {System.out.println("启动 --> 给爷爬!");// 添加一个根路径,然后开始url调度queue.offer(new Request("https://www.showmeizi.com/category/qingchun", "qingchun"));// 下载对应的html页面PageDownloader pageDownloader = new PageDownloader();String html = null;// 创建一个线程池ExecutorService pool = Executors.newFixedThreadPool(2);  // 没有使用代理ip,而且只是验证,慢慢爬也无所谓了while(!queue.isEmpty()) {Request request = queue.poll();String url = request.getUrl();System.out.println("开始处理url:" + url + " --> " + request.getName());if (url.contains("category")) {  // 这个url是爬虫的起点html = pageDownloader.getHtml(url, "UTF-8");resolveRoot(html);} else if (url.contains("detail")) {  // 对应标题页的urlhtml = pageDownloader.getHtml(url, "UTF-8");resolveChild(html);} else {  // 图片对应的urlpool.submit(new UrlDownloader(request, filePath));}}pool.shutdown();// 采用轮询方式,当爬虫结束时打印该语句while (true) {if (pool.isTerminated()) {System.out.println("结束 --> 给爷爬");break;  }}}public static void resolveRoot(String html) {html = html.replace(' ', '_');   // 由于标题字符串中含有空格,所以先替换掉空格,再匹配String regex = "/detail/d{4}";                     // 匹配URLString regex1 = "/(S+|s*|S+)-thumbnail.jpg";   // 匹配对应的标题Pattern urlPattern = Pattern.compile(regex);Pattern titlePattern = Pattern.compile(regex1);Matcher urlMatcher = urlPattern.matcher(html);Matcher titleMatcher = titlePattern.matcher(html);while(urlMatcher.find() && titleMatcher.find()) {String url = urlMatcher.group();String title = titleMatcher.group();queue.offer(new Request("https://www.showmeizi.com" + url, title));   // 添加新的request对象进入队列,等待处理}}public static void resolveChild(String html) {html = html.replace(' ', '_');   // 由于标题字符串中含有空格,所以先替换掉空格,再匹配String regex = "/(S+)/d{2}[a-z]d{2}.jpg";                     // 匹配URLPattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(html);while(matcher.find()) {String url = matcher.group();String title = url.substring(url.lastIndexOf("/")+1);url = url.replace('_', ' ');  // 这里需要注意,有的路径含有空格,我将其替换了,现在再替换回去queue.offer(new Request("https://www.showmeizi.com" + url, title));   // 添加新的request对象进入队列,等待处理}}}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586

    总结

    这里使用Java网络编程+计算机网络的知识,而且是从一个底层开始处理(相对于应用层的底层,不是计算机网络的底层),具有很好的学习价值。特别是刚刚接触计算机网络的人,可以给人一种很直观感受,而不只是单纯书本上面的概念,并且学以致用,也是一种比较有效的学习方式。

    最后多说一句,小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,并私信“学习”即可领取。

    展开全文
  • 创建android工程MobileBelong,设置网络访问权限。   资源 Hello World, MainActivity!... 手机号归属地查询 ... 网络连接失败 布局 TextView android:layout_width="fill_parent" android:layout_heigh

    创建android工程MobileBelong,设置网络访问权限。

     

    资源

        <string name="hello">Hello World, MainActivity!</string>
        <string name="app_name">手机号归属地查询</string>
        <string name="mobile">手机号</string>
        <string name="button">查询</string>
        <string name="error">网络连接失败</string>
    

    布局

    TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/mobile" />
    
        <EditText
            android:id="@+id/mobile"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="13472283596" />
    
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button" />
    
        <TextView
            android:id="@+id/result"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    

    在src目录下创建mobilesoap.xml,并将网址文档中提供的代码复制其中,如下

    <?xml version="1.0" encoding="utf-8"?>
    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
      <soap12:Body>
        <getMobileCodeInfo xmlns="http://WebXml.com.cn/">
          <mobileCode>$mobile</mobileCode>
          <userID></userID>
        </getMobileCodeInfo>
      </soap12:Body>
    </soap12:Envelope>
    

    业务类:MobileService

    注意访问目标地址是:

    http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx

    可以有协议中得到。


    package cn.class3g.service;
    …
    public class MobileService {
    
    public static String getMobileAddress(String mobile) throws Exception {
    
    		InputStream inStream = MobileService.class.getClassLoader()
    				.getResourceAsStream("mobilesoap.xml");
    		byte[] data = StreamTool.readInputStream(inStream);
    		String xml = new String(data);
    		String soap = xml.replaceAll("\\$mobile", mobile);
    
    		/**
    		 * 正则表达式$为特殊正则中的特殊符号须转义,即\$mobile
    		 * 而\为字符串中的特殊符号,所以用两个反斜杠,即"\\{1}quot;
    		 */
    		String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
    		data = soap.getBytes();// 得到了xml的实体数据
    		URL url = new URL(path);
    		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    		conn.setConnectTimeout(5 * 1000);
    		conn.setRequestMethod("POST");
    		conn.setDoOutput(true);
    		conn.setRequestProperty("Content-Type",
    				"application/soap+xml; charset=utf-8");
    		conn.setRequestProperty("Content-Length", String.valueOf(data.length));
    		OutputStream outStream = conn.getOutputStream();
    		outStream.write(data);
    		outStream.flush();
    		outStream.close();
    		if (conn.getResponseCode() == 200) {
    			InputStream responseStream = conn.getInputStream();
    			return parseXML(responseStream);
    		}
    		return null;
    	}
    
    	/**
    	 * 解析返回xml数据
    	 * 
    	 * @param responseStream
    	 * @return
    	 * @throws Exception
    	 */
    	private static String parseXML(InputStream responseStream) throws Exception {
    		XmlPullParser parser = Xml.newPullParser();
    		parser.setInput(responseStream, "UTF-8");
    		int event = parser.getEventType();
    		while (event != XmlPullParser.END_DOCUMENT) {
    			switch (event) {
    			case XmlPullParser.START_TAG:
    				if ("getMobileCodeInfoResult".equals(parser.getName())) {
    					return parser.nextText();
    				}
    				break;
    			}
    			event = parser.next();
    		}
    		return null;
    	}
    }
    

    工具类StreamTool

    package cn.class3g.utils;
    …
    public class StreamTool {
    	/**
    	 * 从输入流读取数据
    	 * @param inStream
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] readInputStream(InputStream inStream) throws Exception{
    		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
    		byte[] buffer = new byte[1024];
    		int len = 0;
    		while( (len = inStream.read(buffer)) !=-1 ){
    			outSteam.write(buffer, 0, len);
    		}
    		outSteam.close();
    		inStream.close();
    		return outSteam.toByteArray();
    	}
    }
    
    Activity类MobileBelongActivity
    package cn.class3g.mobile;
    …
    public class MobileBelongActivity extends Activity {
    
    	private static final String TAG = "MainActivity";
    	private EditText mobileText;
    	private TextView resultView;
    
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    
    		mobileText = (EditText) this.findViewById(R.id.mobile);
    		resultView = (TextView) this.findViewById(R.id.result);
    		Button button = (Button) this.findViewById(R.id.button);
    		button.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				String mobile = mobileText.getText().toString();
    				try {
    					String address = MobileService.getMobileAddress(mobile);
    					resultView.setText(address);
    				} catch (Exception e) {
    					Log.e(TAG, e.toString());
    					Toast.makeText(MobileBelongActivity.this, R.string.error, 1).show();
    				}
    			}
    		});
    	}
    }
    



    展开全文
  • 问题:没有终结点在侦听可以接受消息...这通常是由于不正确的地址或者 SOAP 操作导致的。如果存在此情况,请参见 InnerException 以了解详细信息。解决方案: 把web.config配置文件里的http://sdk999ws.eucp.b2m.cn...
  • 项目描述 使用biztalk2006在vs2005开发环境中做一个简单的测试业务流程,主要是测试使用biztalk发布一个web services,这个web services接受用户发送的请求,然后根据用户要求通过sql adapter到sql server数据库中...
  • 顺丰BSP接口SOAP的请求示例... 针对顺丰接口的SOAP请求的核心代码分享如下: /** * 发送soap请求 */ p顺丰BSP接口SOAP的请求示例在一些接口的设计中有时用到了SOAP方式的请求,比如顺丰BSP的接口。我尝试不同方式的P...
  • 在一些接口的设计中有时用到了SOAP方式的请求,比如...针对顺丰接口的SOAP请求的核心代码分享如下:代码如下:/*** 发送soap请求*/private function _soap(){$client = new SoapClient($this->serviceUrl);$info =...
  • method:[unknown]msg:try again: Unable to connect to the MTAcode:mail.TRY_AGAINdetail:soap:Receivertrace:...
  • webservice soap报文是xml格式交互的,当中针对特殊字符传递无法解析,导致数据处理失败。解决的方法例如以下:1、在发送报文之前,针对报文进行base64转码,转义后避免报文中含有特殊字符。标准base64中是以%开头的...
  • tcp连接偶尔失败

    2020-03-12 15:10:51
    文章目录问题描述解决流程...但是我们客户端发送消息偶尔失败。 使用了psping工具,ping我们的服务器端口,发现会有ping不通的时候。 .\psping -n 10 -w 2 -h 10 www.baidu.com:80 参考 解决流程 怀疑是客户网络线...
  • * @return String success:发送成功 fail:发送失败 */ public static String requestService(String phoneNumber, String content, String templateNo) { String result = ""; try { URL url = new ...
  • 如果你具有 Confluence 管理员的权限,你可以限制 Confluence 登录失败的最大尝试次数。在给予最大登录失败尝试...同样的,在 3 次错误尝试的XML-RPC 或者 SOAP API,一个错误的信息将会发送给用户,提示用户通...
  • 搜索热词微信回复原理:当普通微信用户向公众账号发送消息时,微信服务器首先收到用户发送的消息;然后将用户信息和消息打包成XML格式的数据包,再将...POST只能保存标准的数据类型,对于XML、SOAP或Application/Oct...
  • 微信回复原理:当普通微信用户向公众账号发送消息时,微信服务器首先收到用户发送的消息;然后将用户信息和消息打包成XML格式的数据包,再将这个...回答:POST只能保存标准的数据类型,对于XML、SOAP或Application/...
  • 我调用webservice服务的接口,发送请求数据,为什么第一次调用接口的时候,总是失败,报错,然后紧接着我在继续调用,就成功了,不报错了,有大神能解释一下为什么吗?代码和报错如下: 报错: webService方法推送...
  • 1.利用JAXM发送SOAPMessage失败,只能发送到本地环回地址127.0.0.1或者localhost,而不能发送到一个实体IP 解决问题思路: 1.SOAPMessage构造是否有问题,检查后发现没问题 2.系统防火墙是否影响,检查后发现...
  • WCF 可靠会话

    2013-02-07 22:17:00
    此消息传递通过克服传输失败SOAP 消息级别失败,可在不可靠的网络上实现传输可靠性。具体而言,它为跨 SOAP 或传输中介发送的消息提供了一种基于会话的、单一的和(可选)有序的传送。基于对话的传送可按消息的...
  •  因为需要做一个推送数据的服务,需要调用webservice,由于某种原因需要使用用http发送soap请求,而推送的数据是json格式的,在测试过程中发现请求失败,服务端webservice返回400错误。返回400错误,应该就是请求的...
  • BEA-3XXXXX错误代码

    2021-04-07 15:45:53
    传输运行时错误 (BEA-380000 至 BEA-38099...绑定层的常规解析失败(例如,发送至 XML 服务的消息不是 XML) BEA-382031 不符合 WS-I 标准 BEA-382032 消息必须是 soap:Envelope XML 详细信息: 收到一个非 SOAP 或无
  • 原理:通过HTTP协议发送XML数据并调用webservice(soap)   首先定义string.xml   手机号码归属查询 手机号 查询 连接失败   构建一个布局:   ...
  • 1.取样器(sample)(在线程组下面):发送各种协议(http,FTP,java,JMS,lamp,mail,MongoDB,SMTP,SOAP,TCP,Junit,BeanSheel脚本)的请求,接受服务器的响应数据 2.断言(检查点):验证结果 用一个预设的...
  • webservice soap报文是xml格式交互的,当中针对特殊字符传递无法解析,导致数据处理失败。 解决的方法例如以下: 1、在发送报文之前,针对报文进行base64转码,转义后避免报文中含有特殊字符。 标准base64中是以%...

空空如也

空空如也

1 2 3
收藏数 45
精华内容 18
关键字:

发送soap失败