Java 网络编程
网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。
java.net 包中 J2SE 的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。
java.net 包中提供了两种常见的网络协议的支持:
TCP:TCP(英语:Transmission Control Protocol,传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP 层之上,应用层之下的中间层。TCP 保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。
UDP:UDP (英语:User Datagram Protocol,用户数据报协议),位于 OSI 模型的传输层。一个无连接的协议。提供了应用程序之间要发送数据的数据报。由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。
网络分层
(1)物理层
物理层处于OSI的最底层,是整个开放系统的基础。物理层涉及通信信道上传输的原始比特流(bits),它的功能主要是为数据端设备提供传送数据的通路以及传输数据。机房,硬件空调什么的。
(2)数据链路层
数据链路层的主要任务是实现计算机网络中相邻节点之间的可靠传输,把原始的、有差错的物理传输线加上数据链路协议以后,构成逻辑上可靠的数据链路。需要完成的功能有链路管理、成帧、差错控制以及流量控制等。其中成帧是对物理层的原始比特流进行界定,数据链路层也能够对帧的丢失进行处理。交换机 双绞线。
(3)网络层
网络层涉及源主机节点到目的主机节点之间可靠的网络传输,它需要完成的功能主要包括路由选择、网络寻址、流量控制、拥塞控制、网络互连等。IP,路由器。
(4)传输层
传输层起着承上启下的作用,涉及源端节点到目的端节点之间可靠的信息传输。传输层需要解决跨越网络连接的建立和释放,对底层不可靠的网络,建立连接时需要三次握手,释放连接时需要四次挥手。
(5)应用层
应用层为OSI的最高层,是直接为应用进程提供服务的。其作用是在实现多个系统应用进程相互通信的同时,完成一系列业务处理所需的服务。约定数据内容和格式。
TCP/UDP
TCP(传输控制协议) TCP是面向连接的协议,因此每个TCP连接都有3个阶段:连接建立、数据传送和连接释放。连接建立经历三个步骤,通常称为“三次握手”。握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。
(TCPServer)
package com.lanou.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TCPServer {
public static void main(String[] args) {
//JAVA的TCP编程中,BIO模型使用一个工具实现TCP编程,这个工具叫做Socket,服务端叫ServerSocket,
try {
ServerSocket ss = new ServerSocket(65535);//这个端口号 写死 固定的
//这个是客户端发送上来的链接,服务器使用这个链接做数据处理
Socket s = ss.accept();
//分别是两个指针对当前联机的输入输出流
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
//改变输入输出流的状态(套一个其它流)
PrintWriter pw = new PrintWriter(os);
Scanner scanner = new Scanner(System.in);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while(true) {
String str= scanner.nextLine(); //nextline 阻塞式代码
pw.println(str);
pw.flush();
if(str.equals("")) {
break;
}
str = br.readLine();
System.out.println("我是服务器,我收到客户端消息" + str);
if(str.equals("")) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
(TCPClient)
package com.lanou.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class TCPClient {
public static void main(String[] args) {
//客户端,直接使用Sockert工具
try {
Socket s = new Socket("127.0.0.1", 65535);
// host 链接到那个主机上 String的参数 port端口
InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
PrintWriter pw = new PrintWriter(os);
Scanner scanner = new Scanner(System.in);
String str;
while(!(str = br.readLine()).equals("")) {
System.out.println("客户端收到"+str);
str = scanner.nextLine();
pw.println(str);
pw.flush();
if(str.equals("")) {
break;
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(UDPServer)
package com.lanou.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UDP {
public static void main(String[] args) {
//UDP是面向报文的,所以数据传输过程中,是不需要建立链接的,只要有对应的报文,就可以指挥网卡去发送这个数据包
//但是对于服务器来说,UDP虽然没有建立链接,却需要在对应的端口上进行监听,否则是有问题的
//DatagramSocket,这个类型是JAVA对于UDP实现的一个网络套接字,当我们需要使用UDP传输内容的时候,只需要创建一个
//DatagramSocket,对象就可以了,不用指定这个对象是否是服务(区别TCP的ServerSocket)
try {
DatagramSocket socket = new DatagramSocket(10086);
byte[] b = new byte[1024];
DatagramPacket p =new DatagramPacket(b, b.length);
while(true) {
socket.receive(p);
b = p.getData();//拿出数据 拆开包裹
System.out.println(new String(b));
System.out.println(p.getAddress() + "说 : " + new String(b));
p.setData("你开心就好".getBytes());
socket.send(p);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(UDPClient)
package com.lanou.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
public class UDPClient {
public static void main(String[] args) {
try {
DatagramSocket socket = new DatagramSocket();
String str = "我是客户端 ";
DatagramPacket p = new DatagramPacket(str.getBytes(), str.getBytes().length);
p.setSocketAddress(new InetSocketAddress("127.0.0.1", 10086));
socket.send(p);
socket.receive(p);
System.out.println(new String(p.getData()));
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}