package com.net;
/**
* 1、什么是网络?什么是计算机网络?
* 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,
* 从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源
* 2、计算机网络的基本功能?
* 资源共享
* 信息传输与集中处理
* 均衡负荷与分布处理
* 综合信息服务
* 3、计算机网络协议?
* 计算机网络中实现通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传 输控制步骤、出错控制等制定标准。
* 4、纷繁复杂的计算机网络是如何来管理的?
* 由于结点之间联系很复杂,在制定协议时,把复杂成份分解成 一些简单的成份,再将它们复合起来。
* 最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系
* 分层的思想。
* 1) OSI 开放的系统互联参考模型。 将计算机网络分为七个层次。
* 由高到低: 应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
* 2) TCP/IP参考模型。 将计算机网络分为四个层次。
* 应用层、传输层、网络层、物理·数据链路层
* 5、数据在计算机网络中的传输过程?
* 从一端的高层到底层,再从另一端的底层到高层
* 6、什么是TCP:transfer control protocol?
* 一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议 。
* 特点:面向连接点到点的通信高可靠性
* TCP三次握手(Three-way Handshake),TCP通信类似于拨打电话
* 7、什么是UDP:UserDatagramProtocol?
* 一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
* 特点:非面向连接传输不可靠数据可能丢失
* 类似于:发送短信
* 8、什么是IP:Internet Protocol?
* IP: Internet Protocol
* 网络之间互连的协议,为计算机网络相互连接进行通信而设计的协议。
* IPV4:32位地址,以点分十进制表示,如192.168.0.1
* IPV6:128位(16个字节)写成8个16位的无符号整数,每个整数用四个十六进制位表示,
* 数之间用冒号(:)分开,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984
* 9、端口:
* 端口是虚拟的概念,并不是说在主机上真的有若干个端口。通过端口,可以在一个主机上运行多个网络应用程序。
* 它是信息的输入输出的通信口,它是一个int型整数,其范围是[0, 65535]
* http 80
* ftp 21
* 在Java中使用InetAddress类来封装计算机的ip地址和DNS,
* 也可以用包含端口的InetSocketAddress类,如以下代码
*/
import java.net.*;
import java.io.*;
public class MyInetAddress {
public static void main(String[] args) {
try {
//InetAddress 不指定端口,即利用默认端口
InetAddress iObj = InetAddress.getByName("www.baidu.com");
//InetAddress iObj2 = InetAddress.getLocalHost();
String name = iObj.getHostName();
String ip = iObj.getHostAddress();
System.out.println("百度的Web服务器的名称是: " + name);
System.out.println("百度的Web服务器的地址是: " + ip);
//InetSocketAddress 指定端口
InetSocketAddress socketAddress = new InetSocketAddress("www.baidu.com",8080);
InetSocketAddress socketAddress2 = new InetSocketAddress("www.baidu.com",9000);
System.out.println(socketAddress.getHostName());
System.out.println(socketAddress2.getAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
/** 10、本章涉及的类和接口等均来自 java.net.*包。
*
* 11、URL是什么:Uniform Resource Locator?
* 统一资源定位器,用来定位网络上指定的资源。
* 它由四部分组成:协议://主机名:端口号/资源名称
* 例如: http://localhost:8080/index.jsp/
*
* 在Java中为了定位网络上的资源,为此提供了 URL类。
* URL类提供了一个 openStream() 方法用来获取网络上的字节流。
*
* 案例: 网络爬虫,即: 用来读取网络上的指定资源[]。如以下代码:
*/
class MyURL {//测试请加public
public static void main(String[] args) {
String url = "http://www.baidu.com/";
URL obj = null;
InputStream is = null;
BufferedReader br = null;
try {
obj = new URL( url );
is = obj.openStream();//返回InputStream
//使用转换流防止乱码,可以指定编码
br = new BufferedReader( new InputStreamReader(is, "utf-8") );
//读取
int x = br.read();
while( x != -1 ){
System.out.print( (char)x );
x = br.read();
}
System.out.println("
从 " + url + " 上读取主页内容完毕。");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if( br != null ){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( is != null ){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/** 12、Socket通信(TCP通信)
* 关于Socket套接字,它是一种进程间的数据交换机制。
* 这些进程既可以在同一机器上,也可以在通过网络连接的不同机器上。
* 换句话说,套接字起到通信端点的作用。
* 单个套接字是一个端点,而一对套接字则构成一个双向通信信道,使非关联进程可以在本地或通过网络进行数据交换。
* 一旦建立套接字连接,数据即可在相同或不同的系统中双向或单向发送,直到其中一个端点关闭连接。
* 1) 什么是Socket?
* 它称之为套接字,指定计算机网络中通信双方的某一端。
* 由套接字建立两个通信节点之间的数据流通道,从而实现信息的传递。
* 它采用TCP协议以字节流方式实现通信,是实时地。
* 2) Socket网络程序的原理[通信步骤]?
* a) 先在服务器上开放一个端口(就是一个信息的输入输出口,是一个int型整数。)
* b) 调用accept()方法准备接收客户端的请求连接。
* c) 客户端向服务器发现请求,要求建立连接。
* d) 服务器响应客户端的请求。
* e) 服务器或客户端通过Socket对象的方法getInputStream()和getOutputStream()建立输入输出流通道。
* f) 当输入输出流通道建立后,则可实现信息的传递。
* g) 最后,当信息传递完毕;则需要关闭通信。
* 13、要实现Socket通信,在服务器端如何编程?
* 1) 构建一个ServerSocket对象,开放服务器某个端口。
* 2) 调用accept()方法,准备接收客户端的请求。
* 3) 调用Socket对象的getInputStream()和getOutputStream()方法建立输入输出流通道。
* 4) 根据业务的需要,将输入输出流通道处理成其它流通道(如: 数据流通道)。
* 5) 调用流通道提供的方法实现信息传递。
* 6) 当业务完成后,需要关闭输入输出流通道,关闭Socket对象,关闭开放的端口。
* 7) 重写 2)至6)可为多个客户端服务。如下面的代码:
*/
class ServerTest {//简单版,下面有稍稍复杂点的
public static void main(String[] args) {
ServerSocket ss = null;
Socket s = null;
OutputStream os = null;
PrintStream ps = null;
System.out.println("服务器已启动,开放的端口为 9999,正等待客户端的请求连接....... ");
try {
//1
ss = new ServerSocket( 9999 );
//2
s = ss.accept();
//3
os = s.getOutputStream();
//4
ps = new PrintStream( os );
String str = "世界,你好!";
//5出口
ps.println( str );
ps.flush();
System.out.println("服务器已将 " + str + " 传递给客户端了。");
} catch (IOException e) {
System.out.println("端口被占用!");
e.printStackTrace();
} finally {
if( ps != null ){
ps.close();
}
if( os != null ){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( s != null ){
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( ss != null ){
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class ServerTest2 {//这个版本可以传文件
public static void main(String[] args) {
ServerSocket ss = null;
Socket s = null;
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
String path = "d:\ab.jpg";
byte[] bs = new byte[2048];
System.out.println("
服务器已准备好,开放的端口为 8899,正等待客户端的请求连接....... ");
try {
//1
ss = new ServerSocket( 8899 );
while( true ){
//2
s = ss.accept();
//3,4
bos = new BufferedOutputStream( s.getOutputStream() );
bis = new BufferedInputStream( new FileInputStream(path) );
//一边读取文件内容一边传递
int len = bis.read( bs );
while( len > 0 ){
bos.write( bs, 0, len );
len = bis.read( bs );
}
bos.flush();
bis.close();
bos.close();
s.close();
System.out.println("已将 " + path + " 传递给 " + s.getInetAddress().getHostAddress() + " 客户端了。" );
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if( bis != null ){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( bos != null ){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( s != null ){
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( ss != null ){
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/** 14、要实现Socket通信,在客户端如何编程?
* 1) 构建一个Socket对象,向服务器发送请求。
* 2) 调用getInputStream()和getOutputStream()方法建立输入输出流通道。
* 3) 根据业务的需要,将输入输出流通道处理成其它流通道(如: 数据流通道)。
* 4) 调用流通道提供的方法实现信息传递。
* 5) 当业务完成后,需要关闭输入输出流通道,关闭Socket对象。如以下代码:
*/
class ClientTest {//简单版,下面有稍稍复杂点的
public static void main(String[] args) {
Socket s = null;
InputStream is = null;
BufferedReader br = null;
try {
//1
s = new Socket("localhost", 9999 );
//2
is = s.getInputStream();
//3 把从Socket对象获取输入流转成缓冲流
br = new BufferedReader( new InputStreamReader(is) );
//4
String str = br.readLine();
while( str != null ){
System.out.println( str );
str = br.readLine();
}
System.out.println("从服务器上传来的信息接收完毕。");
} catch (UnknownHostException e) {
System.out.println("给定的主机找不到!");
} catch (IOException e) {
System.out.println("给定的端口被占用或不存在!");
} finally {
if( br != null ){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( is != null ){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( s != null ){
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class ClientTest2 {
public static void main(String[] args) {
Socket s = null;
BufferedInputStream bis = null;
byte[] bs = new byte[2048];
String path = "d:\abc.jpg";
BufferedOutputStream bos = null;
try {
s = new Socket("localhost", 8899);
bis = new BufferedInputStream( s.getInputStream() );
bos = new BufferedOutputStream( new FileOutputStream(path) );
int len = bis.read( bs );
while( len > 0 ){
bos.write(bs, 0, len);
len = bis.read( bs );
}
bos.flush();
bos.close();
bis.close();
System.out.println("已将服务器传来信息接收完毕,并存放到 " + path + "文件中了。");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if( bos != null ){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( bis != null ){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( s != null ){
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 1、什么是UDP?数据报通信
* 每个数据发送单元被统一封装成数据包的方式,发送方将数据包发送到网络中,数据包在网络中去寻找他的目的地
* 2、UDP通信的必须条件:
* 1) DatagramSocket 数据报套接字类 (相当于投递员);
* 2) DatagramPacket 数据报包类(打包机)
* 3) 字节型数组。
* 4) InetAddress 地址类[管目标地址,源地址的]
* 5) 端口号 [int型整数]
* 3、UDP通信的原理:
* 1) 服务器必须开放一个端口[创建了一个DatagramSocket对象]。
* 2) 准备两个数据报包[一个是用来接收数据的包,一个是用来发送数据的包]
* 3) 包的投递与接收。
* 4、要实现UDP通信,在服务器如何编程?
* 1) 构建一个DatagramSocket对象,并开放一个端口。
* 2) 构建一个接收包,用来接收客户端发来的信息。
* 3) 调用 receive()方法来接收信息,并存放到接收包上。
* 4) 从接收包上读取客户的IP和端口 及其信息。
* 5) 构建一个发送包,并将要发送的信息及客户端地址和端口一同封装。
* 6) 调用 send()方法将发送包投递出去。
* 7) 重复 2)至6)可反复实现接收与发送数据包。
* 5、要实现UDP通信,在客户端如何编程?
* 1) 构建一个DatagramSocket对象。
* 2) 构建一个发送包,需要将发送的信息和服务器公开的地址及其端口一同封装。
* 3) 调用 send() 方法将发送包投递出去。
* 4) 构建一个接收包。
* 5) 调用 receive()方法,接收服务器传来的信息并存放到接收包中。
* 6) 从接收包上获取信息并处理它(如: 显示)
* 7) 重复 2)至 6)即可反复实现包投递服务。
* UDP案例代码如下:
*/
class UDPServer {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket dpIn = null;
DatagramPacket dpOut = null;
byte[] b = new byte[1000];
try {
ds = new DatagramSocket(9528);
dpIn = new DatagramPacket(b, b.length);
ds.receive(dpIn);
String ss = new String(dpIn.getData(), 0, dpIn.getLength());
System.out.println("收到的信息:" + ss);
String s = "我是服务器,我已经收到你的信息我是服务器,我已经收到你的信息我是服务器,我已经收到你的信息我是服务器,我已经收到你的信息";
System.out.println(""+s.length()+"+"+s.getBytes().length);
dpOut = new DatagramPacket(s.getBytes(), s.getBytes().length, dpIn.getAddress(), dpIn.getPort());
ds.send(dpOut);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
}
class UDPClient {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket dpOut = null;
DatagramPacket dpIn = null;
byte[] b = new byte[1000];
try {
ds = new DatagramSocket();
String s = "服务器,你能看见我?我是客户端发出的消息";
dpOut = new DatagramPacket(s.getBytes(), s.getBytes().length, InetAddress.getByName("localhost"), 9528);
ds.send(dpOut);
System.out.println("我是客户端,我向服务器发送了一条消息");
dpIn = new DatagramPacket(b, b.length);
ds.receive(dpIn);
System.out.println(new String(dpIn.getData(), 0, dpIn.getLength()));
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
}