第四章 网络编程(上)
4.1 URL对象
例:通过URL读取WWW信息
代码:
import java.net.*;import java.io.*; public class URLReader{ public static void main(String[] args) throws Exception{ URL cs = new URL("http://www.yushuai.me/"); BufferedReader in = new BufferedReader(new InputStreamReader(cs.openStream())); String inputLine; while((inputLine = in.readLine())!=null) System.out.println(inputLine); in.close(); }}
构造URL对象:
(1)public URL(String spec)
URL urlBase = new URL("http://www.yushuai.me");
直接把网址作为一个字符串,然后并作为参数传递给URL资源。
(2)我还可以用一个URL对象来表示它的上下文的这个环境
public URL(URL context, String spec)
URL yushuai = new URL("http://www.yushuai.me/pages/1");
URL yush = new URL(yushuai, "Gamelan.game.html");
URL gamelanNetwork = new URL(gamelan, "Gamelan.net.html");
获取URL对象属性:
public String getProtocol():返回你所描述的URL访问时采用的协议;
public String getHost():获得它的主机名;
public String getPort():获得端口号;
public String getFile():获得文件名;
public String getRef():获得引用地址。
4.2 URL Connection对象
这个对象代表了java和互联网资源上的一个访问链接,可以通过它对URL资源进行读写。它与URL的区别是,URL是单向,而本对象是双向,本对象还可以查看服务器的相响应消息的首部,它还可以设置客户端请求消息的首部。
1.使用URLConnection通信的一般步骤:
(1)构造一个URL对象;
(2)调用URL对象的openConnection()方法获得对应URL的URLConnection对象;
(3)配置此URLConnect对象;
(4)读取首部字段;
(5)获得输入流以便进行读取数据;
(6)获得输出流写入数据;
(7)关闭连接。
例:通过URLConnection抓取网页
代码:
import java.net.*;import java.io.*; public class URLReader{ public static void main(String[] args){ try { URL cs =new URL("http://www.yushuai.me/"); URLConnection tc =cs.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream())); String inputLine; while((inputLine = in.readLine())!= null) System.out.println(inputLine); in.close(); }catch(MalformedURLException e) { System.out.println("MalformedURLException"); } catch(IOException e) {System.out.println("IOException");} }}
4.3 Get请求与Post请求
例:发送get请求
代码:
public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty ("accept", "*/*"); connection.setRequestProperty ("connection", "Keep-Alive"); // 建立实际连接 connection.connect(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader (new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { } finally { try { if (in != null) { in.close(); } } catch (final Exception e2) { } return result; } }
发送POST请求,POST请求的参数需要通过URLConnection的输出流来写入参数。
例:发送POST请求
代码:
public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in =null; String result = ""; try { URL realUrl = new URL(url); //打開和URL之間的連接 URLConnection conn = realUrl.openConnection(); //设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty ("connection", "Keep-Alive"); //允许输出流 conn.setDoOutput(true); //获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); //发送请求参数 out.print(param); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while((line = in.readLine())!=null) { result +=line; } } catch(Exception e) {} finally { try { if(out!=null) { out.close(); } if(in!=null) { in.close(); } }catch(IOException ex) {} } return result;
}
HttpURLConnection类在URLConnection的基础上提供一系列针对http请求的内容:
(1)HTTP状态码(例如HTTP_OK:200);
(2)setRequestMethod(设置请求方法get/post等);
(3)getResponseCode(获取HTTP响应)。
4.4 Socket通信原理
本节讲述如何在两个java程序之间建立网络连接。
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端成为一个socket。Socket通常用来实现客户方和服务方的连接。
怎样用socket大道客户端和服务端之间的通信呢?
如图1所示,客户端有一个客户端的ClientSocket,在Server端也有一个ServerStocket。由客户端向服务器端发出一个Socket连接请求,服务器收到后会给它返回一个响应信号,在客户端就建立了连接。
图1
4.5 Socket通信实现
1.创建Socket
①Socket()
②Socket(InetAddress address, int port);
③Socket(String host, int port);
④Socket(InetAddress host, int port, InetAddress localAddr, int localPort);
⑤Socket(String host, int port, InetAddress localAddr, int localPort)
例:客户端Socket的建立
代码:
try{ Socket socket = new Socket("127.0.0.1", 2000);//2000是端口号}catch(IOException e){ System.out.println("Error:" +e);}
例:服务器端Socket的建立
代码:
ServerSocket server =null;try{ server = new ServerSocket(2000);}catch(IOException e){ System.out.println("can not listen to:" +e);}Socket socket = null;try{ socket = server.accept();//accept方法代表等着客户端发送链接请求,//如果没有客户端发请求,它就一致循环执行,直到客户端发送请求来。}catch(IOException e){ System.out.println("Error:" +e);}
2.打开输入/输出流
利用socket构建几个输入输出流。如图2所示,第一行就是通过我们一个socket对象的getoutputstream方法获得一个输出流,反过来理解就是拿到socket输入流以后外面包一层BufferedOutputStream,然后外面再包一层PrintStream,这样利用PrintStream就可以进行通讯了。只不过这是一个输出流。输出流是干什么用的呢?站在java程序来看,这个输出流就是往外发送信息的。
第二行来说,这是一个输入流。我们通过socket对象的getInputStream方法获得了输入流,然后在外面包了一层DataInputStream。
所以我们构造了这个socket输入输出流了以后,就可以用来进行通讯。第三行和第四行是另外一种方式来构造socket的输入输出流。
3.进行读写操作。
4.关闭socket
在关闭socket之前,先关闭输入输出流,使用close()方法。记住,先关闭流,再关闭socket。
例:命令行聊天程序
客户端代码:
import java.io.*;import java.net.*; public class TalkClient { public static void main(String[] args) { // TODO Auto-generated method stub try { //构造一个socket,端口号4700 Socket socket = new Socket("127.0.0.1", 4700); //构造三个输入输出流。 //第一个sin是键盘输入流。第二个os输出流, //从客户端发信息给服务端 BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); PrintWriter os = new PrintWriter(socket.getOutputStream()); //第三个是接受网络上发给我的信息 BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream())); //接受信息 String readline; readline = sin.readLine(); while(!readline.equals("bye")) { os.println(readline); os.flush(); //下面是打印客户端和服务器端发送的信息 System.out.println("Client:"+ readline); System.out.println("Server:"+ is.readLine()); readline = sin.readLine();//再获取客户键盘输入 } os.close(); is.close(); socket.close();//先关闭流再关闭socket }catch(Exception e) { System.out.println("Error"+e); } } }
服务器端代码:
import java.io.*;import java.net.*;import java.applet.Applet; public class TalkServer { public static void main(String[] args) { // TODO Auto-generated method stub try { ServerSocket server = null; //声明一个serversocket对象 try { server = new ServerSocket(4700); }catch(Exception e) { System.out.println("can not listen to:" +e); } Socket socket = null; try { socket = server.accept(); }catch(Exception e) { System.out.println("Error."+e); } //下面开始通信。第一个流是读入客户端发送的信息。 //第二个是发送信息给客户端,第三个是键盘输入流 String line; BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter os =new PrintWriter(socket.getOutputStream()); BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Client:"+is.readLine()); line =sin.readLine(); while(!line.equals("bye")) { os.println(line); os.flush(); //下面是打印客户端和服务器端发送的信息 System.out.println("Server:"+ line); System.out.println("Client:"+ is.readLine()); line = sin.readLine(); } os.close(); is.close(); server.close(); }catch(Exception e) {\ System.out.println("Error:"+e); } } }