线程
线程通信
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 |
tomcat | 8080 |
oracle | 1521 |
mysql | 3306 |
在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();
}
}