1 网络通信协议
- HTTP,smtp,ftp是应用层协议,主要解决如何包装数据
- TPC/IP协议是传输层协议,主要解决数据如何在网络中传输
1.1 TCP/IP和HTTP协议的关系
WEB使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发到网络上
1.2 socket和TCP/IP协议关系
TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口,这就是Socket编程接口
2 java URL处理
URL(Uniform Resource Locator)中文名为统一资源定位符,有时也被俗称为网页地址。表示为互联网上的资源,如网页或者FTP地址。
2.1 URL组成可以分为如下几部分:protocol://host:port/path?query#fragment
scheme:通信协议,常用的http,ftp,maito等。
host:主机,服务器(计算机)域名系统 (DNS) 主机名或 IP 地址。
port:端口号,整数,可选,省略时使用方案的默认端口,如http的默认端口为80。
path:路径,由零或多个"/"符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。
query:查询,可选,用于给动态网页传递参数,可有多个参数,用"&"符号隔开,每个参数的名和值用"="符号隔开。
fragment:信息片断,字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用fragment直接定位到某一名词解释。(也称为锚点)
1.2 URL相关类
- java.net包的URL类提供了丰富的URL构建方式,并可以通过java.net.URL来获取资源。
- URL的openConnection()返回一个java.net.URLConnection对象:
-
如果你连接HTTP协议的URL, openConnection() 方法返回 HttpURLConnection 对象。
-
如果你连接的URL为一个 JAR 文件, openConnection() 方法将返回 JarURLConnection 对象。
-
2 socket编程
2.1 socket通信过程
socket(套接字)使用TCP提供了两台计算机之间的通信机制,客户端程序创建一个套接字,并尝试连接服务器的套接字;当连接建立时,服务器会创建一个socket对象,客户端与服务端之间通过对socket对象的写入和读取数据进行通信。两台计算机之间用套接字建立通信的步骤:
- 服务器实例化一个ServerSocket对象,表示通过服务器上的端口通信
- 服务器调用ServerSocket类的accept()方法,该方法将一直等待,直到客户端连接到服务器上给定的端口
- 服务器正在等待时,一个客户端实例化一个socket对象,指定服务器名称和端口号来请求连接
- Socket类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个socket对象能够与服务器进行通信
- 在服务器端,accept()方法返回服务器上一个新的socket引用,该socket连接到客户端的socket
连接建立后,通过使用I/O流在进行通信。每一个socket都有一个输出流和一个输入流。客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。
2.2 与socket通信相关类(均在java.net包中)
- ServerSocket类:服务器应用程序通过其获取一个端口,并且监听客户端请求
- Socket类:java.net.Socket类代表客户端和服务器端相互通信的套接字,客户端要获取一个sockket对象通过实例化,而服务器获得一个socket对象则通过accept()方法的返回值
- InetAdress类:表示互联网协议(IP)地址
2.3 示例
服务端代码:
import java.awt.*; import java.io.*; import java.net.*; import javax.swing.*; public class ServerFrame extends JFrame{ JTextArea txtDisplay = new JTextArea(); JButton btnStart = new JButton("开始"); public ServerFrame(){ setLayout(new BorderLayout()); txtDisplay.setEditable(false); getContentPane().add(btnStart, BorderLayout.NORTH); getContentPane().add(new JScrollPane(txtDisplay), BorderLayout.CENTER); btnStart.addActionListener((e)->{ try { Thread t = new GreetingServer(8888); t.start(); }catch(IOException ioe) { ioe.printStackTrace(); } }); setSize(400,300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } class GreetingServer extends Thread{ private ServerSocket socketServer; public GreetingServer(int port) throws IOException{ socketServer = new ServerSocket(port); socketServer.setSoTimeout(10000); } public void run(){ while(true){ try{ txtDisplay.append("Waiting for client on port " + socketServer.getLocalPort() + "..." + " "); Socket socket = socketServer.accept(); txtDisplay.append("Just connected to " + socket.getRemoteSocketAddress() + " "); DataInputStream in = new DataInputStream(socket.getInputStream()); txtDisplay.append(in.readUTF() + " "); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); out.writeUTF("Thank you for connecting to " + socket.getLocalSocketAddress() + " Googbye"); socket.close(); }catch(SocketTimeoutException e){ txtDisplay.append("Socket timed out!" + " "); break; }catch(IOException e){ e.printStackTrace(); break; } } } } public static void main(String[] args) { // TODO Auto-generated method stub new ServerFrame(); } }
客户端代码:
import java.io.*; import java.net.*; public class GreetingClient { public static void main(String[] args) { // TODO Auto-generated method stub String serverName = "127.0.0.1";//args[0]; int port = 8888; //Integer.parseInt(args[0]); try{ System.out.println("Connecting to " + serverName + " on port " + port); Socket client = new Socket(serverName, port); System.out.println("Just connected to " + client.getRemoteSocketAddress()); OutputStream outToServer = client.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); out.writeUTF("Hello from " + client.getLocalSocketAddress()); InputStream inFromServer = client.getInputStream(); DataInputStream in = new DataInputStream(inFromServer); System.out.println("Server says " + in.readUTF()); client.close(); }catch(IOException e){ e.printStackTrace(); } } }
3 使用第三方类库
- 如Apache的httpclient :http://hc.apache.org/
- 在Eclipse中引入库:项目右击—Build Path—Add External Archives…
import org.apache.http.client.fluent.*; import java.awt.image.BufferedImage; import java.io.File; import java.net.URL; import javax.imageio.ImageIO; public class HttpClientStock { public static void main(String... args) throws Exception { String stockCode = "sh600190"; //sh600509 String str = Request.Get("http://hq.sinajs.cn/list="+stockCode) .execute().returnContent().asString(); System.out.println(str); String chartType = "min"; //daily, weekly, monthly String imageURL = "http://image.sinajs.cn/newchart/" + chartType + "/n/" + stockCode + ".gif"; //BufferedImage img = ImageIO.read(Request.Get(imageURL) // .execute().returnContent().asStream()); BufferedImage img = ImageIO.read(new URL(imageURL)); ImageIO.write(img, "gif", new File("d:\aaa.gif")); } }
4 应用示例----网络取词
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import javax.swing.*; import org.apache.http.client.*; import org.apache.http.client.fluent.*; public class HttpSuggestion extends JFrame{ private JTextField txtInput = new JTextField(); private JList<String> lstSuggestion = new JList<>(); public HttpSuggestion(){ setLayout(new BorderLayout()); getContentPane().add(txtInput, BorderLayout.NORTH); getContentPane().add(new JScrollPane(lstSuggestion), BorderLayout.CENTER); txtInput.addKeyListener(new KeyAdapter(){ public void keyPressed(KeyEvent arg0){ new Thread(()->{ try{ String txt = txtInput.getText(); String[] suggerstion = getSuggestionList(txt); SwingUtilities.invokeLater(()->{ lstSuggestion.removeAll(); lstSuggestion.setListData(suggerstion); lstSuggestion.updateUI(); }); }catch(Exception ex){ ex.printStackTrace(); } }).start(); } }); setSize(300,250); setTitle("网络取词"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } String[] getSuggestionList(String word) throws UnsupportedEncodingException, ClientProtocolException, IOException { if (word == null || word.length() == 0) return new String[0]; String url = "http://suggestion.baidu.com/su?wd=" + URLEncoder.encode(word, "utf-8"); url += "&rnd=" + Math.random(); String content = Request.Get(url) .addHeader("cookie", "BDUSS=Aadasdfsfee").execute() .returnContent().asString(); System.out.println(content); // q:"s",p:false,s:["s5总决赛","s5","三国杀","顺丰","s5总决赛小组赛","顺丰快递单号查询","搜狗输入法下载","苏宁易购","搜狐视频","蜀山战纪"]}); String temp = content.replaceAll(".*,s:\[([^\]]*)\].*", "$1"); String[] sug = content.replaceAll(".*,s:\[([^\]]*)\].*", "$1") .replaceAll(""", "").split(","); return sug; } public static void main(String[] args) { // TODO Auto-generated method stub SwingUtilities.invokeLater( ()->{ new HttpSuggestion();}); } }