JavaSE_day45-46(网络编程、UDP/TCP)

 了解了网络通讯中的三个要素: IP地址、端口号、通讯协议
 * Java中有一个类就可以来表示IP地址
 * 
 * InetAddress: 此类表示互联网协议(IP)地址.
 * 
 * ipconfig: 可以获取当前计算机的网卡 和 IP地址
 * 
 * */
 

public class A_netAddressDemo {
	public static void main(String[] args) throws UnknownHostException {
		//static InetAddress getByName(String host)  : 在给定主机名的情况下确定主机的 IP 地址。
		 InetAddress address = InetAddress.getByName("172.24.124.93"); // ip地址是唯一的
		 InetAddress address1 = InetAddress.getByName("LAPTOP-R9G4F3MU"); // ip地址是唯一的
		 System.out.println(address);
		 System.out.println(address1);
		 
		 System.out.println("-------------------------");
		 
		 String hostAddress = address.getHostAddress();  // 172.24.124.93    返回IP地址
		 String hostName = address.getHostName();		//	返回主机名LAPTOP-R9G4F3MU
		 
		 System.out.println(hostName);
		 System.out.println(hostAddress);
	}
}

 使用UDP协议接收数据
        创建接收端Socket对象
        创建包对象(DatagramPacket)
        接收数据(receive)
        解析数据
        输出数据
        释放资源

//DatagramPacket:(此类表示数据报包。)用来接收UDP协议传过来的数据的

快捷键:alt+shift+r修改文件名字

public class B_ReceiveDemo {
	public static void main(String[] args) throws IOException {
		//创建接收端Socket对象
		DatagramSocket ds = new DatagramSocket(8888);
		//接收数据
		//DatagramPacket(byte[] buf, int length) 
		byte[] bys = new byte[1024];
		DatagramPacket dp = new DatagramPacket(bys,bys.length);//存入字节数组了,存入的长度为1024,所以最多只能输出1024个字节,多了的会自动戒掉!
				
		System.out.println(1);
		ds.receive(dp);//(从此套接字接收数据报包)阻塞,收到数据后才会放行!
		System.out.println(2);
		
		//解析数据
		//InetAddress getAddress() : 获取发送端的IP对象
		InetAddress address = dp.getAddress();
		//byte[] getData()  :获取接收到的数据,也可以直接使用创建包对象时的数组
		byte[] data = dp.getData();
		//int getLength()  :获取具体收到数据的长度
		int length = dp.getLength();
		
		
		//输出数据
		System.out.println("sender ---> " + address.getHostAddress());
		System.out.println(new String(data,0,length));	//字节数组转成字符串
		System.out.println(new String(bys,0,length));  //字节数组转成字符串
		//释放资源
		ds.close();

	}
}

2 使用UDP协议发送数据
        1.创建发送端Socket对象
        2.创建数据并打包
        3.发送数据
        4.释放资源
 * 
 * DatagramSocket:(此类表示用来发送和接收数据报包的套接字)此类表示用来发送和接收数据,基于UDP协议的
 * 
 * DatagramSocket() :创建Socket对象并随机分配端口号
 * DatagramSocket(int port) :创建Socket对象并指定端口号
 * 
 * 
 * ctrl+1快捷键:补全代码前半段
 */
 

public class B_SendDemo {
	public static void main(String[] args) throws IOException  {
		//创建发送端Socket对象
		DatagramSocket ds = new DatagramSocket();
		
		//创建数据并打包
		/*
		 * DatagramPacket :此类表示数据报包
		 * byte[] buf:数据byte[]
		 * int length:传输字节的长度
		 * InetAddress address:设备的地址 ip
		 * int port:进程的地址  端口号
		   DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
		 */
		
		String s = "hello udp,im comming!";
		byte[] bys = s.getBytes();//字符串转成字符数组
		int length = bys.length;
		InetAddress address = InetAddress.getByName("172.24.124.93");//发送给当前设备   或者使用主机名:LAPTOP-R9G4F3MU
		int port = 8888;
		
		//打包
		DatagramPacket dp = new DatagramPacket(bys,length,address,port);
		//发送数据
		ds.send(dp);
		//释放资源
		ds.close();
	}
}

3 重复第2点

package day45_day46;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class B_ReceiveDemo2 {
	public static void main(String[] args) throws Exception {
		//1.创建接收端Socket对象
		DatagramSocket ds = new DatagramSocket(9999);
		//2.创建包对象
		byte[]bys = new byte[1024];
//		构造 DatagramPacket,用来接收长度为 length 的数据包。
		DatagramPacket pd = new DatagramPacket(bys,bys.length);
		//3.接收数据
		ds.receive(pd);
		//4.解析数据
		//4.1获取发送端IP对象
		InetAddress address = pd.getAddress();
		//4.2获取数据
		byte[] data = pd.getData();
		//4.3获取数据的长度
		int length = pd.getLength();
		
		//5.输出数据
		System.out.println("接收到的数据:"+address.getHostName());
		System.out.println(new String(data,0,length));
		//6.释放资源
		ds.close();
	
	}
	

}
package day45_day46;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/*
 * UDP协议收发数据的注意事项:
 * 				A: 端口号错误: 数据可以正常发出,但是接收端收不到数据
 * 				B:Exception in thread "main" java.net.BindException: Address already in use: Cannot bind
 * 					启动了两个接收端,端口号第一个接收端已经占用了,第二个接收端再去使用就报错了
 * 		
 * 
 * 发送端和接收端是有个数据包的!	
 * */

public class B_SendDemo2 {
	public static void main(String[] args) throws Exception {
		
		//1.创建发送端的Socket对象
		DatagramSocket ds = new DatagramSocket();
		//2.创建包对象
		byte[] bytes = "Hello,World! UDP....".getBytes();
//		构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号
		DatagramPacket dp = new DatagramPacket(bytes,bytes.length,InetAddress.getByName("PS20190620DZMJ"),9999);
		//3.发送数据
		ds.send(dp);
		//4.释放资源
		ds.close();
		
	}
}

4  使用TCP协议发送数据
        创建发送端Socket对象(创建连接)
        获取输出流对象
        发送数据
        释放资源
        
    Socket(InetAddress address, int port) 
    Exception in thread "main" java.net.ConnectException: Connection refused: connect   没有连接就会报错

客户端:发送数据(设置端口)

public class C_ClientDemo {
	public static void main(String[] args) throws IOException {
		//创建发送端Socket对象(创建连接)
		Socket s = new Socket(InetAddress.getByName("LAPTOP-R9G4F3MU"),10086);  //创建一个流套接字并将其连接到指定 IP 地址的指定端口号
		//通过Socket对象-->获取输出流对象
		OutputStream os = s.getOutputStream();
		//发送数据
		String str = "hello tcp,im comming!!!";
		os.write(str.getBytes());
		//释放资源
		//os.close();
		s.close();
	}
}

使用TCP协议接收数据
         创建接收端Socket对象
         监听(阻塞)
         获取输入流对象
         获取数据
         输出数据
         释放资源
         
     ServerSocket:接收端
     Socket:服务端
     ServerSocket(int port) 对应端口
     Socket accept() 阻塞,等待接收
 
 
 服务端:接收数据(需要端口)
 
 服务端和客户端之间是有个流的
 

public class C_ServerDemo {
	public static void main(String[] args) throws IOException  {
		//创建接收端Socket对象
		ServerSocket ss = new ServerSocket(10086);
 		//监听(阻塞),就是一直等着接收功能
		Socket s = ss.accept();
 		//通过Socket对象获取输入流对象
		InputStream is = s.getInputStream();
 		//获取数据
		byte[] bys = new byte[1024];
		int len;//用于存储读到的字节个数
		len = is.read(bys);//读进字节数组
 		//输出数据
		InetAddress address = s.getInetAddress();
		System.out.println("client ---> " + address.getHostName());
		System.out.println(new String(bys,0,len));
 		//释放资源
		s.close();
		//ss.close();
	}
}

5 通过TCP
     需求:使用TCP协议发送数据,并将接收到的数据转换成大写返回(关键是他们之间可以相互传来传去!!)
     
         客户端发出数据
         服务端接收数据
     
         服务端转换数据
     
         服务端发出数据
         客户端接收数据
     
 */

客户端:

public class C_ClientDemo2 {
	public static void main(String[] args) throws IOException {
		//创建客户端Socket对象
		Socket s = new Socket(InetAddress.getByName("LAPTOP-R9G4F3MU"),10010);
		//获取输出流对象
		OutputStream os = s.getOutputStream();
		//发出数据
		os.write("tcp,im comming again!!!".getBytes());  

		
		//获取输入流对象
		InputStream is = s.getInputStream();
		byte[] bys = new byte[1024];
		int len;//用于存储读取到的字节个数
		//接收数据
		len = is.read(bys);
		//输出数据
		System.out.println("step2:"+new String(bys,0,len));
		
		//释放资源
		s.close();
		
	}
}

服务端:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class C_ServerDemo2 {
	public static void main(String[] args) throws IOException {
		//创建服务端Socket对象
		ServerSocket ss = new ServerSocket(10010);
		//监听
		Socket s = ss.accept();
		//获取输入流对象
		InputStream is = s.getInputStream();
		//获取数据
		byte[] bys = new byte[1024];
		int len;//用于存储读取到的字节个数
		len = is.read(bys);
		String str = new String(bys,0,len);
		//输出数据
		System.out.println("step1:"+str);
		//转换数据
		String upperStr = str.toUpperCase();  //就是大写方法!
		//获取输出流对象
		OutputStream os = s.getOutputStream();
		//返回数据(发出数据)
		os.write(upperStr.getBytes());
		
		//释放资源
		s.close();
//		ss.close();//服务端一般不关闭
	}
}

6 通过TCP

/*
 * 模拟用户登录(跟第五点有点像,都是传来传去)
 * 
 */

客户端:

package day45_day46;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/*
 * 模拟用户登录
 * 
 */
public class D_ClientTest {
	public static void main(String[] args) throws  IOException  {
		//创建客户端Socket对象
		
		Socket s = new Socket("LAPTOP-R9G4F3MU",8888);
		
		//获取用户名和密码
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //缓冲流与标准输入输出流
		System.out.println("请输入用户名:");
		String username = br.readLine();
		System.out.println("请输入密码:");
		String password = br.readLine();
		
		
		//获取输出流对象
//		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		PrintWriter out = new PrintWriter(s.getOutputStream(),true); //表示追加,很方便,写完一行就换行,与后面的服务端接收一次读取一行对应上了
//		//写出数据
//		bw.write(username);
//		bw.newLine();
//		bw.flush();
//		bw.write(password);
//		bw.newLine();
//		bw.flush();
		
		out.println(username);
		out.println(password);
		
		//获取输入流对象
		BufferedReader serverBr = new BufferedReader(new InputStreamReader(s.getInputStream()));
		//获取服务器返回的数据
		String result = serverBr.readLine();
		System.out.println(result);
		
		//释放资源
//		bw.close();
		s.close();
	}
}

服务端:

package day45_day46;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class D_ServerTest {
	public static void main(String[] args) throws IOException {
		//创建服务器端Socket对象
		ServerSocket ss = new ServerSocket(8888);
		//监听
		Socket s = ss.accept();
		//获取输入流对象
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		//获取用户名和密码
		String username = br.readLine();
		String password = br.readLine();
		//判断用户名和密码是否正确
		boolean flag = false;
		if("user".equals(username) && "123456".equals(password)) {
			flag = true;
		}
		//获取输出流对象
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		//返回判断信息
		if(flag) {
			out.println("登陆成功");
		}
		else {
			out.println("登陆失败");
		}
		//释放资源
		s.close();
		//ss.close();//服务器一般不关闭
	}
}



你可能感兴趣的:(java,开发语言)