Java之线程通信、网络编程之UDP、TCP的初步接触

线程

线程通信

​ wait()和notify(0通过操作同一份资源控制线程的通信,方法必须使用在同步的环境下

wait()进入到对象(资源)的等待池中排队等待,等待被唤醒,会让出cpu的资源,如果需要执行,除了获取cpu的资源以外,还要拿到对象的锁

案例一:信号灯

​ 在同一街道上,人和车同时在走,人往南北走,车往东西走,但是十字路口只有一个信号灯,绿灯人走,红灯车走

package day_01;
/*
 * 在同一街道上,人和车同时在走,人往南北走,车往东西走,
 * 但是十字路口只有一个信号灯,绿灯人走,红灯车走
 * 
 */
public class Demo01 {
	public static void main(String[] args) {
		Street street=new Street();
		new Thread(new Person(street)).start();;
		new Thread(new Car(street)).start();;
	}
	
}

class Street{
	//信号灯
	boolean flag=false;
	
	//we 东西 false 车
	public void we() throws InterruptedException{
		if(flag==true){
			this.wait();
		}else{
			Thread.sleep(100);
			System.out.println("车走");
			flag=true;
			this.notify();
		}
	}
	
	//ns 南北 true 人
	public void ns() throws InterruptedException{
		if(flag==false){
			System.out.println("人停");
			this.wait();
		}else{
			Thread.sleep(200);
			System.out.println("人走");
			flag=false;
			this.notify();
		}
	}
	
}

//人 对象
class Person implements Runnable{
	Street street=null;

	public Person(Street street) {
		super();
		this.street = street;
	}

	@Override
	public synchronized void run() {
		synchronized(street){
		while(true){
		try {
			street.ns();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			}
			}
		}
	}
}
//车对象
class Car implements Runnable{
	Street street=null;

	public Car(Street street) {
		super();
		this.street = street;
	}

	@Override
	public synchronized void run() {
		synchronized(street){
		while(true){
		// TODO Auto-generated method stub
		try {
			street.we();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
				}
			}
		}
	}
	
}

网络编程

基本常识

端口:区分软件
统一协议下端口不能冲突 tcp udp
0~65535 2个字节 表示端口
建议使用8000以上的端口号自定义
预留端口号:

常用软件或协议端口号
http协议80
tomcat8080
oracle1521
mysql3306

在java中表示端口: InetSocketAddress IP地址+端口号

常用命令

package net02;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

public class PortDemo02 {
	public static void main(String[] args) throws UnknownHostException {
		/*
		 * InetSocketAddress(InetAddress addr, int port)创建一个套接字地址的IP地址和端口号。  
		 * InetSocketAddress(String hostname, int port) 创建一个套接字地址的主机名和端口号。  
		 */
		InetSocketAddress net1=new InetSocketAddress("localhost",8888);
		InetSocketAddress net2=new InetSocketAddress(InetAddress.getLocalHost(),8888);
		System.out.println(net1);
		System.out.println(net2);
		/*
		 * getPort() 的端口号。
		 * String getHostName()  ip
		 */
		System.out.println(net1.getPort());//8888
		System.out.println(net1.getHostName());//localhost
		System.out.println(net1.getAddress());//localhost/127.0.0.1
	}

}

URL

URL: 统一资源定位符
互联网的三大基石: url html http

协议: http
域名:www.baidu.com
端口:80
资源:index.html
数据:uname=zhangsan&pwd=123
锚点:#a
“http://www.baidu.com:80/index.html?uname=zhangsan&pwd=123#a”
java中表示url:URL类

常用方法
package net02;

import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo03 {
	public static void main(String[] args) throws MalformedURLException {
		/*
		 * URL(String spec)创建一个从String URL对象表示
		*/
		URL url=new URL("http://www.baidu.com:80/index.html?uname=zhangsan&pwd=123#a");
		/*
		String getFile() 
		URL的文件名。  
		String getHost() 
		这个 URL的主机名,如果适用的话。  
		String getPath() 
		得到这个 URL路径的一部分。  
		int getPort() 
		这个 URL的端口号。  
		String getProtocol() 
		这个 URL的协议名称。  
		String getQuery() 
		获取查询 URL的一部分。  
		String getRef() 
		得到了锚(也称为“参考”) URL。  
	 */
		System.out.println("文件名:"+url.getFile());
		System.out.println("主机名:"+url.getHost());
		System.out.println("地址:"+url.getPath());
		System.out.println("端口号:"+url.getPort());
		System.out.println("协议:"+url.getProtocol());
		System.out.println("数据资源:"+url.getQuery());
		System.out.println("锚点:"+url.getRef());
		System.out.println();
		
	}
}

TCP和UDP

面向Socket套接字编程

socket就是传输层为引用层开辟的小口子

tcp和udp对socket的实现不同

UDP特点:发信息,非面向连接, 不安全 协议简单开销小,效率高大小有限制,一般不超过60k。

TCP特点:打电话,面向连接,安全效率低,

基于3次握手:1拨号 2.响应 3.通信

UDP实现流程

发送端代码
package udp03;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class UDPSend01 {
	public static void main(String[] args) throws IOException {
		System.out.println("-----------发送端------------");
	//1.定义发送端
		DatagramSocket client=new DatagramSocket(8888);
	//2.数据
		byte[] str="疑问".getBytes();
	//3.打包
		DatagramPacket packet=new DatagramPacket(str,str.length,new InetSocketAddress("localhost",9999));
	//4.发送
		client.send(packet);
	//5.关闭
		client.close();
	
	}
}

接收端代码
package udp03;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPReceive02 {
	public static void main(String[] args) throws IOException {
		System.out.println("----------服务端-----------------");
		//1.定义接收端
		DatagramSocket server=new DatagramSocket(9999);
		//2.准备一个字节数组打包
		byte[] car=new byte[1024];
		DatagramPacket packet=new DatagramPacket(car,car.length);
		//3.接收  接收到所有的数组
		server.receive(packet);
		///处理数据
		/*
			byte[] getData();
			返回数据缓冲区
			int getLength();
			返回数据的长度发送或接收到数据的长度
		*/
		byte[] datas=packet.getData();
		int length=packet.getLength();
		System.out.println(new String(datas,0,length));
		//5.关闭
		server.close();
	}
}

TCP的示例

客户端
package tcp04;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/*
 * tcp实现基本流程
 * 1.定义客户端Socket Socket(String host,int port)创建一个流套接字连接到指定主机上的端口
 * 2.准备数据
 * 3.写出 IO操作
 * 4.关闭
 * 
 * 
 * 
*/
public class TCPSend01 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("---------------客户端---------------------");
		//1.第一个客户端Socket Socket(String host,int port)
		Socket client=new Socket("localhost",8888);
		//2.准备数据
		String str="namezhangsan&pwd=123";
		//3.写出 IO操作
		//3.1选择流  数据流 输出流
		DataOutputStream data=new DataOutputStream(client.getOutputStream());
		data.writeUTF(str);
		//3.2刷新
		data.flush();
		//4.关闭
		data.close();
		client.close();
	
	}
}

服务端
package tcp04;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/*	
 * TCP实现基本流程:服务端
 * 1.定义服务端 ServerSocket ServerSocket(int port)创建一个服务器套接字绑定到指定端口
 * 2.阻塞式监听 Scoket accept()
 * 3.io操作		
 * 4.关闭
 * 
 */	
public class TCPReceive02 {
	public static void main(String[] args) throws IOException {
		System.out.println("-----服务端-----------");
		//1.定义服务器端
		ServerSocket server=new ServerSocket(8888);
		//2.阻塞式监听
		Socket client=server.accept();
		//3.io操作
		DataInputStream in=new DataInputStream(client.getInputStream());
		String str=in.readUTF();
		System.out.println(str);
		//4.关闭
		in.close();
		client.close();
		server.close();
	}
}

客户端-单向登录
package tcp04;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

/*
	TCP实现单向登录
*/
public class TCPSend04 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("--------------Client----------------");
		//1.定义一个客户端
		Socket client=new Socket("localhost",8898);
		//2.准备数据
		BufferedReader read=new BufferedReader(new InputStreamReader(System.in));
		System.out.println("请输入用户名");
		String name=read.readLine();
		System.out.println("请输入密码");
		String pwd=read.readLine();
		//3.选择流,并把  客户端的流 封装到   数据流中
		DataOutputStream data=new DataOutputStream(client.getOutputStream());
		data.writeUTF("name="+name+"&pwd="+pwd);
		data.flush();
		//4.关闭流
		data.close();
		read.close();
		client.close();
		
	}
}
服务端-单向登录
package tcp04;
/*
 * 	1.定义服务端
 *  2.阻塞式监听
 * 	3.准备一个流,接收数据
 * 	4.接收数据
 *  5.关闭		
*/

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

public class TCPReceived05 {
	public static void main(String[] args) throws IOException {
		System.out.println("---------------Server-----------");
		//1.定义服务器端
		ServerSocket server=new ServerSocket(8898); 
		//2.阻塞式监听
		Socket client=server.accept();
		//3.准备一个流用于接收数据
		DataInputStream data=new DataInputStream(client.getInputStream());
		//3.1写出
		String str=data.readUTF();
		System.out.println(str);
		//校验           如果是name=lao pwd=13456则在服务端提示登录成功                         
		String uname="";
		String pwd="";
		String[] arr=str.split("&");
		System.out.println(Arrays.toString(arr));
		for(String x:arr){
			System.out.println(x);
			String[] y=x.split("=");
			System.out.println(Arrays.toString(y));
			if("name".equals(y[0])){
				uname=y[1];
				System.out.println("uname的值"+y[1]);
			}
			if("pwd".equals(y[0])){
				pwd=y[1];
				System.out.println("password的值"+y[1]);
			}
		}
		if("lao".equals(uname)&&"13456".equals(pwd)){
			System.out.println("登录成功");
		}else{
			System.out.println("用户或密码错误");
		}
		//4.关闭
		data.close();
		client.close();
		server.close();
		
	
	}
}

客户端-单向登录并给出提示
package tcp04;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

/*
	TCP实现单项登录
*/
public class TCPToWaySend05 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("--------------Client----------------");
		//1.定义一个客户端
		Socket client=new Socket("localhost",8898);
		//2.准备数据
		BufferedReader read=new BufferedReader(new InputStreamReader(System.in));
		System.out.println("请输入用户名");
		String name=read.readLine();
		System.out.println("请输入密码");
		String pwd=read.readLine();
		//3.选择流,并把  客户端的流 封装到   数据流中
		DataOutputStream data=new DataOutputStream(client.getOutputStream());
		data.writeUTF("name="+name+"&pwd="+pwd);
		
	//接收服务端响应
		DataInputStream in=new DataInputStream(client.getInputStream());
		String s=in.readUTF();
		System.out.println(s);
		in.close();
	//接收服务端响应	
		
		data.flush();
		
		//4.关闭流
		data.close();
		read.close();
		client.close();
		
	}
}
服务端-单向登录并给出提示
package tcp04;
/*
 * 	1.定义服务端
 *  2.阻塞式监听
 * 	3.准备一个流,接收数据
 * 	4.接收数据
 *  5.关闭		
*/

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

public class TCPToWayReceived05 {
	public static void main(String[] args) throws IOException {
		System.out.println("---------------Server-----------");
		//1.定义服务器端
		ServerSocket server=new ServerSocket(8898); 
		//2.阻塞式监听
		Socket client=server.accept();
		System.out.println("----------一个客户端连接成功---------------------");
		//3.准备一个流用于接收数据
		DataInputStream data=new DataInputStream(client.getInputStream());
		//3.1写出
		String str=data.readUTF();
		
		//校验                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
		String uname="";
		String pwd="";
		String[] arr=str.split("&");
		for(String x:arr){
			String[] y=x.split("=");
			if("name".equals(y[0])){
				uname=y[1];
				System.out.println("uname的值"+y[1]);
			}
			if("pwd".equals(y[0])){
				pwd=y[1];
				System.out.println("password的值"+y[1]);
			}
		}
	//这一段是用来给客户端输出结果
		//获取输出流,结果写回客户端
		DataOutputStream os=new DataOutputStream(client.getOutputStream());
		
		if("lao".equals(uname)&&"13456".equals(pwd)){
			os.writeUTF("登录成功");
		}else{
			os.writeUTF("用户或密码错误");
		}
		os.flush();
		os.close();
  //这一段是用来给客户端输出结果	
		//4.关闭
		data.close();
		client.close();
		server.close();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值