----------- android培训、java培训、java博客、java学习型技术博客、期待与您交流! --------------
本章主要的知识点总结:1、网络通讯三要素,网络参考模型,InetAddress类的作用
2、 TCP和UDP的区别
3、Socket类,网络编程(UDP传输)的实例代码,(TCP传输)的实例代码, TCP复制文件、TCP-客户端并发登录的实例代码
4、URL类和 URLConnection 的使用, 了解SocketAddress类和 ServerSocket类
域名解析的相关知识
一.网络编程(概述)
1、网络通讯要素
(1)IP地址:
IP地址的概念类似于电话号码、身份证这样的概念,用于网络中设备的标 识, 它占四个字节, 4 个0-255 之间的数字组成 。有些地址被保留了。
本地回环地址:127.0.0.1(默认),可以用来测试网卡的好坏
主机名:localhost。后来不够用,出现IPV6。
(2)端口号
用于标识网络应用程序的逻辑地址,作为不同网络应用程序的标识,是逻辑端口,有效端 口:0~65535,其中0~1024系统保留端口。
(3)传输协议
通信的规则,国际通用组织定义了通讯规则TCP/IP。
常见的协议:TCP,UDP
2、网络参考模型
OSI参考模型,共七层,简化TCP/IP参考模型共有应用层、传输层、网际层、主机至网络层,我们学的网络编程在传输层、网际层。
3、InetAddress类(java.net包)
(1)此类表示互联网协议 (IP) 地址。
IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议, UDP 和 TCP 协议都是在它的基础上构建的 , InetAddress 的实例包含 IP 地址,还可能包含相应的主机名。
(2)常用方法
static InetAddress getByName(String host)
在给定主机名的情况下确定主机的 IP 地址。
String getHostAddress()
返回 IP 地址字符串(以文本表现形式)。
String getHostName()
获取此 IP 地址的主机名。
static InetAddress getLocalHost()
返回本地主机。
String toString()
将此 IP 地址转换为 String。
static InetAddress getLocalHost()
返回本地主机。
static InetAddress[] getAllByName(String host)
在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。
代码:
class IPDemo{
Public static void main(String[] args) throws UnknownHostException{
//通过名称(ip或者主机名)来构造一个ip对象。
InetAddress ip = InetAddress.getByName("www.sina.com");
System.out.println("addr:"+ip.getHostAddress());
System.out.println("name:"+ip.getHostName());
}
}
二.网络编程(TCP和UDP)
TCP和UDP
(1)UDP:
将数据及源和目的封装成数据包中,不需要建立连接。
每个数据包的大小限制在64K内
因无连接,是不可靠协议
不需要建立连接,速度快
(2)TCP:
建立连接,形成传输数据的通道。
在连接中进行大量数据传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低。
(3)UDP如QQ聊天等,UDP如同报话机
TCP如下载等, TCP如同打固定电话
三、网络编程(Socket)
1、Socket
Socket就是为网络服务提供的一种机制,通信的两端都有Socket。网络通信其实就是Socket间的通信, 数据在两个Socket间通过IO传输。
UDP传输需要用到下列类:
DatagramSocket类(java.net包)
此类表示用来发送和接收数据报包的套接字。 数据报套接字是包投递服务的发送或接收点。
DatagramPacket类(java.net包)是一个数据报包
需求:通过UDP传输方式,将一段文字数据发送出去。
定义udp的发送端
思路:
(1)建立udpsocket服务。
(2)提供数据,并将数据封装到数据包中。
(3)通过socket服务的发送功能,将数据包发出去。
(4)关闭资源。
1 class UdpSend
2 {
3 public static void main(String[] args) throws Exception
4 {
5 // 建立udpsocket服务,通过DatagramSocket对象
6 DatagramSocket ds = new DatagramSocket();
7 // 提供数据,并将数据封装到数据包中
8 byte[] buf=”udp come ”.getBytes();
9 DatagramPacket dp =
10 new DatagramPacket(buf,buf.length,InetAddress.getByName
11 (“192.182.3.4”),1099);
12 // 通过socket服务的发送功能,将数据包发出去
13 ds.send(dp);
14 }
15 //关闭资源
16 ds.close();
17 }
18 }
需求:定义一个应用程序,用于接收udp协议传输过来的数据并处理
思路:
(1)建立udpsocket服务。通常会监听一个端口,其实就是给接收应用程序定义一个数字标识,方便明确数据
(2)定义一个数据包,要存储接收到的的数据。
因为数据包对象提供了提取字节数据中不同的数据信息的方法。
(3)通过socket服务的receive方法将接收的数据存入已定义好的数据包中。
(4)通过数据包的特有功能,将这些不同数据取出,打印在控制台上。
(5)关闭资源。
19 class UdpReceive
20 {
21 public static void main(String[] args) throws Exceptions
22 {
23 //1,建立udpsocket服务,建立端点
24 DatagramSocket ds = new DatagramSocket(1099);
25 while(true)
26 {
27 //2,定义一个数据包,存储数据
28 byte buf = new byte[1024];
29 DatagramPacket dp = new DatagramPacket(buf,buf.length);
// 通过socket服务的receive方法将接收的数据存入数据包中。
30 ds.receive(dp);
31 //通过数据包方法获取数据
32 String ip = dp.getAddress.getHostAddress();
33 String data =new String(dp.getData(),0,dp.getLength());
34 Int port=dp.getPort();
35 System.out.println(ip+"::"+data+”::”+port);
36 //关闭资源
37 ds.close();
38 }
39 }
40 }
四.网络编程(TCP传输)
1.TCP传输
Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket.
同样,客户端与服务器端是两个独立的应用程序。
2.类 Socket(java.net )
此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
3.类 ServerSocket(java.net)
此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
代码例题:
1.演示tcp的传输的客户端和服务端的互访。
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
客户端:
1.建立socket服务,指定目的主机和端口。
2.获取socket流中的输出流。将数据写到该流中。通过网络发送给服务端。
3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
4.关闭客户端资源。
41 class TcpClient
42 {
43 public static void main(String[] args) throws Exception
45 {
46 //建立socket服务,指定目的主机和端口
47 Socket s = new Socket("192.165.6.1",10005);
48 //获取socket流中的输出流
49 OutputStream out = s.getOutputStream;
50 out.write("client come on".getBytes());
51 InputStream in = s.getInputStream();
52 byte[] buf = new byte[1024];
53 //读取服务端反馈信息
54 int len = in.read(buf);
55 System.out.println(new String(buf,0,len);
56 s.close();
57 }
58 }
59 class TcpServer
60 {
61 public static void main(String[] args) throws Exception
62 {
63 //建立服务端的Socket服务,并监听一个端口
64 ServerSocket ss = new ServerSocket(10005);
65 //通过 accept方法获取连接过来的客户端对象
66 Socket s = ss.accept();
67 //拿客户端的IP地址
68 String ip = s.getInetAddress.getHostAddress();
69 System.out.println(ip+"....connected");
70 //获取客户端发送过来的数据,使用客户端对象的读取流来读取数据
71 InputStream in = s.getInputStream();
72 byte[] buf = new byte[1024];
73 int len = in.read(buf);
74 System.out.println(new String(buf,0,len);
75 OutputStream out = s.getOutputStream();
76 out.write("服务端已经收到".getBytes());
77 s.close(); //关闭客户端
78 ss.close();
79 }
80 }
/*
82 需求:建立一个文本转换服务器。
83 客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端。
84 而且客户端可以不断的进行文本转换,当客户端输入over时,转换结束。
85 分析:
86 客户端:
87 既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。
88 源:键盘录入。
89 目的:网络设备,网络输出流。
90 而且操作的是文本数据,可以选择字符流。
91 */
92 class TransClient
93 {
94 public static void main(String[] args) throws Exception
95 {
96 //建立服务
97 Socket s =new Socket("192.168.1.1",10003);
98 //定义读取键盘录入的流对象
99 BuffereReader bufr =
100 new BuffereReader(new InputStreamReader(System.in));
101 String line = null;
102 //定义目的,将数据写入socket输出流,发给服务端
103 PrintWriter out = new PrintWriter(s.getOutputStream(),true);
104 //定义读取流,读取服务端返回的信息
105 BufferedReader bufIn =
106 new BufferedReader(new InputStreamReader(s.getInputStream());
107 while((line = bur.readLine())!= null)
108 {
109 if("over".equals(line))
110 break;
111 out.println(line);
112 String str = bufIn.readLine();
113 System.out.println("server:"+str);
114 }
115 bufr.close();
116 s.close();
117 }
118 }
119 服务端:
120 源:socket读取流。
121 目的:socket输出流。
122 class TransServer
123 {
124 public static void main(String[] args) throws Exception
125 {
126 ServerSocket ss = new ServerSocket(10003);
127 Socket s = ss.accept();
128 String ip = s.getInetAddress.getHostAddress();
129 System.out.println(ip+".....is connected!");
130 //读取流中的数据
131 BufferedReader bufIn =
132 new BufferedReader(new InputStreamReader(s.getInputStream());
133 //输出流,将大写数据写入socket输出流,并发送给客户端
134 PrintWriter out = new PrintWriter(s.getOutputStream());
135 String line = null;
136 while((line = bufIn.readLine())!= null)
137 {
138 out.println(line.toUpperCase());
139 }
140 s.close();
141 ss.close();
142 }
143 }
TCP复制文件
144 /*
145 TCP复制文件
146 Socket类的方法(用于加结束标记):
147 void shutdownInput()
148 此套接字的输入流置于“流的末尾”。
149 void shutdownOutput()
150 禁用此套接字的输出流。
151 注:用over作标记容易重复
152 */
153 class CopyClient
154 {
155 public static void main(String[] args) throws Exception
156 {
157 Socket s = new Socket("192.168.6.1",10006);
158 //读取一个文件,文件要存在。
159 BufferedReader bufr =
160 new BufferedReader(new FileReader("java1.txt"));
161 PrintWriter out = new PrintWriter(s.getOutputStream(),true);
162 String line = null;
163 while((line = bufr.readLine())!= null)
164 {
165 out.println(line);
166 }
167 s.shutdownOutput();//关闭客户端的输出流,相当给流加入结束标记
168 BufferedReader bufIn =
169 new BufferedReader(new InputStreamReader(s.getInputStream());
170 String str = bufIn.readLine();
171 System.out.println(str);
172 bufr.close();
173 s.close();
174 }
175 }
176
177 class CopyServer
178 {
179 public static void main(String[] args) throws Exception
180 {
181 ServerSocket ss =new ServerSocket(10006);
182 Socket s = ss.accept();
183 String ip = s.getInetAddress.getHostAddress();
184 System.out.println(ip+"....is connected!");
185 BufferedReader bufIn =
186 new BufferedReader(new InputStreamReader(s.getInputStream());
187 PrintWriter pw = new PrintWriter
188 (new FileWriter("server.txt",true);
189 String line = null;
190 while((line =bufIn.readLine())!= null)
191 {
192 pw.println(line);
193 }
194 PrintWriter out = new PrintWriter(s.getOutputStream());
195 out.write("上传成功".getBytes());
196 out.close();
197 s.close();
198 ss.close();
199 }
200 }
TCP-客户端并发登录
1 /*
2 客户端通过键盘录入用户名。
3 服务端对这个用户名进行校验。
4 如果该用户存在,在服务端显示xxx,已登陆。
5 并在客户端显示 xxx,欢迎光临。
6 如果该用户存在,在服务端显示xxx,尝试登陆。
7 并在客户端显示 xxx,该用户不存在。
8 最多就登录三次。
9 */
10 import java.io.*;
11 import java.net.*;
12 class LoginClient
13 {
14 public static void main(String[] args) throws Exception
15 {
16 Socket s = new Socket("192.168.1.254",10008);
17
18 BufferedReader bufr =
19 new BufferedReader(new InputStreamReader(System.in));
20 PrintWriter out = new PrintWriter(s.getOutputStream(),true);
21
22 BufferedReader bufIn =
23 new BufferedReader(new InputStreamReader(s.getInputStream()));
24 //验证登录次数
25 for(int x=0; x<3; x++)
26 {
27 String line = bufr.readLine();
28 if(line==null)
29 break;
30 out.println(line);
31 String info = bufIn.readLine();
32 System.out.println("info:"+info);
33 if(info.contains("欢迎"))
34 break;
35 }
36 bufr.close();
37 s.close();
38 }
39 }
40
41 class UserThread implements Runnable
42 {
43 private Socket s;
44 UserThread(Socket s)
45 {
46 this.s = s;
47 }
48 public void run()
49 {
50 String ip = s.getInetAddress().getHostAddress();
51 System.out.println(ip+"....connected");
52 try
53 {
54 for(int x=0; x<3; x++)
55 {
56 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
57 String name = bufIn.readLine();
58 if(name==null)
59 break;
60 BufferedReader bufr = new BufferedReader(new FileReader("user.txt"));
61 PrintWriter out = new PrintWriter(s.getOutputStream(),true);
62 String line = null;
63 boolean flag = false; //定义标记
64 while((line=bufr.readLine())!=null)
65 {
66 if(line.equals(name))
67 {
68 flag = true;
69 break;
70 }
71 }
72
73 if(flag) //找到用户名
74 {
75 System.out.println(name+",已登录");
76 out.println(name+",欢迎光临");
77 break;
78 }
79 else
80 {
81 System.out.println(name+",尝试登录");
82 out.println(name+",用户名不存在");
83 }
84 }
85 s.close();
86 }
87 catch (Exception e)
88 {
89 throw new RuntimeException(ip+"校验失败");
90 }
91 }
92 }
93 class LoginServer
94 {
95 public static void main(String[] args) throws Exception
96 {
97 ServerSocket ss = new ServerSocket(10008);
98 while(true)
99 {
100 Socket s = ss.accept();
101 new Thread(new UserThread(s)).start();
102 }
103 }
104 }
类URL(java.net包)
类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。 资源可以是简单的文件或目录, 也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询 ,URL 可选择指定一个“端口”,它是用于建立到远程主机 TCP 连接的端口号。如果未指定该端口号, 则使用协议默认的端口。例如,http 协议的默认端口为 80。
URL url=new URL(“http://192.168.1.1:8080/myweb/1.html”);
URLConnection conn=url.openConnection();
InputStream in=conn.getInputStream();
byte[ ] nuf=new byte[1024] ;
int len=in.read(buf);
System.out.println(new String(buf,0,len);
URLConnection(java.net包)
抽象类 URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。
此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:
(1)通过在 URL 上调用 openConnection 方法创建连接对象。
(2)处理设置参数和一般请求属性。
(3)使用 connect 方法建立到远程对象的实际连接。
(4)远程对象变为可用。远程对象的头字段和内容变为可访问。
小知识点
1.Socket:
void connect(SocketAddress endpoint)
将此套接字连接到服务器。
2.类 SocketAddress(java.net)
此类表示不带任何协议附件的 SocketAddress。作为一个抽象类,应通过特定的、协议相关的实现为其创建子类。 它提供不可变对象,供套接字用于绑定、连接或用作返回值。
3 SocketAddress(java.net)------>InetSocketAddress类
(1)此类实现 IP 套接字地址(IP 地址 + 端口号)。它还可以是一个对(主机名 + 端口号),在此情况下,将尝试解析主机名。如果解析失败,则该地址将被视为未解析 地址,但是其在某些情形下仍然可以使用, 比如通过代理连接。
(2)构造方法
InetSocketAddress(InetAddress addr, int port)
根据 IP 地址和端口号创建套接字地址。
4.ServerSocket:
构造方法
ServerSocket(int port, int backlog)
利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
参数:
port - 指定的端口;或者为 0,表示使用任何空闲端口。
backlog - 队列的最大长度。即主机可同时被访问的最多人数。
网络编程(域名解析)
1、想把主机名翻译成IP地址,需要域名解析。DNS
127.0.0.1和localhost有映射关系,两种都可以访问
2、配置映射关系
(1)将要访问的网站配置到hosts文件,可以极大地提高访问速度。因为减少了访问解析的路程。
(2)有些收费软件使用时,会自动到网站更新,从而会影响使用,将更新网站的主机名进行配置,则软件就不会再更新了,因为它走的是本地地址,所以更新失败。
如:#127.0.0.1 www.myeclipse.com(更新网站举例)
(3)将恶意网站网址在hosts文件中进行配置,则会屏蔽恶意网站。