java基础---网络编程

1 网络编程

1.1 网络编程概述

  • 什么网络:分存在不同区域计算机使用专业通信线把连接起来,实现资源(数据,硬件)共享。

  • 网络编程目的:通过通讯协议实现数据传输
    在这里插入图片描述

  • 如何通信

    • ip和端口

      ip: Internet网络唯一标识.

      端口:计算机中运行的一个进程

    • 通讯协议的约定

      TCP:传输控制协议

      UDP:用户数据报协议

1.2 通讯要素

  • IP地址和端口

    InetAddress类:此类表示Internet协议(IP)地址

    端口号:0-65535 系统预留:0-1023 自定义端口:1024-65535

    如:mysql端口:3306

@Test
	public void test1() throws Exception {
		InetAddress inet = InetAddress.getByName("www.baidu.com");
		//InetAddress inet = InetAddress.getByName("182.61.200.6");
		System.out.println(inet);
		System.out.println(inet.getHostName());
		System.out.println(inet.getHostAddress());
		//本机  localhost 127.0.0.1 本地的回环地址(用于测试本机)
		//ipconfig   --查看当前机器的ip地址
		//ping  ip  --检查网络是否畅通 
		inet= InetAddress.getByName("127.0.0.1");
		System.out.println(inet.getHostName());
		System.out.println(inet.getHostAddress());
		//本机
		InetAddress inet1 = InetAddress.getLocalHost();
		System.out.println(inet1.getHostName());
		System.out.println(inet1.getHostAddress());
	}

  • 通讯协议

    TCP :传输控制协议 UPD:用户数据报 l>
    必须建立连接,形成传输通道将数据、源、目的封装成数据包,不必须建立连接
    传输前,采用“三次握手”,是可靠的数据包大小是64K
    Tcp通信位于两个进程 (客户端-服务端)因无需连接,故不可靠
    可以传输大量的数据传完数据无需释放资源 效率高
    传完需要释放己建立的连接 效率低
  • 传递的socket套接字

    ip地址和端口的组合

    网络通信其实就是Socket间的通信,以流的方式进行传输

    一般主动发起通信应用程序叫客户端,等待接受数据叫服务端‘

    客户端:Socket

    Socket(InetAddress address, int port) 创建流套接字并将其连接到指定IP地址的指定端口号。

    getInputStream() 返回此套接字的输入流。

    getOutputStream() 返回此套接字的输出流。

    服务端:ServerSocket

    ServerSocket(int port) 创建绑定到指定端口的服务器套接字。

    Socket=accept() 侦听要连接到此套接字并接受它。

    ​ getInputStream() 返回此套接字的输入流。

    ​ getOutputStream() 返回此套接字的输出流。

在这里插入图片描述

1.3 TCP网络协议通讯

public class TestTcp3 {
	//客户端
	@Test
	public void client() throws IOException {
		Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),8888);
		//发送
		OutputStream os = socket.getOutputStream();
		
		//本地读取文件
		FileInputStream fis = new FileInputStream(new File("a.txt"));
		byte[] bs = new byte[1024];
		int le ;
		while((le=fis.read(bs))!=-1) {
			os.write(bs, 0, le);
		}
		//方法
		socket.shutdownOutput();  //输出完成
		
		//接收服务端的数据 
		InputStream is = socket.getInputStream();
		byte[] bytes = new byte[1024];
		int len;
		while((len=is.read(bytes))!=-1) {
			String s = new String(bytes,0,len);
			System.out.println(s);
		}
		is.close();
		os.close();
		socket.close();
	}
	//服务端
	@Test
	public void server() throws IOException {
		ServerSocket ss=new ServerSocket(8888);
		Socket socket = ss.accept();  //监听客户端是否有消息
		FileOutputStream fis = new FileOutputStream(new File("c.txt"));
		InputStream is = socket.getInputStream();
		
		byte[] bytes = new byte[1024];
		int len;
		while((len=is.read(bytes))!=-1) {  //阻塞
			fis.write(bytes, 0, len);
		}
		/
		//向客户端发数据 
		OutputStream os = socket.getOutputStream();
		os.write("好的,我收到了!".getBytes());
		
		os.close();
		is.close();
		socket.close();
		ss.close();
	}

}

1.4 UDP网路协议通讯

DatagramSocket: 此类表示用于发送和接收数据报套接字

DatagramPacket: 封装了UDP数据报,在数据报中包含了发送端和接收端的IP和端口号。

UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接

public class TestUDP2 {
	//发送方
		@Test
		public void client() throws Exception {
			DatagramSocket ds = new DatagramSocket();
			byte[] bytes = "你好,我是客户端".getBytes();
			DatagramPacket dp = new DatagramPacket(bytes, 0, bytes.length,
					InetAddress.getLocalHost(), 8989);		
			//发送
			ds.send(dp);
			ds.close();
		}
		//接收方
		@Test
		public void server() throws Exception {
			DatagramSocket ds = new DatagramSocket(8989);
			byte[] bytes = new byte[1024];
			DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length);
			//接收方法
			ds.receive(dp);
			String s =new String(dp.getData(),0,dp.getLength());
			System.out.println(s);
			ds.close();
		}
}

UDP传送文件

public class TestUDP2 {
	//发送方
		@Test
		public void client() throws Exception {
			DatagramSocket ds = new DatagramSocket();
			//本地读取文件
			FileInputStream fis = new FileInputStream(new File("a.txt"));
			byte[] bytes = new byte[fis.available()];
			fis.read(bytes);   //读到字节数组中
			DatagramPacket dp = new DatagramPacket(bytes, 0, bytes.length,
					InetAddress.getLocalHost(), 8989);		
			//发送
			ds.send(dp);
			//释放资源
			fis.close();
			ds.close();
		}
		//接收方
		@Test
		public void server() throws Exception {
			DatagramSocket ds = new DatagramSocket(8989);
			byte[] bytes = new byte[1024];
			DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length);
			//接收方法
			ds.receive(dp);
			//输出磁盘某一位置 
			FileOutputStream fos = new FileOutputStream(new File("b.txt"));
			fos.write(dp.getData(), 0, dp.getLength());
		
			//释放资源
			fos.close();
			ds.close();
		}
}

1.5 URL编程

  • URL:统一资源定位符 或叫网络一资源

  • 组成:<传输协议>://<主机名>:<端口号 http默认80>/<文件名>

  • openStream() --读

    打开与此 URL ,并返回一个 InputStream ,以便从该连接读取。

  • openConnection() —可以读,可以写(下载)

    返回一个URLConnection实例,表示与URL引用的远程对象的URL 。

  • getInputStream()

    返回从此打开的连接读取的输入流。

public class TestUrl {
	@Test
	public void test1() throws Exception {
		URL url = new URL("http://127.0.0.1:8080/examples/1.txt");
		//URL url1 = new URL("http://img.redocn.com/sheji/20141219/zhongguofengdaodeliyizhanbanzhijing_3744115.jpg")
		InputStream is = url.openStream();
		byte[] bytes =new byte[1024];
		int len;
		while((len=is.read(bytes))!=-1) {
			String s = new String(bytes,0,len);
			System.out.println(s);
		}
		is.close();
	}
	@Test
	public void test2() throws Exception {
		URL url1 = new URL("http://img.redocn.com/sheji/20141219/zhongguofengdaodeliyizhanbanzhijing_3744115.jpg");
		URLConnection conn = url1.openConnection();
		InputStream is = conn.getInputStream();
		
		//写当前d:/abc.jpg
		FileOutputStream fos = new FileOutputStream(new File("d:/abc.jpg"));
		byte[] bytes =new byte[1024];
		int len;
		while((len=is.read(bytes))!=-1) {
			fos.write(bytes, 0, len);
		}
		System.out.println("成功");
		fos.close();
		is.close();
	}
}

1.6 动态代理(静态代理)

public class DynamicProxy {
	public static void main(String[] args) {
		RealSubject real = new RealSubject();
		
		MyProxy myproxy = new MyProxy();
		Object obj = myproxy.bind(real);  //初始化了被代理对象 obj它就是代理对象
		Subject sub = (Subject)obj;  //接口subject
		sub.action();
		
		System.out.println("===========================");
		Object bind = myproxy.bind(new RealObject());
		Interface i =(Interface)bind;   //接口Interface
		i.action();
	}
}
//
interface Subject{
	void action();
}
//被代理类
class RealSubject implements Subject{
	@Override
	public void action() {
		System.out.println("被代理类的行为");
	}
}
//代理类的处理类,调用代理对象的方法时会自动调用invoke方法 
class MyProxy implements InvocationHandler{
	Object obj=null;  //被代理类对象的声明
	//声明一个方法1.实例化被 代理对象   2 返回一个代理对象 
	public Object bind(Object obj) {
		//实例化被 代理对象
		this.obj = obj;
		//返回代理对象 
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), 
				obj.getClass().getInterfaces(), this);
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("1111111111111");
		Object o = method.invoke(obj, args);  //通过反射调用被代理类的方法
		System.out.println("2222222222222");
		return o;
	}
}

1.7 死锁

同步块,同步方法目的是实现线程安全

如果synchronized关键嵌套不当,就会引起死锁

public class TestDeadThread {
	static Object obj1 = new Object();
	static Object obj2 = new Object();
	public static void main(String[] args) {
		new Thread() {
			@Override
			public void run() {
				synchronized(obj1) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程1的obj1");
					synchronized (obj2) {
						System.out.println("线程1的obj2");
					}
				}
			}}.start();
		new Thread() {
			@Override
			public void run() {
				synchronized(obj2) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程2的obj2");
					synchronized (obj1) {
						
						System.out.println("线程2的obj1");
					}
				}
			}}.start();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bromide-0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值