java学习(18)-- 网络编程

java学习(18)

这篇来写关于网络编程的内容。

1.网络编程&& Udp

1.1 网络通信介绍

(1)tcp/ip协议

(2)udp/ip协议


1.2 Socket通信

网络编程三要素:

(1)ip:一个计算的标示(找到这个计算机)

(2)端口:应用程序都会对应一个端口,用来进行通信,有效端口:0~65535,其中0~1024系统使用或保留端口(360查看端口)。

(3)协议:总共有2种协议:TCP、UDP


1.3 三要素详解:

(1)特殊的IP地址:

127.0.0.1本地回环地址用来做一些本地测试

pingIP地址用来检测本机是否可以和指定的IP地址的计算机可以进行正常通讯

java学习(18)-- 网络编程_第1张图片

ipconfig用来查看IP地址

xxx.xxx.xxx.255 :广播地址


(2)端口号

物理端口:物理设备对应的端口网卡口

逻辑端口用来标示我们的计算机上的进程 , 端口号的有效范围应该是 0-65535其中0-1024被系统占用或者保留


(3)协议:

UDP协议:

A.把数据打成一个数据包 , 不需要建立连接

B.数据包的大小有限制不能超过64k

C.因为无连接,所以属于不可靠协议(可能丢失数据)

D.因为无连接 ,所以效率高

TCP协议:

A.需要建立连接,形成连接通道

B.数据可以使用连接通道直接进行传输,无大小限制

C.因为有链接,所以属于可靠协议

D.因为有链接,所以效率低


1.4 InetAddress:IP地址的描述类

A:InetAddress类的概述

为了方便我们对IP地址的获取和操作,java提供了一个类InetAddress 供我们使用此类表示互联网协议 (IP) 地址。 

B:InetAddress类的常见功能

public static InetAddress getByName(String host)( host: 可以是主机名,也可以是IP地址的字符串表现形式)

public String getHostAddress()返回 IP 地址字符串(以文本表现形式)。

public String getHostName()获取此 IP 地址的主机名。 

示例:

public static void main(String[] args) throws Exception {
		InetAddress address = InetAddress.getByName("10.100.9.174");
		System.out.println(address.getHostAddress());
		System.out.println(address.getHostName());
	}
java学习(18)-- 网络编程_第2张图片

1.5 socket编程(套接字编程,网络编程

Socket套接字:网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。


Socket原理机制:

(1)通信的两端都有Socket。

(2)网络通信其实就是Socket间的通信。

(3)数据在两个Socket间通过IO传输。


1.6 UDP协议

特点:

(1)把数据打包

(2)不需要建立连接,也称为面向无连接协议

(3)数据需打包,数据大小有限制64k

(4)无需建立连接,所以不可靠

(5)速度快


UDP通信步骤:

发送端步骤:

UDP发送数据的步骤:

A:创建UDP发送数据端Socket对象

B:创建数据包,并给出数据,把数据打包

C:通过Socket对象发送数据包 

D:释放资源

示例:

public static void main(String[] args) throws Exception {
		
		//1.创建发送端Socket对象
		DatagramSocket ds = new DatagramSocket();
		
		String str = "hello,world";
		byte[] buf = str.getBytes();
		int length = buf.length;
		InetAddress address = InetAddress.getByName("127.0.0.1");
		int port = 6666;
		
		//2.创建数据包
		DatagramPacket dp = new DatagramPacket(buf,length,address,port);
		
		//3.发送数据
		ds.send(dp);
		
		//4.释放资源
		ds.close();
	}

接收端步骤:

UDP协议接收数据步骤:

A:创建UDP接收数据端Socket对象

B:创建一个接收数据的数据包

C:接收数据,数据在数据包中

D:解析数据包,并把数据显示在控制台

E:释放资源

示例:

public static void main(String[] args) throws Exception {
		//1.创建接收端socket对象
		DatagramSocket ds = new DatagramSocket(6666);
		
		//2.创建数据包
		byte[] buf = new byte[1024];
		int length = buf.length;
		DatagramPacket dp = new DatagramPacket(buf, length);
		
		//3.接受数据
		ds.receive(dp);
		byte[] data = dp.getData();
		int len = dp.getLength();
		System.out.println(new String(data, 0, len));
		
		//4.释放资源
		ds.close();
	}
运行:

java学习(18)-- 网络编程_第3张图片

1.7案例:键盘录入数据实现数据的动态发送

发送端:

public class UdpClient {

	public static void main(String[] args) throws Exception {
		
		//创建发送端socket对象
		DatagramSocket ds = new DatagramSocket();
		
		InetAddress address = InetAddress.getByName("127.0.0.1");
		int port = 7777;
		
		Scanner sc = new Scanner(System.in);
		String line;
		System.out.println("请输入聊天内容:");
		while((line = sc.nextLine())!=null){
			System.out.println("请输入聊天内容:");
			byte[] buf = line.getBytes();
			int length = buf.length;
			DatagramPacket dp = new DatagramPacket(buf, length, address, port);
			
			//发送信息
			ds.send(dp);
		}
		
		//释放资源
		ds.close();
	}
}
接收端:

public class UdpServer {

	public static void main(String[] args) throws Exception {
		//创建接收端socket对象
		DatagramSocket ds = new DatagramSocket(7777);
	
		while(true){
			byte[] buf = new byte[1024];
			int length = buf.length;
			DatagramPacket dp = new DatagramPacket(buf, length);
			ds.receive(dp);
			byte[] data = dp.getData();
			int len = dp.getLength();
			System.out.println("客户端:"+new String(data,0,len));
		}
		
	}
}
运行:

java学习(18)-- 网络编程_第4张图片java学习(18)-- 网络编程_第5张图片

2.TCP协

2.1 TCP协议

特点:

1.需要建立通道

2.传送大量数据无限制

3.面向连接

4.可靠

5.速度慢


TCp协议书写步骤:

发送端:

TCP协议发送数据步骤:

A:创建TCP协议发送端Socket对象

指定服务器IP及端口

B:获取输出流,并写数据

C:释放资源

示例:

public static void main(String[] args) throws Exception {
		//创建socket对象
		Socket socket = new Socket("127.0.0.1",20000);
		
		//获取输出流
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		
		//获取键盘输入
		System.out.println("请输入聊天内容:");
		Scanner sc = new Scanner(System.in);
		String line = sc.nextLine();
		
		//写到流中
		bw.write(line);
		bw.flush();
		
		//释放资源
		socket.close();
		
	}

注意:TCP协议是不能直接运行客户端的,必须先运行服务器。因为他是一种可靠的协议。直接运行客户端会报错:


接收端:

TCP协议接收数据步骤:

A:创建TCP协议接收端Socket对象

B:监听客户端连接

C:获取输入流,并读取数据,显示在控制台

D:释放资源

示例:

public static void main(String[] args) throws Exception {
		//创建socket对象
		ServerSocket serverSocket = new ServerSocket(20000);
		
		//监听
		Socket socket = serverSocket.accept();
		
		//获取通道输入流
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		
		//读数据
		String line = br.readLine();
		
		System.out.println("客户端:"+line);
		
		//释放资源
		socket.close();
		
	}


2.2 案例:客户端键盘录入数据,服务器端接收数据在控制台输出

上述Tcp代码运行即可:

java学习(18)-- 网络编程_第6张图片java学习(18)-- 网络编程_第7张图片


2.3 案例:上传文本文件

客户端:

a: 读取文本文件中的数据

b: 发送到服务器端

服务器:

a: 读取流通道中的数据

b: 把数据写入到文本文件中

分析:基于Tcp协议的文本文件上传

发送端:

public class TcpClient {

	public static void main(String[] args) throws Exception {
		//创建socket对象
		Socket socket = new Socket("127.0.0.1",20000);
		
		//封装流
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		String readLine;
		
		//获取输出流
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		
		while(( readLine = br.readLine())!=null){	
			//写到流中
			bw.write(readLine);
			bw.newLine();
			bw.flush();		
		}
		
		//释放资源
		socket.close();
		
	}
}
接收端:

public class TcpServer {

	public static void main(String[] args) throws Exception {
		//创建socket对象
		ServerSocket serverSocket = new ServerSocket(20000);
		
		//监听
		Socket socket = serverSocket.accept();
		String line;
		
		//获取通道输入流
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		//写到文件 b.txt 中
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		while((line = br.readLine())!=null){
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		
		//释放资源
		socket.close();
	}
}


2.4 基于多线程实现文本文件的上传

分析:对于上述代码,由于接收端把写入文件写死了,只能有一个发送端上传文件,并且每次都会把文件内容覆盖掉,因此,利用多线程改进,可以支持多个发送端上传文件,并且可以使用UUID类每次生成一个随机文件名,避免内容覆盖

改进:

发送端代码不用调整,改进接收端代码,以及添加一个线程类和利用UUID类来产生文件名字的类:

接收端:

public class TcpServer {

	public static void main(String[] args) throws Exception {
		//创建socket对象
		ServerSocket serverSocket = new ServerSocket(20000);
		
		while(true){
			//监听
			Socket socket = serverSocket.accept();
			new Thread(new ServerThread(socket)).start();
		}
	}
}
线程类:

public class ServerThread implements  Runnable{

	Socket socket;
	public ServerThread(Socket socket){
		this.socket = socket;
	}
	
	@Override
	public void run() {
		try {
			String line;
			//获取通道输入流
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			
			BufferedWriter bw = new BufferedWriter(new FileWriter(UUIDUtils.getFiledName()));
			while((line = br.readLine())!=null){
				bw.write(line);
				bw.newLine();
				bw.flush();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

	
}
产生文件名类:

public class UUIDUtils {

	public static String getFiledName(){
		String fileName = UUID.randomUUID().toString();
		fileName = fileName.replace("-", "")+".txt";
		return fileName;
	}
}
这样,每次复制得到的文件名不同:

java学习(18)-- 网络编程_第8张图片


2.5 软件当中基本都是udp和tcp混用

你可能感兴趣的:(Java语言笔记)