精华内容
下载资源
问答
  • SocketURL通信比较

    2015-06-02 14:29:24
    Socket与URL通信比较!  这是咱哥们考研面试的问的一道题,说难不难,说简单不简单,下面这个回答比较... 利用socket进行通信时,在服务器端运行socket通信程序。服务器端不停地监听某个端口,等待客户的连接申
    
    Socket与URL
    通信比较!
    
             这是咱哥们考研面试的问的一道题,说难不难,说简单不简单,下面这个回答比较好,摘录学习了。

             利用URL进行通信与利用socket进行通信有许多相似之处。它们都是利用建立连接、获取流来进行通信。那么,它们的区别在何处呢?
           利用socket进行通信时,在服务器端运行一个socket通信程序。服务器端不停地监听某个端口,等待客户的连接申请,接到申请后建立连接并进行通信,所以,在socket通信方式中,服务器是主动等待连接通信的到来。
           利用URL进行通信时,在服务器端常驻一个CGI程序,但它一直处于休眠状态。只有在客户端要求建立连接时才被激活,然后与用户进行通信。所以,在URL通信方式中,服务器是被动等待连接通信的到来。
           由于URL通信和socket通信的方式不同,所以,它们有各自的特点。利用socket进行通信时,服务器端的程序可以打开多个线程与多个客户进行通信,还可以通过服务器使各个客户之间进行通信。这种方式比较灵活,适用于一些较复杂的通信,但是服务器端的程序必须始终处于运行状态以监听端口。利用URL进行通信时,服务器端的程序只能与一个客户进行通信,形式比较单一。但是它不需要服务器端的CGI程序一直处于运行状态,只是在有客户申请时才被激活。所以,这种方式比较适用于客户机的浏览器与服务器之间的通信。
             这是咱哥们考研面试的问的一道题,说难不难,说简单不简单,下面这个回答比较好,摘录学习了。

    展开全文
  • socket通信: 1、创建ServerSocketSocket 2、打开连接到Socket的输入/输出流 3、安照协议对Socket进行读/写操作 4、关闭输入输出流、关闭Socket 完成个用户的登录功能 编写程序代码如下: 启动先启动服务端,再...

    根据慕课网学习记录:https://www.imooc.com/video/3077

    1、InetAddress类

    用于标识网络上的硬件资源,表示互联网协议(IP)地址

    这个类没有构造函数,没有办法用new方法来新建类,但是提供了静态方法,可以获取实例

    具体代码:

    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.util.Arrays;
    
    /*
     * InetAdrress类*/
    public class Test01 {
    	public static void main(String[] args) throws UnknownHostException {
    		//获取本机的InetAdress实例
    		InetAddress address=InetAddress.getLocalHost();
    	    System.out.println("计算机名:"+address.getHostName());
    	    System.out.println("IP地址:"+address.getHostAddress());
    	    byte[] bytes=address.getAddress();//获取字节数组形式的地址
    	    System.out.println("字节数组形式的地址:"+Arrays.toString(bytes));
            System.out.println(address);	
            
            //也可以根据计算机名,IP地址来访问
            InetAddress address2=InetAddress.getByName("DESKTOP-0PG7U41");
            
            InetAddress address3=InetAddress.getByAddress("DESKTOP-0PG7U41",bytes);
            System.out.println("计算机名:"+address3.getHostName());
    	    System.out.println("IP地址:"+address2.getHostAddress());
    	}
    }
    
    字节数组形式的地址:[10, -81, -94, 33]
    DESKTOP-0PG7U41/10.175.162.33
    计算机名:DESKTOP-0PG7U41
    IP地址:10.175.162.33
    

    2、URL

        创建URL

        URL(Uniform Resource Locator)统一资源定位符,表示Internet上的某一资源的地址

        URL由两部分组成:https://mp.csdn.net/postedit,协议名称 http  和资源名称,中间以冒号隔开

        在java.net包中,提供了URL类来表示URL

    import java.net.MalformedURLException;
    import java.net.URL;
    
    public class Test02 {
    	public static void main(String[] args) {
    		//创建一个url实例
    		try {
    			URL imooc=new URL("http://www.imooc.com");
    			//后面?表示参数,#表示锚点,采用父URL生成子URL
    			URL url=new URL(imooc,"/index.html?username=tom#test");
    			System.out.println("协议:"+url.getProtocol());
    			System.out.println("主机:"+url.getHost());
    			//如果未指定端口号,则使用默认端口,此时该方法返回的是-1
    			System.out.println("文件路径:"+url.getPort());
    			System.out.println("文件名:"+url.getPath());
    			System.out.println("相对路径:"+url.getRef());
    			System.out.println("查询字符串:"+url.getQuery());
    		} catch (MalformedURLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

    协议:http
    主机:www.imooc.com
    文件路径:-1
    文件名:/index.html
    相对路径:test
    查询字符串:username=tom

    使用URL读取网页内容

    1、通过URL对象的openStream()方法可以得到指定资源的输入流

    2、通过输入流可以读取,访问网络上的数据

    ps:读取数据有很多种方法,各有各的特点

    比如说字节流中,InputStream是最基本的,FileInputStream用来读取文件,DataInputStream适用于读取各种类型的数据,BufferedInputStream加缓冲可以提高IO性能

    字符流中也有相应的类,InputStreamReader,FileReader,BufferedReader

    其中BufferedReader有一个方法readLine(),可以一行一行读取,这个方法其他的都没有,使用起来比较方便

    再看它的构造方法,需要传入Reader类型的参数,那么就必须再它前面new一个InputStreamReader,所以需要把字节流转换成字符流 如果不转换也可以,直接使用InputStream或者BufferedInputStream,一个字节一个字节读,或定义数组一些字节一些字节一起读,都可以,只不过没有一行一行读方便

    /*
     * 使用URL读取页面内容*/
    public class Test03 {
    	public static void main(String[] args) {
    		
    		try {
    			//创建一个URL实例
    			URL url = new URL("http://www.baidu.com");
    			//通过URL的openStream方法获取URL对象所表示的资源的字节输入流
    			java.io.InputStream is=url.openStream();
    			//将字节输入流转换为字符输入流
    			InputStreamReader isr=new InputStreamReader(is,"utf-8");
    			//为字符输入流添加缓存
    			BufferedReader br=new BufferedReader(isr);
    			String data=br.readLine();
    			while(data!=null) {
    				System.out.println(data);
    				data=br.readLine();
    			}
    			br.close();
    			isr.close();
    			is.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		
    	}
    }

    Socket通信

    TCP协议是面向连接、可靠的、有序的,以字节流的方式发送数据

    基于TCP协议实现网络通信的类

        客户端的Socket类

        服务端的ServerSocket类


    socket通信:

    1、创建ServerSocket和Socket

    2、打开连接到Socket的输入/输出流

    3、安照协议对Socket进行读/写操作

    4、关闭输入输出流、关闭Socket

    完成一个用户的登录功能


    编写程序代码如下:

    启动先启动服务端,再启动客户端

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    public class Server {
    	public static void main(String[] args) {
    		try {
    		//1、创建一个服务器Socket
    		ServerSocket serverSocket=new ServerSocket(8888);
    		//2、调用accept()方法开始监听,等待客户端的请求
    		System.out.println("*****服务器启动,等待客户连接******");
    		Socket socket=serverSocket.accept();
    		//3、获取输入流,读取客户端信息
    		InputStream is=socket.getInputStream();
    		//将字节输入流转换为字符输入流
    		InputStreamReader isr=new InputStreamReader(is);
    		//为字符输入流添加缓存
    		BufferedReader br=new BufferedReader(isr);
    		String info=null;
    		
    		while((info=br.readLine())!=null) {
    			System.out.println("我是服务器,客户端说:"+info);
    		}
    		socket.shutdownInput();//关闭输入流
    		
    		//4、关闭资源
    		br.close();
    		isr.close();
    		is.close();
    		socket.close();
    		serverSocket.close();
    		}catch(IOException e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import org.omg.CORBA.portable.OutputStream;
    
    public class Client {
    	public static void main(String[] args) {
    		
    		try {
    			//1、创建客户端socket
    			Socket socket=new Socket("localhost",8888);
    			//2、获取输出流,向服务端发送信息
    			java.io.OutputStream os=socket.getOutputStream();//字节输出流
    			PrintWriter pw=new PrintWriter(os);//把输出流包装为打印流
    			pw.write("用户名:admin;密码:123");
    			pw.flush();
    			socket.shutdownOutput();
    			
    			//3、关闭其他资源
    			pw.close();
    			os.close();
    			socket.close();
    		} catch (UnknownHostException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		
    	}
    }
    *****服务器启动,等待客户连接******
    我是服务器,客户端说:用户名:admin;密码:123
    




    展开全文
  • socket协议基础知识

    千次阅读 2009-10-14 15:05:00
    在这里作为4BDSUNIX的进程通信机制,取后一意思。socket非常类似于电话插座。以个国家级电话网为例。电话的通话双方相当于相互通信的2个进程,区号是它的网络地址;区内个单位的交换机相当于台主机,主机...

    Socket协议的形象描述


      socket的英文原义是“孔”或“插座”。在这里作为4BDS UNIX的进程通信机制,取后一种意思。socket非常类似于电话插座。以一个国家级电话网为例。电话的通话双方相当于相互通信的2个进程,区号是它的 网络地址;区内一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于socket号。任何用户在通话之前,首先要占有一部电话机,相当于 申请一个socket;同时要知道对方的号码,相当于对方有一个固定的socket。然后向对方拨号呼叫,相当于发出连接请求(假如对方不在同一区内,还 要拨对方区号,相当于给出网络地址)。对方假如在场并空闲(相当于通信的另一主机开机且可以接受连接请求),拿起电话话筒,双方就可以正式通话,相当于连 接成功。双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。通话结束后,一 方挂起电话机相当于关闭socket,撤消连接。


      在电话系统中,一般用户只能感受到本地电话机和对方电话号码的存在,建立通话的过程,话音传输 的过程以及整个电话系统的技术细节对他都是透明的,这也与socket机制非常相似。socket利用网间网通信设施实现进程通信,但它对通信设施的细节 毫不关心,只要通信设施能提供足够的通信能力,它就满足了。


      至此,我们对socket进行了直观的描述。抽象出来,socket实质上提供了进程通信的端 点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。正如打电话之前,双方必须各自拥有一台电话机一样。在网间网内 部,每一个socket用一个半相关描述:


      (协议,本地地址,本地端口)


      一个完整的socket有一个本地唯一的socket号,由操作系统分配。


      最重要的是,socket 是面向客户/服务器模型而设计的,针对客户和服务器程序提供不同的socket 系统调用。客户随机申请一个socket (相当于一个想打电话的人可以在任何一台入网电话上拨号呼叫),系统为之分配一个socket号;服务器拥有全局公认的 socket ,任何客户都可以向它发出连接请求和信息请求(相当于一个被呼叫的电话拥有一个呼叫方知道的电话号码)。


      socket利用客户/服务器模式巧妙地解决了进程之间建立通信连接的问题。服务器 socket 半相关为全局所公认非常重要。读者不妨考虑一下,两个完全随机的用户进程之间如何建立通信?假如通信双方没有任何一方的socket 固定,就好比打电话的双方彼此不知道对方的电话号码,要通话是不可能的。
      -----
      Socket 接口是访问 Internet 使用得最广泛的方法。 如果你有一台刚配好TCP/IP协议的主机,其IP地址是202.120.127.201, 此时在另一台主机或同一台主机上执行ftp 202.120.127.201,显然无法建立连接。因"202.120.127.201" 这台主机没有运行FTP服务软件。同样, 在另一台或同一台主机上运行浏览软件 如Netscape,输入"http://202.120.127.201",也无法建立连接。现在,如果在这台主机上运行一个FTP服务软件(该软件将 打开一个Socket, 并将其绑定到21端口),再在这台主机上运行一个Web 服务软件(该软件将打开另一个Socket,并将其绑定到80端口)。这样,在另一台主机或同一台主机上执行ftp 202.120.127.201,FTP客户软件将通过21端口来呼叫主机上由FTP 服务软件提供的Socket,与其建立连接并对话。而在netscape中输入"http://202.120.127.201"时,将通过80端口来呼 叫主机上由Web服务软件提供的Socket,与其建 立连接并对话。


      在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务。 每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,象一个多孔插座。一台主机犹如布满 各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。


      -----
      1.什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket 是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等 的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类 及其子类完成的。


      重要的Socket API:java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。


      Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。


      getInputStream方法获得网络连接输入,同时返回一个IutputStream对象实例。


      getOutputStream方法连接的另一端将得到输入,同时返回一个 OutputStream对象实例。 注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对 象,通常都会被另一个流对象使用。


      2.如何开发一个Server-Client模型的程序 开发原理:


      服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。


      客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。


      Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员 可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。 Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的 Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返 回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。


      常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式 Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的 Socket,对应于无连接的UDP服务应用。 Socket建立为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符的句柄。socket函数原型为:int socket(int domain, int type, int protocol);domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族);type参数指定socket的 类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值"0"。 Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。 Socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用Socket函数时,socket执行体将建立一个Socket,实际上"建 立一个Socket"意味着为一个Socket数据结构分配存储空间。 Socket执行体为你管理描述符表。两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端 口。Socket数据结构中包含这五种信息。 socket在测量软件中的使用也很广泛

    二 socket函数

      The socket function creates a socket that is bound to a specific service provider.
      SOCKET socket(
      int af,
      int type,
      int protocol
      );
      Parameters
      afAddress family specification.
      type
      Type specification for the new socket.
      The following are the only two type specifications supported for Windows Sockets 1.1: Type Explanation
      SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses TCP for the Internet address family.
      SOCK_DGRAM Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses UDP for the Internet address family.
      In Windows Sockets 2, many new socket types will be introduced and no longer need to be specified, since an application can dynamically discover the attributes of each available transport protocol through the WSAEnumProtocols function. Socket type definitions appear in Winsock2.h, which will be periodically updated as new socket types, address families, and protocols are defined.
      protocol
      Protocol to be used with the socket that is specific to the indicated address family.
      Return Values
      If no error occurs, socket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.
      Error code Meaning
      WSANOTINITIALISED A successful WSAStartup call must occur before using this function.
      WSAENETDOWN The network subsystem or the associated service provider has failed.
      WSAEAFNOSUPPORT The specified address family is not supported.
      WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
      WSAEMFILE No more socket descriptors are available.
      WSAENOBUFS No buffer space is available. The socket cannot be created.
      WSAEPROTONOSUPPORT The specified protocol is not supported.
      WSAEPROTOTYPE The specified protocol is the wrong type for this socket.
      WSAESOCKTNOSUPPORT The specified socket type is not supported in this address family.
      Remarks
      The socket function causes a socket descriptor and any related resources to be allocated and bound to a specific transport-service provider. Windows Sockets will utilize the first available service provider that supports the requested combination of address family, socket type and protocol parameters. The socket that is created will have the overlapped attribute as a default. For Microsoft operating systems, the Microsoft-specific socket option, SO_OPENTYPE, defined in Mswsock.h can affect this default. See Microsoft-specific documentation for a detailed description of SO_OPENTYPE.
      Sockets without the overlapped attribute can be created by using WSASocket. All functions that allow overlapped operation (WSASend, WSARecv,WSASendTo, WSARecvFrom, and WSAIoctl) also support nonoverlapped usage on an overlapped socket if the values for parameters related to overlapped operation are NULL.
      When selecting a protocol and its supporting service provider this procedure will only choose a base protocol or a protocol chain, not a protocol layer by itself. Unchained protocol layers are not considered to have partial matches on type or af either. That is, they do not lead to an error code of WSAEAFNOSUPPORT or WSAEPROTONOSUPPORT if no suitable protocol is found.
      Important The manifest constant AF_UNSPEC continues to be defined in the header file but its use is strongly discouraged, as this can cause ambiguity in interpreting the value of the protocol parameter.
      Connection-oriented sockets such as SOCK_STREAM provide full-duplex connections, and must be in a connected state before any data can be sent or received on it. A connection to another socket is created with a connect call. Once connected, data can be transferred using send and recv calls. When a session has been completed, a closesocket must be performed.
      The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.
      Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using sendto and recvfrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer using send and can be received only from this peer using recv.
      Support for sockets with type SOCK_RAW is not required, but service providers are encouraged to support raw sockets as practicable.
      Notes for IrDA Sockets
      The Af_irda.h header file must be explicitly included.
      Only SOCK_STREAM is supported; the SOCK_DGRAM type is not supported by IrDA.
      The protocol parameter is always set to 0 for IrDA.
      Note On Windows NT, raw socket support requires administrative privileges.
      Requirements
      Windows NT/2000/XP: Included in Windows NT 3.1 and later.
      Windows 95/98/Me: Included in Windows 95 and later.
      Header: Declared in Winsock2.h.
      Library: Use Ws2_32.lib.
      See Also
      Windows Sockets Programming Considerations Overview, Socket Functions, accept, bind, connect, getsockname, getsockopt, ioctlsocket, listen, recv, recvfrom, select, send, sendto, setsockopt, shutdown, WSASocket

     

     

    转自:http://baike.baidu.com/view/13870.htm


    展开全文
  • 最近呢,由于实习需要呢,复习遍爬虫,前断时间闭关刷题去了,也会把刷题心得总结成博客分享给大家,比如java...基于socket通信编写爬虫:最底层的方式,同时也是执行最高效的,不过开发效率最低。2.基于HttpURLCo...

    最近呢,由于实习需要呢,复习一遍爬虫,前断时间闭关刷题去了,也会把刷题心得总结成博客分享给大家,比如java集合类特性及源码解析,操作系统数据结构的一些算法,设计模式等,放心,肯定不会鸽的,虽然可能会晚一点写。

    言归正传,java实现网络爬虫一般有五种方法(据我所知,要是有其他方法的同学欢迎分享)

    1.基于socket通信编写爬虫:最底层的方式,同时也是执行最高效的,不过开发效率最低。

    2.基于HttpURLConnection类编写爬虫:java se的net包的核心类,主要用于http的相关操作。

    3.基于apache的HttpClient包编写爬虫:由net包拓展而来,专为java网络通信编程而服务。

    4.基于phantomjs之类的无头(无界面)浏览器:

        (1)它是浏览器的核心,并非浏览器。换言之,它是没有UI的浏览器。

        (2)它提供的js api,故它可以方便直接的被各种程序语言调用。换言之,似乎是js写的。

    5.基于Selenium或者是WebDriver之类的有头(有界面)浏览器

        (1)它是浏览器核心,并非浏览器。换言之,它是没有界面UI的浏览器。无头,即无界面。

        (2)它提供的js api,故它可以方便直接的被各种程序语言调用。

    其实第五个呢,我也不是很熟悉,到时候写第五篇的时候呢,会一边学一边写,可能会有比较幼稚的错误,欢迎大家指点哈。

    这部分呢。借鉴了周光亮老师的视频上的部分讲解。

    首先,这篇介绍的是socket编程编写爬虫,当然,一般在程序开发的时候我们一般不会用这种方式,毕竟httpclient几行代码的事情,但是基于这种方式使其他的方式更易于理解,了解一下还是比较必要的。

        socket并不是什么通信协义,只是为了方便tcp/ip层的上层访问tcp/ip层而做一层封装。即应用层以下负责ip地址间的传输,而应用层应用socket实现端对端的传输,即精确到    IP:端口。

    首先呢,因为之后要写出很多的类,所以提前规划一下包结构是比较好的,如下:


    com.lzx.simple.control这个包是用来给用户控制行为的包

    com.lzx.simple.enumeration 这个包集合了一些枚举类型,如TaskLevel用来控制优先级。

    package com.lzx.simple.enumeration;
    
    /**
     * 抓取任务的优先级等级
     * @author Administrator
     *
     */
    public enum TaskLevel {
    	HIGH,MIDDLES,LOW
    }
    

    com.lzx.simple.iface.crawl这个包集合了一些接口,毕竟我们需要面向接口来编程,什么是面向接口编程?去拿本设计模式的书出去罚站

    package com.lzx.simple.iface.crawl;
    
    import com.lzx.simple.pojos.CrawlResultPojo;
    import com.lzx.simple.pojos.UrlPojo;
    
    public interface ICrawler {
    	public CrawlResultPojo crawl(UrlPojo urlPojo);
    }
    

    com.lzx.simple.imple.crawl这个包集合了一些接口的实现类,比如这次的SocktCrawlerImpl类实现了ICrawler接口,这个类的代码不放了,待会儿单独解释。

    com.lzx.simple.manager这个包集合了一些管理方法

    com.lzx.simple.pojos这个包集合了一些简单对象,例如UrlPojo类

    package com.lzx.simple.pojos;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import com.lzx.simple.enumeration.TaskLevel;
    
    /**
     * 简单的Java对象(Plain Ordinary Java Objects)
     * @author Administrator
     *
     */
    public class UrlPojo {
    	private String url;
    	private TaskLevel taskLevel;
    	
    	public String getHost(){
    		try {
    			URL url = new URL(this.url);
    			return url.getHost();
    		} catch (MalformedURLException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
    		return null;
    	}
    	
    	
    	public UrlPojo(String url) {
    		this.url = url;
    	}
    	public UrlPojo(String url, TaskLevel taskLevel) {
    		this.url = url;
    		this.taskLevel = taskLevel;
    	}
    	public String getUrl() {
    		return url;
    	}
    	public void setUrl(String url) {
    		this.url = url;
    	}
    	public TaskLevel getTaskLevel() {
    		return taskLevel;
    	}
    	public void setTaskLevel(TaskLevel taskLevel) {
    		this.taskLevel = taskLevel;
    	}
    	
    }
    

    我们可以看到UrlPojo中有url属性(网址)和taskLevel(优先级),除了getset还有gethost函数,这个类封装 了一个需抓取的网页,还有另一个类如下:

    package com.lzx.simple.pojos;
    
    public class CrawlResultPojo {
    	private boolean isSuccess;
    	private String pageContent;
    	private int httpStatuCode;
    	public boolean isSuccess() {
    		return isSuccess;
    	}
    	public void setSuccess(boolean isSuccess) {
    		this.isSuccess = isSuccess;
    	}
    	public String getPageContent() {
    		return pageContent;
    	}
    	public void setPageContent(String pageContent) {
    		this.pageContent = pageContent;
    	}
    	public int getHttpStatuCode() {
    		return httpStatuCode;
    	}
    	public void setHttpStatuCode(int httpStatuCode) {
    		this.httpStatuCode = httpStatuCode;
    	}
    }
    
    我们用CrawlResultPojo这个类来表示抓取结果,三个属性都很显而易见,抓取是否成功,网页内容,状态码。还有相应getset。

    有些package还没有文件,之后用到会添加并说明。

    然后开始我们的socket通信的类:

    package com.lzx.simple.imple.crawl;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import javax.swing.text.AbstractDocument.BranchElement;
    
    import com.lzx.simple.iface.crawl.ICrawler;
    import com.lzx.simple.pojos.CrawlResultPojo;
    import com.lzx.simple.pojos.UrlPojo;
    
    public class SocketCrawlerImpl implements ICrawler{
    
    	public CrawlResultPojo crawl(UrlPojo urlPojo) {
    		CrawlResultPojo crawlResultPojo=new CrawlResultPojo();
    		if (urlPojo==null||urlPojo.getUrl()==null ){
    			crawlResultPojo.setSuccess(false);
    			crawlResultPojo.setPageContent(null);
    			
    			return crawlResultPojo;
    		}
    		String host=urlPojo.getHost();
    		if (host==null) {
    			crawlResultPojo.setSuccess(false);
    			crawlResultPojo.setPageContent(null);
    			
    			return crawlResultPojo;
    		}
    		BufferedWriter bufferedWriter=null;
    		BufferedReader bufferedReader=null;
    		try {
    			Socket socket=new Socket(host, 80);
    			//socket.setKeepAlive(false);
    			bufferedWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    			bufferedWriter.write("GET "+urlPojo.getUrl()+" HTTP/1.1\r\n");
    			bufferedWriter.write("HOST:"+host+"\r\n");
    			bufferedWriter.write("Connection:close"+"\r\n");
    			bufferedWriter.write("\r\n");//提示http header结束
    			bufferedWriter.flush();//flush()表示强制将缓冲区中的数据发送出去,不必等到缓冲区满.
    			
    			bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
    			String line;
    			StringBuilder stringBuilder=new StringBuilder();
    			while((line=bufferedReader.readLine())!=null){
    				stringBuilder.append(line+"\n");
    			}
    			crawlResultPojo.setSuccess(true);
    			crawlResultPojo.setPageContent(stringBuilder.toString());
    			
    			return crawlResultPojo;
    		} catch (UnknownHostException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}finally {
    			try {
    				if (bufferedReader!=null) {
    					bufferedReader.close();					
    				}
    				if (bufferedWriter!=null) {
    					bufferedWriter.close();									
    				}
    			} catch (Exception e2) {
    				// TODO: handle exception
    				e2.printStackTrace();
    			}
    		}
    		return null;
    	}
    	public static void main(String[] args) {
    		SocketCrawlerImpl socketCrawlerImpl=new SocketCrawlerImpl();
    		UrlPojo urlPojo=new UrlPojo("http://www.baidu.com");
    		CrawlResultPojo crawlResultPojo=socketCrawlerImpl.crawl(urlPojo);
    		System.out.println(crawlResultPojo.getPageContent());
    	}
    
    }
    

    这个是整个类的源码

    主要的抓取工作就在crawl这个函数中,因为我们要返回CrawlResultPojo对象,所以一开始new了一个CrawlResultPojo;

    然后判断待抓取的网页对象urlPojo是不是空,以及它的属性url是不是空。如果是就构造个返回失败的CrawlResultPojo返回回去。

    然后gethost获得待抓取对象的主机名,用于待会儿构造http header。当然也要判断一下首部是否为空了。

    然后构造缓冲输入流和输出流bufferedWriter和bufferedReader;

    然后构造Socket,构造函数的参数这里是主机名+端口,端口默认是80,如果有特殊需要再改动;当然构造函数的参数也可以是IP地址+端口,端对端通信的本质。

    然后在bufferedWriter构造http首部以便发送。

    这里就有一个比较有趣事情了,周光亮老师在视频的讲解中发现了一个bug,他发现使用http/1.1的协议会导致抓取有一段真空期,即程序输出完这个页面的字符串后,会停顿一段时间然后再结束程序,而改用http/1.0的协议就不会,抓取完直接结束程序,周老师当时调试了很久都没有解决。

    其实主要原因呢,是他在构造http首部的时候没有加

    bufferedWriter.write("Connection:close"+"\r\n");

    这段代码,为什么加了这段代码后就可以去除真空期呢?

    因为,

    http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive",才能启用Keep-Alive;

    http 1.1中默认启用Keep-Alive,如果加入"Connection: close ",才关闭。

    嗯,1.1版本更持久一点- -,


    构造完就调用flush扔出去了

    然后输入流就不多说了,基本套路。

    这样就实现了socket抓取网页= =。


    展开全文
  • socket通信基础知识点记录

    千次阅读 2016-09-11 15:34:31
    网络通信一种进程间通信(IPC, Inter-Process Communication),要求位于不同网络节点不同进程的通信双方必须遵循统一的通信协议方可实现。基于套接字(Socket)通信是应用在不同节点上的进程间通信的典型办法。1、...
  • 在编程中,Socket被称做 套接字,是网络通信中的一种约定。 Socket编程用于解决我们 客户端与 服务端之间通信的问题。 java中的serversocket类:用于创建Socket套接字的服务端,而Socket类的作用是创建Socket的...
  • Socket通信

    万次阅读 2016-03-24 20:26:11
    下面4层(物理层、数据链路层、网络层传输层)主要提供数据传输交换功能, 即以节点到节点之间的通信为主 第4层作为上下两部分的桥梁,是整个网络体系结构中最关键的部分; 上3层(会话层、表示层
  • TCP是Transfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上...
  • Android开发之Socket通信

    千次阅读 2012-05-18 13:55:46
    All Rights Reserved ! 序---最近一直相当忙,方面是项目,方面是工作,另方面还有书要看,总之很多要写的题目,暂时只编了个大纲... 简介:在从业过程中,所用到的有关Socket通信的有这么几个地方:1、Q...
  • socket通信 socket翻译成中文就是“套接字”的意思,所谓的socket编程就是指用计算机语言通过编程来实现计算机之间的通信问题。socket通信技术就是两台联网或者多态联网的计算机之间的数据交互技术。 二、...
  • 网络通信一种进程间通信(IPC,Inter-ProcessCommunication),要求位于不同网络节点不同进程的通信双方必须遵循统一的通信协议方可实现。基于套接字(Socket)通信是应用在不同节点上的进程间通信的典型办法。1、基本...
  • TCP TCP/IP HTTP Socket URL 等一些概念

    千次阅读 2019-01-10 11:04:07
    它的网络层只支持一种面向无连接的服务, 但传输层同时支持TCP(面向连接)UDP(面向无连接)两种通信模式。 面向连接无连接的概念: 面向连接:  ->服务:是指用户首先必须先建立一个连接,然后用这...
  • Java中的网络支持针对网络通信的不同层次,Java提供了不同的API,其提供的网络功能有四大类:①InetAddress:用于标识网络上的硬件资源,主要是IP地址②URL:统一资源定位符,通过URL可以直接...
  • Socket 编程原理

    2021-03-30 15:27:51
    socket编程即计算机网络编程,目的是使两台主机能够进行远程连接,既然要使两者产生联系,那么就要有至少个信息发送端和一个信息接收端,因此形成了现在绝大多数 socket 编程都会用到的 C/S 架构(Client[客户端]/...
  • 面向连接与非面向连接的通信方式有什么区别? 接下来以此篇文章来学习: 理解计算机网络编程的概念,掌握如何使用Java在台或多台计算机之间进行基于TCP/IP协议的网络通讯。通过理解TCP/IP协议的通讯模型,以JDK...
  • socket套接字是什么

    千次阅读 2019-04-20 10:57:00
    socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。...
  • 不可不知 Linux操作系统网络服务器模型Linux系统网络服务器模型主要有两:并发服务器循环服务器。所谓并发服务器就是在同个时刻可以处理来自多个客户端的请求;循环服务器是指服务器在同一时刻指可以响应个...
  • socket通信中select函数的使用详解

    千次阅读 2015-04-02 16:09:09
    最近在写个网络通信函数,参考别人的代码时对select()函数的使用存有疑惑,不太确定具体的使用方法,何时使用,以及其作用。在网上搜到篇文章,觉得介绍的不错,收藏学习。 先自我总结一下。  select...
  • Java Socket应用---通信是这样练成的

    千次阅读 2016-06-28 14:36:00
    、网络基础知识 两台计算机要通过网络进行通信必备条件a、唯一的标识IP地址 b、需要共同的语言–协议 c、辨别不同的应用程序–端口号。 1.IP地址 每台计算机的唯一标识,用来区分网络中的不同主机,是两台主机...
  • 在上篇博客中,我们通过unity中的www类来web服务器进行数据的交互,所使用的方式就是http通信,那么http通信的原理是什么呢,socket通信原理又是什么呢,这里推荐两篇写的比较不错的博文:这里,还有这里。...
  • 关于TCP/IPHTTP协议的关系,网络有段比较容易理解的介绍:“我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到...
  • Java利用Socket进行数据读写

    千次阅读 2020-02-06 18:48:54
    Java中和网络有关的类分为四:InetAddress(网络信息标识)、URL(统一资源定位器,读写网络数据)、Sockets(利用TCP/IP实现网络通信)、Datagram(UDP数据报通信) 通过InetAddress可以获取计算机名、IP地址等...
  • 在客户机/服务器工作模式中,在Server端,要准备接受多...端口号与IP地址的组合称为网络套接字(socket)。 Java语言在实现C/S模式中,套接字分为两类: 在Server端,ServerSocket类支持底层的网络通信; 在Clie
  • C#网络编程(Socket编程)

    万次阅读 多人点赞 2020-04-02 09:45:27
    它是计算机之间进行通信一种约定或一种方式。通过Socket这种约定可以接收到其他计算机的数据,也可以向其他计算机发送数据。 2.本质 是编程接口(API),对于TCP/IP的封装,TCP/IP也提供了可供程序员做网络开发...
  • 、网络编程概述 二、网络编程三要素之IP概述 三、网络编程三要素之端口号概述 四、网络编程三要素之协议概述 五、Socket通信原理图解
  • http、TCP/IP协议与socket之间的区别   网络由下往上分为:  物理层–           &...
  • 本节引言:为了照顾没学过Java Socket的初学者,或者说捋捋Android开发中涉及到的网络协议相关的概念,毕竟面试的时候,面试官来了句给我说下网络协议有几层?那么IP协议在哪层?Socket是什么鬼?分哪几?TCP...
  • https 与 http、TCP/IP、Socket网络通信

    千次阅读 2017-03-03 22:52:54
    如若感觉排版看着不舒服,请移步https 与 http、TCP/IP、Socket网络通信 、https 与 http HTTPS HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是...
  • python socket

    2020-12-22 12:16:13
    套接字(socket)是个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写关闭等操作。 套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。 网络套接字是IP...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,933
精华内容 7,973
关键字:

url和socket通信是一种面向