概述
网络编程其实是为了实现不同主机上的数据通信,而要实现通讯则需要首先知道对方的IP和端口号,同时明确双方使用的通信规则,或传输协议。
Ip地址、端口号和传输协议,即是网络通讯的三要素
IP地址:主机在网络的地址,或者在网上的唯一标识。
127.0.0.1,本地回环地址,用它可以测试网卡是否损坏;还有些IP地址保留了,不用于广域网,只用于局域网,例如:192.168.0.1~255,192.168.1.1~255等。
端口号:数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识,为了方便称呼这个数字,就这个数组叫为“端口”,或“逻辑端口”,它并没有物理实体与之对应。有效端口好从0~65535,其中0~1024是系统保留的。一些常用程序的默认端口:浏览器80端口,TomCat服务器8080端口,MySQL的3306端口。
通信规则:即传输协议,国际组织定义的通用协议是TCP/IP。TCP/IP既能用于局域网,也能用于广域网。除了TCP/IP,还有其他的协议,例如UDP、FTP、HTTP等。
网络模型
主要由两个OSI和TCP/IP模型,其分层情况如下:

TCP和UDP在传输层。IP协议在网络层。FTP协议、HTTP协议在应用层。
数据封包:数据从应用层开始,每经过一层都加入该层的标识信息,直到物理层,这个过程就叫数据封包。之后变成二进制01数据从物理设备上传输。
数据拆包:与封包过程正好相反,指去掉每层的标识信息,获取数据的过程。
网络编程:现阶段主要是在网际层和传输层。而javaWeb开发主要是在应用层。
Java中,对各个层都创建了有对象与之对应,以方便我们的开发使用。下边主要学习传输层的一些对象,比如InetAddress、Socket、DatagramSocket。
IP地址
IP地址是数字,使用时不容易记忆,所以有与这个地址名想对应的主机名。主机名与IP地址相对应。
体系结构:
|----InetAddress
|----Inet4Address,
|----Inet6Address
InetAddress中没有提供构造函数,但它提供了多种静态方法,以获取本类对象。
Socket地址
装的是带端口号的IP地址
|——SocketAddress
|———InetSocketAddress
程序示例:
- import java.net.*;
- class IPDemo
- {
- public static void main(String[] args) throws Exception
- {
-
-
-
-
-
-
-
-
-
-
-
-
- InetAddress i= InetAddress.getByName("www.sina.com");
-
- System.out.println(i.toString());
- String adr = i.getHostAddress();
- String name = i.getHostName();
- sop("adr="+adr+" name="+name);
-
-
- }
- public static void sop(Object obj)
- {
- System.out.println(obj);
- }
- }
TCP和UDP
TCP和UDP都是在网络传输层
TCP和UDP的区别【重要】
UDP:是面向无连接的,它将数据集源和目的封装成数据包中,不需要建立连接;它的每个数据报(Datagram)的大小限制在64k以内;因为无连接,是不可靠的协议;同样因为不需要建立里连接,所以速度快。
应用特点:只求速度快,数据丢失对程序影响不大。
应用程序实例:聊天室工具、视频、网络会议等。
TCP:需要建立连接,形成传输数据的通道;在连接中进行大量数据传输;通过三次握手协议完成连接,是可靠的协议;因为必须建立连接,所以效率会稍低。(TCP不像UDP需要封包,而且每个包不能超过64k,它可以大量的传输数据)。
应用特点:适合对数据完整性要求高的程序。
应用程序实例:下载程序。
Socket
网络编程其实就Socket编程,Socket是为网络服务的一种机制。(Socket,中文意思为插座)
每个应用程序都有一个socket信端点,可以把Socket想象为每个应用程序上的码头。
通信的两端都有Socket,网络通信其实就是Socket间的通信,数据在两个Socket间通过IO传输。
UDP传输
UDP两端是发送端和接受端。
- DatagramSocket:UDP传输专用的程序通信端点,既能发送也能接受。
- DatagramPacket:数据报包,封装了UDP传输的数据报。里边可以设置要发送的目的地IP地址、端口及要发送的数据。
广播地址:每个网段尾数为255的IP地址,例如192.168.1.255
代码示例:
1、发送端
-
-
-
-
-
-
-
-
-
- import java.net.*;
- class UdpSend
- {
- public static void main(String[] args) throws Exception
- {
-
- DatagramSocket ds = new DatagramSocket(8888);
-
- byte[] buf = "这是通过UDP发送的数据!".getBytes();
- DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10000);
-
- ds.send(dp);
-
- ds.close();
-
- }
- }
2、接收端
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- import java.net.*;
- class UdpRece
- {
- public static void main(String[] args) throws Exception
- {
-
- DatagramSocket ds = new DatagramSocket(10000);
-
- byte [] buf = new byte[1024];
- DatagramPacket dp = new DatagramPacket(buf,buf.length);
-
- ds.receive(dp);
-
- InetAddress i= dp.getAddress();
- String ip = i.getHostAddress();
- String data = new String(dp.getData(),0,dp.getLength());
- int port = dp.getPort();
- System.out.println(ip+"::"+data+"::"+port);
-
- ds.close();
- }
- }
改进:让接收端始终处于接收状态,发送端可以发送多条数据并以“over”结束
发送端:
- package tan;
- import java.io.*;
- import java.net.*;
- public class UDPSend2 {
- public static void main(String[] args) throws Exception{
- DatagramSocket socket=new DatagramSocket();
-
- BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
-
- DatagramPacket dp=null;
- String line=null;
- while((line=br.readLine())!=null){
-
- if("over".equals(line)){
- break;
- }
- byte[]buf=("sender:"+line).getBytes();
-
- InetAddress ip=InetAddress.getByName("127.0.0.1");
-
- dp=new DatagramPacket(buf, buf.length,ip,10001);
-
- socket.send(dp);
- }
-
- socket.close();
-
-
-
- }
- }
接收端:
- package tan;
- import java.io.*;
- import java.net.*;
- public class UDPRec2 {
- public static void main(String[] args) throws Exception {
- DatagramSocket ds=new DatagramSocket(10001);
- byte []buf=new byte[64];
- DatagramPacket dp=new DatagramPacket(buf, buf.length);
-
- while(true){
- ds.receive(dp);
- String ip=dp.getAddress().getHostAddress();
- int port=dp.getPort();
- String data=new String(dp.getData(),0,dp.getLength());
- System.out.println("IP"+ip+":"+port+":"+data);
- }
- }
- }
UDP练习:聊天程序
- package tan;
- import java.io.*;
- import java.net.*;
-
- class Send implements Runnable{
- private DatagramSocket ds;
- public Send(DatagramSocket ds) {
- this.ds=ds;
- }
- @Override
- public void run() {
- try {
- ds=new DatagramSocket();
- BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
- String line=null;
- while((line=bufr.readLine())!=null){
- if("over".equals(line)){
- break;
- }
- byte []buf=line.getBytes();
- DatagramPacket dp=new DatagramPacket(buf, 0,buf.length,InetAddress.getByName("127.0.0.1"),10002);
- ds.send(dp);
-
- }
- ds.close();
- } catch (Exception e) {
- throw new RuntimeException("发送端发送失败!");
- }
-
- }
- }
-
-
- class Receive implements Runnable{
- private DatagramSocket ds;
- public Receive(DatagramSocket ds) {
- this.ds=ds;
- }
- @Override
- public void run() {
- try {
- while(true){
- byte []buf=new byte[1024];
- DatagramPacket dp=new DatagramPacket(buf, buf.length);
- ds.receive(dp);
- String ip=dp.getAddress().getHostAddress();
- String data=new String(dp.getData(),0,dp.getLength());
-
- System.out.println("ip:"+ip+" data:"+data);
-
-
- }
- } catch (Exception e) {
- throw new RuntimeException("接收端失败!");
- }
-
- }
- }
-
-
- public class chatDemo {
- public static void main(String[] args) throws Exception {
- DatagramSocket sendSocket=new DatagramSocket();
- new Thread(new Send(sendSocket)).start();
-
- DatagramSocket receSocket=new DatagramSocket(10002);
- new Thread(new Receive(receSocket)).start();
- }
- }
TCP传输
TCP的两端对应的是客户端和服务端。
Socket:TCP传输客户端通信端点。
SeverSocket:TCP传输服务端通信端点。
因为TCP需要建立连接,所有Socket客户端一建立就要指定服务端的IP和端口。而在服务端建立时,要设置监听的端口。
TCP连接成功后,在客户端和服务端就会产生网络流。
客户端Socket提供对网络流进行读写的输入流和输出流对象。
服务端操作网络流时,先获取客户端Socket对象,然后利用该Socket的字节输入输出流进行读写操作。
客户端与服务端进行多次交互时,注意阻塞式方法对程序的影响。
ServerSocket(int port, int backlog),这个构造函数中backlog用于指定客户端的最大连接数。
TCP传输中的两个问题
一、 客户端与服务端交互时同时阻塞
在示例代码3中,当客户端和服务端中都都有多个阻塞式方法时,如果使用缓冲区读取每行,没有刷新并加入换行符时,会导致客户端与服务端同时处于阻塞等待状态。
二、 定义文件结束标记
在示例代码4中,当上传文件时,客户端把本地文件变成了IO流,并写入网络输出流时,因为去掉了去掉了window加入的结束标记,使得该IO流没有结束标记,导致服务端读取流中数据时,无法结束。这就需要自定义标记。
自定义标记有三种方法:
1.定义”over”这样的字符结束标记;
2.盖时间戳。
3.使用Socket的shutdownOutput( )和shutdownInput()方法。
示例代码1------给服务器发送一个文本
建立TCP客户端
-
-
-
-
-
-
-
-
-
-
-
- package TCP;
- import java.io.*;
- import java.net.*;
- public class TCPClient {
- public static void main(String[] args) throws Exception, IOException {
-
- Socket s=new Socket("127.0.0.1", 10003);
-
- OutputStream out=s.getOutputStream();
-
- out.write("我是客户端~~".getBytes());
-
- s.close();
-
-
- }
- }
建立服务端:
-
-
-
-
-
-
-
-
-
-
-
- package TCP;
- import java.io.*;
- import java.net.*;
-
- public class TCPServer {
- public static void main(String[] args) throws Exception{
-
- ServerSocket ss=new ServerSocket(10003);
-
- Socket s=ss.accept();
-
- InputStream is=s.getInputStream();
- byte[]buf=new byte[1024];
- int len=is.read(buf);
- System.out.println(new String(buf, 0, buf.length));
-
-
- s.close();
-
- ss.close();
-
-
- }
- }
-
-
示例代码2-------完成客户端与服务端的一次交互
演示tcp的传输的的客户端和服务端的互访。
需求:客户端给服务端发送数据,服务端收到数据后,给客户端反馈信息。
建立客户端程序:
-
-
-
-
-
-
-
-
-
- package TCP;
- import java.io.*;
- import java.net.*;
- public class TCPClient2 {
- public static void main(String[] args) throws Exception {
- Socket s=new Socket("127.0.0.1", 10004);
-
- OutputStream out=s.getOutputStream();
- out.write("服务端你好!我是客户端".getBytes());
-
- InputStream in=s.getInputStream();
- byte[]buf=new byte[1024];
- int len=in.read(buf);
- System.out.println(new String(buf,0,len));
- s.close();
-
- }
- }
建立服务端程序:
- package TCP;
- import java.io.*;
- import java.net.*;
- public class TCPServer2 {
- public static void main(String[] args) throws Exception {
- ServerSocket ss=new ServerSocket(10004);
- Socket s=ss.accept();
-
- String ip=s.getInetAddress().getHostAddress();
- System.out.println(ip+"......is connected!");
-
- InputStream in=s.getInputStream();
- byte []buf=new byte[1024];
- int len=in.read(buf);
- System.out.println(new String(buf, 0, len));
-
- OutputStream out=s.getOutputStream();
- out.write("你好客户端!我是服务端,已经接收到了你发送的数据".getBytes());
-
- s.close();
- }
- }
示例代码3------键盘录入数据通过服务端转成大写形式。
需求:建立一个文本转换服务器。
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端。
而且,客户端可以不断的进行文本转换。当客户端输入over,转换就结束。
分析:
客户端:
既然是操作设备上的数据,那么就可以使用io技术,并按照IO的操作规律来思考。
源:键盘录入
目的:网络设备,也就是网络输出流,
而且操作的是文本数据,可以选择字符流。
步骤:
1,建立服务
2.获取键盘录入
3,将数据发给服务端。
4.获取服务端返回的大写数据。
5.结束,关闭资源。
都是文本数据,可以使用字符流进行操作。同时提高效率,要加入缓冲。
客户端代码:
- package TCP;
- import java.io.*;
- import java.net.*;
-
- public class TransClient {
- public static void main(String[] args) throws Exception {
-
- Socket s=new Socket("127.0.0.1", 10005);
-
- BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
-
-
-
- PrintWriter out=new PrintWriter(s.getOutputStream(),true);
-
- BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
- String line=null;
- while((line=bufr.readLine())!=null){
- if("over".equals(line)){
- break;
- }
-
-
-
-
- out.println(line);
-
- String str=bufin.readLine();
- System.out.println("server:"+str);
-
- }
-
- bufr.close();
- s.close();
-
- }
- }
服务端代码:
-
-
-
-
-
-
- package TCP;
- import java.io.*;
- import java.net.*;
- public class TransServer {
- public static void main(String[] args) throws Exception {
- ServerSocket ss=new ServerSocket(10005);
- Socket s=ss.accept();
- String ip=s.getInetAddress().getHostAddress();
- System.out.println(ip+"....已经连接!");
-
- BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
-
-
-
- PrintWriter out=new PrintWriter(s.getOutputStream(), true);
-
- String line=null;
-
-
- while((line=bufin.readLine())!=null){
-
-
-
- System.out.println(line);
- out.println(line.toUpperCase());
-
- }
-
- s.close();
- ss.close();
- }
- }
-
-
-
-
-
-
-
示例代码4------TCP上传文件(使用IO字符流)
把文件从客户端传到服务器端上。
容易出现的问题:没有客户端上传完后,文件结束标记,服务器无法停止连接Socket连接。
客户端代码:
- package TCP;
- import java.io.*;
- import java.net.*;
- public class TextClient {
- public static void main(String[] args) throws Exception {
- Socket s=new Socket("127.0.0.1", 10006);
-
-
- BufferedReader bufr=new BufferedReader(new FileReader("TCPClient.java"));
-
-
-
- PrintWriter out=new PrintWriter(s.getOutputStream(), true);
- String line=null;
- while((line=bufr.readLine())!=null){
- out.println(line);
- }
-
- s.shutdownOutput();
-
-
- BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
- String str=bufin.readLine();
- System.out.println("server:"+str);
-
-
- bufr.close();
- s.close();
-
- }
- }
服务端代码:
- package TCP;
- import java.io.*;
- import java.net.*;
- public class TextServer {
- public static void main(String[] args) throws Exception {
- ServerSocket ss=new ServerSocket(10006);
- Socket s=ss.accept();
-
- String ip=s.getInetAddress().getHostAddress();
- System.out.println(ip+".....is connected !");
-
-
- BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
-
-
- PrintWriter out=new PrintWriter(new FileWriter("server.txt"),true);
- String line=null;
- while((line=bufin.readLine())!=null){
- out.println(line);
- }
-
-
-
- PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
- pw.println("文件上传成功!");
-
-
-
- out.close();
- s.close();
- ss.close();
- }
- }
示例代码5------TCP上传图片使用IO字符流)
客户端代码:
- package TCP;
- import java.io.*;
- import java.net.*;
- public class PicClient {
- public static void main(String[] args) throws Exception{
-
- Socket s=new Socket("127.0.0.1", 10007);
-
-
- FileInputStream fis=new FileInputStream("1.jpg");
-
- OutputStream out=s.getOutputStream();
- byte []buf=new byte[1024];
- int len=0;
- while((len=fis.read(buf))!=-1){
- out.write(buf, 0, len);
- }
- s.shutdownOutput();
-
-
-
- InputStream in=s.getInputStream();
- byte[]bufin=new byte[1024];
- int inLen=in.read(buf);
- System.out.println("From Server:"+new String(buf, 0, inLen));
-
-
-
- fis.close();
- s.close();
-
- }
- }
服务端:
- package TCP;
- import java.io.*;
- import java.net.*;
- public class PicServer {
- public static void main(String[] args) throws Exception{
- ServerSocket ss=new ServerSocket(10007);
- Socket s=ss.accept();
-
- String ip=s.getInetAddress().getHostAddress();
- System.out.println(ip+"...... is connected!");
-
- InputStream in=s.getInputStream();
- FileOutputStream fos=new FileOutputStream("server.jpg");
- byte[]buf=new byte[1024];
- int len=0;
- while((len=in.read())!=-1){
- fos.write(buf, 0, len);
- }
-
-
- OutputStream out=s.getOutputStream();
- out.write("图片上传成功!".getBytes());
-
-
- fos.close();
- s.close();
- ss.close();
-
-
-
-
- }
- }
TCP客户端并发访问
客户端并发访问服务器时,把服务端的处理代码封装在Runnable实现子类的run方法中,并把服务器获的的Socket对象传给该实现子类的构造函数。服务端通过while循环启动多个线程,对多个客户端请求进行并发处理。这也是一般服务器的基本原理。
示例代码6:上传图片(多客户端并发访问)
-
-
-
-
-
-
- package TCP;
- import java.io.*;
- import java.net.*;
- public class PicClient {
- public static void main(String[] args) throws Exception{
-
-
- if(args.length!=1){
- System.out.println("请选择一个jpg格式的图片");
- return;
- }
-
- File file=new File(args[0]);
- if(!(file.exists()&& file.isFile())){
- System.out.println("该文件有问题,不存在或者不是文件");
- return;
- }
-
- if(!file.getName().endsWith(".jpg")){
- System.out.println("图片格式错误");
- return;
- }
-
- if(file.length()>1024*1024*5){
- System.out.println("图片过大,应在5M以内");
- return ;
- }
-
-
-
-
-
- Socket s=new Socket("127.0.0.1", 10007);
-
-
- FileInputStream fis=new FileInputStream("1.jpg");
-
- OutputStream out=s.getOutputStream();
- byte []buf=new byte[1024];
- int len=0;
-
- while((len=fis.read(buf))!=-1){
- out.write(buf, 0, len);
- }
- s.shutdownOutput();
-
-
-
- InputStream in=s.getInputStream();
- byte[]bufin=new byte[1024];
- int inLen=in.read(buf);
- System.out.println("From Server:"+new String(buf, 0, inLen));
-
-
-
- fis.close();
- s.close();
-
- }
- }
服务端代码演示:
-
-
-
-
-
-
- package TCP;
- import java.io.*;
- import java.net.*;
- public class PicServer {
- public static void main(String[] args) throws Exception{
- ServerSocket ss=new ServerSocket(10007);
-
- while(true){
- Socket s=ss.accept();
- new Thread(new PicThread(s)).start();
- }
-
- }
- }
- class PicThread implements Runnable{
- private Socket s;
-
- public PicThread(Socket s) {
- this.s=s;
- }
-
- @Override
- public void run() {
- String ip=s.getInetAddress().getHostAddress();
- int count=0;
- try {
- System.out.println(ip+"......is connnected!");
- InputStream in = s.getInputStream();
-
-
-
- File file=new File(ip+"("+(count)+")"+".jpg");
- while(file.exists()){
- file=new File(ip+"("+(count++)+")"+".jpg");
- }
-
- FileOutputStream fos=new FileOutputStream(file);
- byte[]buf=new byte[1024];
- int len=0;
-
- while((len=in.read(buf))!=-1){
- fos.write(buf, 0, len);
- }
-
-
- OutputStream out=s.getOutputStream();
- out.write("图片上传成功!".getBytes());
-
-
- fos.close();
- s.close();
-
- } catch (Exception e) {
- throw new RuntimeException(ip+"上传失败!");
- }
-
-
- }
- }
示例代码7:------客户端并发登陆
客户端通过键盘录入用户,服务端对这个用户名进行校验。如果该用户存在,在服务端显示xxx,已登陆。并在客户端显示 xxx,欢迎光临。 如果该用户不存在,在服务端显示xxx,尝试登陆。并在客户端显示 xxx,该用户不存在。 最多登录三次。
登陆成功、登录三次都直接断开Socket
客户端代码:
- package tan;
- import java.io.*;
- import java.net.*;
- class LoginClient {
- public static void main(String[] args) throws Exception {
- Socket s = new Socket("127.0.0.1", 10008);
-
- BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
-
- PrintWriter out = new PrintWriter(s.getOutputStream(), true);
-
- BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
-
- for (int x = 0; x < 3; x++) {
-
- String line = bufr.readLine();
-
- if (line == null)
- break;
-
- out.println(line);
-
- String info = bufIn.readLine();
- System.out.println("info:" + info);
- if (info.contains("欢迎")){
- break;
- }
- }
-
- bufr.close();
- s.close();
- }
- }
服务端代码:
- package tan;
- import java.io.*;
- import java.net.*;
- public class LoginServer {
- public static void main(String[] args) throws Exception {
- ServerSocket ss=new ServerSocket(10008);
- while(true){
- Socket s=ss.accept();
- new Thread(new UserThread(s)).start();
- }
- }
- }
-
-
-
- class UserThread implements Runnable {
- private Socket s;
- UserThread(Socket s) {
- this.s = s;
- }
- public void run() {
- String ip = s.getInetAddress().getHostAddress();
- System.out.println(ip + "....connected");
-
- try {
-
- for (int x = 0; x < 3; x++) {
-
- BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
-
- String name = bufIn.readLine();
- if (name == null){
- break;
- }
-
- BufferedReader bufr = new BufferedReader(new FileReader("user.txt"));
-
- PrintWriter out = new PrintWriter(s.getOutputStream(), true);
-
- String line = null;
- boolean flag = false;
-
- while ((line = bufr.readLine()) != null) {
-
- if (line.equals(name)) {
- flag = true;
- break;
- }
- }
-
- if (flag) {
-
- System.out.println(name + ",已登录");
-
- out.println(name + ",欢迎光临");
-
- break;
- } else {
- System.out.println(name + ",尝试登录");
- out.println(name + ",用户名不存在");
- }
- }
- s.close();
- } catch (Exception e) {
-
- throw new RuntimeException(ip + "校验失败");
- }
- }
- }
URL
URL-:代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
URI 是统一资源标识符,而 URL是统一资源定位符。因此,笼统地说,每个 URL都是 URI,但不一定每个 URI都是 URL。这是因为 URI还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。
常用方法示例:
intgetDefaultPort() :获取与此 URL关联协议的默认端口号。
String getFile() :获取此 URL的文件名。
String getHost() :获取此 URL的主机名(如果适用)。
String getPath() :获取此 URL的路径部分。
int getPort() :获取此 URL的端口号。
String getProtocol():获取此 URL的协议名称。
String getQuery() :获取此 URL的查询部分。
- import java.net.*;
- class URLDemo
- {
- public static void main(String[] args) throws Exception
- {
-
- URL url=new URL("http://192.168.1.13:11000/myweb/demo.html?name=haha&age=30");
- System.out.println("getProtocol():"+url.getProtocol());
- System.out.println("getHost():"+url.getHost());
- System.out.println("getDefaultPort():"+url.getDefaultPort());
- System.out.println("getPort():"+url.getPort());
- System.out.println("getPath():"+url.getPath());
- System.out.println("getFile():"+url.getFile());
- System.out.println("getQuery():"+url.getQuery());
-
-
-
-
-
-
- }
- }
URLConnection
它的作用于Socket类似,其实它内部封装了Socket,所以可以获取网络输入输出流。通过URL和URLConnection可以方便地对应用层网络数据进行读取和操作。
URLConnection———应用层
Socket-————传输层
方法示例:
- import java.net.*;
- import java.io.*;
-
- class URLConnectionDemo
- {
- public static void main(String[] args) throws Exception
- {
- URL url=new URL("http://192.168.1.13:8080/myweb/demo.html");
- URLConnection conn = url.openConnection();
- System.out.println(conn);
- InputStream in = conn.getInputStream();
- byte [] buf =new byte[1024];
- int len = in.read(buf);
- System.out.println(new String(buf,0,len));
-
- }
- }
改写MyIEByGUI中的showWebPage()方法。
示例:
- private void showWebPage() throws Exception
- {
-
-
- ta.setText("");
- String urlPath =tf.getText();
- URL url=new URL(urlPath);
- URLConnection conn = url.openConnection();
-
- InputStream in = conn.getInputStream();
- byte [] buf =new byte[1024];
- int len = in.read(buf);
- ta.setText(new String(buf,0,len));
- }
域名解析
用Ip地址登陆网站是,不好记忆,人们习惯用主机名。从主机名到获得该主机名对应的Ip地址的过程,就是域名解析。域名解析一般是DNS服务器完成的。
域名解析主要分为两步:
第一步:查找本地的Ip地址和主机名映射表。
这个表,在C:\Windows\System32\drivers\etc文件夹中的hosts文件。127.0.01和localhost的对应关系就在这个表中。
对hosts文件进行设置可以实现一些功能,比如:破解,将软件的官网地址域名与127.0.0.1对应;过滤垃圾网站、恶意网站。
第二步:如果第一步没有找到,那么就去你设置的DNS服务器中去查找映射表,找到对应的IP地址。获得IP地址后,再与之连接。
小结:
进入网络编程,你会发现,它把异常、多线程、IO、GUI等等知识都串联了起来,每一个小程序都是各种技术的结合体,只用把前边的学熟学透,你才能再接触新技术时很快上手。重要的还是基础。
from: http://blog.youkuaiyun.com/u010834071/article/details/38498089