一、网络基础
- 计算机网络:把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息共享硬件、软件、数据信息等资源;
- 网络编程的目的: 直接或间接地通过网络协议与其它计算机实现数据交换,进行通讯;
- 实现网络通信需要解决的两个问题:
- 如何准确地定位网络上一台或多台主机;定位主机上的特定的应用;
- 找到主机后如何可靠高效地进行数据传输;
二、网络通讯要素
【要素】
- IP和端口号;(定位网络上一台或多台主机)
- 网络通信协议;(数据传输)
1、要素一:IP和端口号
1.1 IP简述
-
IP:唯一的标识 Internet 上的计算机(通信实体);
-
在Java中使用InetAddress类代表IP;
-
IP分类:IPv4 和 IPv6 ; 万维网 和 局域网;
-
域名: www.xxx.com;
-
域名解析:域名容易记忆,当在连接网络时输入一个主机的域名后,域名服务器(DNS)负责将域名转化成IP地址,这样才能和主机建立连接;
-
本地回路地址(访问自己的主机):127.0.0.1; 对应:localhost;
【InetAddress类】
此类的一个对象就代表着一个具体的IP地址;
- 实例化:getByName(String host) /getLocalHost()
- 常用方法:getHostName() / getHostAddress()
//实例化
InetAddress inet1 = InetAddress.getByName("www.baidu.com");
InetAddress inet2 = InetAddress.getByName("192.168.8.151");
//getLocalHost(),获取本地ip;
InetAddress localHost = InetAddress.getLocalHost();
//获取该对象的IP地址和域名;
System.out.println(inet2.getHostAddress());
System.out.println(inet2.getHostName());
1.2 端口号
端口号用于标识正在计算机上运行的进程;
- 要求:不同的进程不同的端口号;
- 范围:被规定为一个 16 位的整数 0~65535;
- 分类:
- 公认端口:0~1023;被预先定义的服务通信占用;(如:HTTP占用端口80,FTP占用端口21,TeInet占用端口23)
- 注册端口:1024~49151;分配给用户进程或应用程序;(如:Tomcat占用端口8080,MSQL占用端口3306,Oracle占用端口1521等)
- 动态私有端口:49152~65535;
【套接字Socket】
端口号与IP地址的组合得出一个网络套接字:Socket;
2、要素二:网络通信协议
2.1分层通信
【网络通讯协议】
一般使用TCP/IP协议簇;
2.2 传输层中的TCP和UDP
【TCP协议】
- 使用TCP协议前,须先建立TCP连接,形成传输数据通道;
- 传输前,采用“三次握手”方式,点对点通信,是可靠的;
- TCP协议进行通信的两个应用进程:客户端、服务端;
- 在连接中可进行大数据量的传输;
- 传输完毕,需释放已建立的连接,效率低;
【UDP协议】
- 将数据、源、目的封装成数据包,不需要建立连接;
- 每个数据报的大小限制在64K内;
- 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的;对方不在则可能丢包;
- 可以广播发送;
- 发送数据结束时无需释放资源,开销小,速度快;
2.3 TCP三次握手和四次挥手
【建立连接】
【释放链接】
客户端和服务端都可以主动挥手;一般都是客户端主动;
三、TCP网络编程
【客户端Socket】
- 创建Socket:根据指定服务端的P地址或端口号构造Sσcket类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常;
- 打开连接到 Socket的输入出流:使用getInputstream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输;
- 按照一定的协议对Socket进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程;
- 关闭 Socket:断开客户端到服务器的连接,释放线路;
【服务器端Socket】
- 调用ServerSocket(int port):创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求;
- 调用accept0():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象;
- 调用该Socket类对象的getOutputStream()和getInputStream():获取输出流和输入流,开始网络数据的发送和接收;
- 关闭 ServerSocket和Socket对象:客户端访问结束,关闭通信套接字;
【代码示例】
客户端发送文件给服务端,服务端将文件保存在本地;
/*
这里涉及到的异常,应该使用try-catch-finally处理,为了方便查看,就直接抛出了;
*/
@Test
public void client() throws IOException {
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("beauty.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
fis.close();
os.close();
socket.close();
}
@Test
public void server() throws IOException {
ServerSocket ss = new ServerSocket(9090);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("beauty1.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
fos.close();
is.close();
socket.close();
ss.close();
}
}
四、UDP网络编程
【基本步骤】
- 创建DatagramSocket与DatagramPacket对象;
- 建立发送端,接收端;
- 建立数据包;new DatagramPacket
- 调用 Socket的发送、接收方法;
- socket.send(packet);
- socket.receive(packet);
- 关闭 Socket;
【代码示例】
//发送端
@Test
public void sender() throws IOException {
DatagramSocket socket = new DatagramSocket();
String str = "我是UDP方式发送的信息";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
socket.send(packet);
socket.close();
}
//接收端
@Test
public void receiver() throws IOException {
DatagramSocket socket = new DatagramSocket(9090);
byte[] buffer = new byte[100];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
}
}
五、URL编程
【说明】
- URL(Uniform Resource Locator):统一资源定位符,它表示Internet上某一资源的地址;
- 它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源;
- 通过URL我们可以访问 Internet上的各种网络资源,比如最常见的www,ftp站点。浏览器通过解析给定的URL可以在网络上查找相应的文件或其他资源;
- URL的基本结构由5部分组成: <传输协议>://<主机名>:<端口号>/<文件名>#片段名?
【URL类的构造器】
java.net中实现了类URL;
- public URL(String spec):通过一个表示URL地址的字符串可以构造一个URL对象。 例如:URL url = new URL(“http://www.baidu.com/”);
- public URL(URL context,String spec):通过基URL和相对URL构造一个URL对象 例如: URL downloadeUrl = new URL(url,“download.html”);
- public URL(String protocol,String host,String file); 例如:new URL(“http”,“www.baidu.com”,80,“download.html”);
- public URL(String protocol,String host,int port,String file); 例如:new URL(“http”,“www.baidu.com”,80,“download.html”);
【方法】
- public String getProtocol( ) 获取该URL的协议名;
- public String getHost( ) 获取该URL的主机名;
- public String getPort( ) 获取该URL的端口号;
- public String getPath( ) 获取该URL的文件路径;
- public String getFile( ) 获取该URL的文件名;
- public String getQuery( ) 获取该URL的查询名;
【代码示例】
通过URL下载;
public static void main(String[] args) {
HttpURLConnection urlConnection = null;
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL("http://localhost:8080/xxx/xxx.jpg");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
is = urlConnection.getInputStream();
fos = new FileOutputStream("xxx.jpg");
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
System.out.println("下载完成");
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
//流资源关闭略。。
if(urlConnection != null){
urlConnection.disconnect();
}
}
}
}
fos.write(buffer,0,len);
}
System.out.println("下载完成");
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
//流资源关闭略。。
if(urlConnection != null){
urlConnection.disconnect();
}
}
}
}