Java网络编程基础
一、网络编程中有两个主要的问题
- 如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
- 找到主机后如何可靠高效地进行数据传输
二、网络编程中的两个要素
- 对应问题一:IP和端口号
- 对应问题二:提供网络通信协议。TCP/IP参考模型(应用层、传输层、网络层、物理+数据链路层)
三、通信要素一:IP和端口号
- IP:唯一的标识 Internet上的计算机(通信实体)
- 在Java中使用InetAddress类代表IP
- IP分类:IPV4 和 IPV6 ; 万维网 和 局域网
- 域名: wwww.baidu.com
- 本地回路地址:127.0.0.1 对应着 localhost
- 如何实例化InetAddress:两个方法:getByName(String host) / getLocalHost()
两个常用方法:getHostName() / getHostAddress() - 端口号:正在计算机上运行的进程。
要求:不同的进程有不同的端口号
范围:被规定为一个16位的整数 0 ~ 65535。 - 端口号与IP地址的组合得出一个网络套接字:Socket
四、通信要素二:网络通信协议
InetAddress类的实例化以及方法的调用
public class InetAddressTest {
public static void main(String[] args) {
try {
//File file = new File("hello.txt");
InetAddress inet1 = InetAddress.getByName("127.0.0.1");
System.out.println(inet1);
InetAddress inet2 = InetAddress.getByName("www.baidu.com");
System.out.println(inet2);
//获取本机IP
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
//
System.out.println(inet2.getHostName());
System.out.println(inet2.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
实现TCP的网络编程
例题1:客户端发送信息给服务端,服务端将数据显示在控制台上
//客户端
@Test
public void client(){
Socket socket = null;
OutputStream os = null;
try {
//1.创建socket对象,指明服务器的IP和端口号
InetAddress inet = InetAddress.getByName("127.0.0.1");
socket = new Socket(inet, 8899);
//2.获取输出流,用于输出数据
os = socket.getOutputStream();
//3.写出数据操作
os.write("唯独你没懂".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭资源
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//服务端
@Test
public void server(){
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.创建服务器端的ServerSocket,指明自己的端口号
ss = new ServerSocket(8899);
//2.调用accept()表示接受来自于客户端的socket
socket = ss.accept();
//3.获取输入流
is = socket.getInputStream();
//4.读取输入流中的数据
byte[] buffer = new byte[5];
int len;
baos = new ByteArrayOutputStream();
while ((len = is.read(buffer)) != -1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
//5.关闭资源
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
例题2:客户端发送文件给服务端,服务端将文件保存在本地。
@Test
public void client() throws IOException {
//1.创建一个Socket对象,输入目标服务器的IP与端口号
Socket socket = new Socket("127.0.0.1", 9090);
//2.获取socket的输出流,用于输出数据
OutputStream os = socket.getOutputStream();
//3.创建一个读取图片的文件输入流
FileInputStream fis = new FileInputStream("p1.png");
//4.读取图片的输入流并写出到socket的输出流中
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//5.关闭资源
os.close();
fis.close();
socket.close();
}
@Test
public void server() throws IOException{
//1.创建一个ServerSocket对象,指明端口号
ServerSocket ss = new ServerSocket(9090);
//2.调用accept()表示接受来自于客户端的socket
Socket socket = ss.accept();
//3.获取socket的输入流
InputStream is = socket.getInputStream();
//4.创建一个本地文件的输出流
FileOutputStream fos = new FileOutputStream("p2.png");
//5.读取输入流中的数据并将其写出到本地
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
System.out.println("保存成功!");
//6.关闭资源
fos.close();
is.close();
socket.close();
ss.close();
}
例题3:客户端发送文件给服务端,服务端保存在本地,并返回“发送成功”给客户端。并关闭相应的连接。
@Test
public void client() throws IOException {
//1.创建一个socket对象,指明目标IP地址和端口号
Socket socket = new Socket("127.0.0.1", 9090);
//2.获取socket的输出流
OutputStream os = socket.getOutputStream();
//3.创建一个文件输入流
FileInputStream fis = new FileInputStream("p1.png");
//4.将图片数据写出
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//5.写出图片操作结束后关闭输出流
socket.shutdownOutput();
//6.获取服务端传来的消息并打印
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer1 = new byte[20];
int len1;
while ((len1 = is.read(buffer1)) != -1){
baos.write(buffer1,0,len1);
}
System.out.println(baos.toString());
//7.关闭资源
baos.close();
is.close();
os.close();
fis.close();
socket.close();
}
@Test
public void server() throws IOException{
//1.创建一个ServerSocket对象,指明端口号
ServerSocket ss = new ServerSocket(9090);
//2.调用accept()表示接受来自于客户端的socket
Socket socket = ss.accept();
//3.获取输入流
InputStream is = socket.getInputStream();
//4.创建文件输出流
FileOutputStream fos = new FileOutputStream("p3.png");
//5.将获取的图片数据写出到本地
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
System.out.println("图片传输完成!");
//6.图片获取成功后给客户端发送消息
OutputStream os = socket.getOutputStream();
os.write("唯独你没懂".getBytes());
//7.关闭资源
os.close();
fos.close();
is.close();
socket.close();
ss.close();
}
UDP协议的网络编程
测试代码:
//发送端
@Test
public void sendder() throws IOException {
DatagramSocket socket = new DatagramSocket();
String str = "唯独你没懂";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
socket.send(packet);
System.out.println("发送成功!");
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()));
System.out.println("完");
socket.close();
}
URL的网络编程
- URL:统一资源定位符,对应着互联网的某一资源地址
- 格式
http://localhost:8080/examples/p1.png?username=xxx
协议 主机名 端口号 资源地址 参数列表
测试代码:
URL类的实例化以及常用方法
try {
URL url = new URL("http://localhost:8080/examples/p1.png");
System.out.println(url.getProtocol());//获取该URL的协议名
System.out.println(url.getHost());//获取该URL的主机名
System.out.println(url.getPort());//获取该URL的端口号
System.out.println(url.getPath());//获取该URL的文件路径
System.out.println(url.getFile());//获取该URL的文件名
System.out.println(url.getQuery());//获取该URL的查询名
} catch (MalformedURLException e) {
e.printStackTrace();
}
使用URL的网络编程获取网络上的资源
@Test
public void test() {
HttpURLConnection urlConnection = null;
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL("http://localhost:8080/examples/p1.png");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
is = urlConnection.getInputStream();
fos = new FileOutputStream("p4.png");
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 (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}