网络编程
网络编程
通过编程语言来实现计算机间的数据共享和数据传递
网络编程的模型
网络编程三要素
A:IP地址
计算机在网络中的唯一标识
B:端口
应用程序的唯一标识
C:协议
通信的规则
UDP:数据打包,有限制,无连接,速度快,不安全
TCP:建立连接通道,无限制,速度慢,安全
Socket机制
网络编程其实就是Socket服务间的IO流传输数据问题
UDP协议
发送端:
A:创建发送端的Socket服务对象
B:创建数据并把数据打包
C:发送数据
D:释放资源
接收端:
A:创建接收端的Socket服务对象
B:创建数据包
C:接收数据
D:解析数据包
E:释放资源
案例:
A:
发送端 一句话
接收端 一句话
B:
发送端 键盘录入,针对某一个台主机
接收端 接收很多句话
C:
发送端 键盘录入,针对多台主机
接收端 接收很多句话
D:
用多线程改进的聊天程序
我的代码:
import java.io.IOException; import java.net.DatagramSocket; public class ChatRoom { public static void main(String[] args) throws IOException { DatagramSocket send = new DatagramSocket(); DatagramSocket receive = new DatagramSocket(12580); SendThread st = new SendThread(send); ReceiveThread rt = new ReceiveThread(receive); Thread t1 = new Thread(st); Thread t2 = new Thread(rt); t1.start(); t2.start(); } }
E:
GUI版的聊天程序
我的代码:
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class ReceiveDemo { public static void main(String[] args) throws IOException { // 创建接受端的Socket服务对象。 // 构造方法: DatagramSocket(int port) DatagramSocket ds = new DatagramSocket(10086); // 创建一个数据包对象,用于接受数据。 // DatagramPacket(byte[] buf, int length) byte[] bys = new byte[1024]; int length = bys.length; DatagramPacket dp = new DatagramPacket(bys, length); // 接受数据。 ds.receive(dp); // 解析数据包,把数据显示在控制台。 // public InetAddress getAddress() InetAddress address = dp.getAddress(); String ip = address.getHostAddress(); // public byte[] getData() byte[] bb = dp.getData(); // public int getLength() int len = dp.getLength(); String s = new String(bb, 0, len); System.out.println("from " + ip + " data is: " + s); // 释放资源。 ds.close(); } }
TCP协议
客户端:
A:创建客户端Socket对象
B:获取输出流,写数据
C:释放资源
服务器端:
A:创建服务器端Socket对象
B:监听客户端连接
C:获取收入流,读取数据
D:释放资源
我的代码:
import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class ClientDemo { public static void main(String[] args) throws IOException { // 创建发送端的Socket对象,要指定服务器的ip及端口。 // Socket(InetAddress address, int port) // Socket(String host, int port) Socket s = new Socket("192.168.11.168", 12345); // 获取输出流,写数据即可。 // public OutputStream getOutputStream() OutputStream os = s.getOutputStream(); os.write("hello,tcp,我来了".getBytes()); // 释放资源。 s.close(); } } import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo { public static void main(String[] args) throws IOException { // 创建接收端的Socket服务,并指定端口 // ServerSocket(int port) ServerSocket ss = new ServerSocket(12345); // 监听客户端连接 Socket s = ss.accept(); // 阻塞式方法 // 获取收入流,读取数据,并显示在控制台 InputStream is = s.getInputStream(); byte[] bys = new byte[1024]; int len = is.read(bys); // 阻塞式方法 String server = new String(bys, 0, len); System.out.println("server:" + server); // 释放资源 ss.close(); } }
A:
客户端:发送一句话
服务器端:接收一句话
B:
客户端:发送一句话,接收反馈
服务器端:接收一句话,给出反馈
C:
客户端:键盘录入
服务器端:输出语句输出到控制台
D:
客户端:键盘录入
服务器端:数据写到文本文件
E:
客户端:数据来自于文本文件
服务器端:数据写到文本文件
F:
客户端:数据来自于文本文件,接收反馈
服务器端:数据写到文本文件,给出反馈
我的代码:
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class UploadClient { public static void main(String[] args) throws IOException { // 创建客户端Socket对象 Socket s = new Socket("192.168.11.168", 12345); // 封装输入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream( "xp.bmp")); // 封装输出流 BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream()); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } // 禁用输出流 s.shutdownOutput(); // 获取反馈 InputStream is = s.getInputStream(); byte[] bytes = new byte[100]; int lens = is.read(bytes); String str = new String(bytes, 0, lens); System.out.println(str); // 释放资源 bis.close(); s.close(); } }
反射
反射其实就是通过class文件去使用构造方法,成员变量,成员方法。
获取字节码文件对象的方式
A:Object类的getClass()方法
B:数据类型.class
C:Class类的forName()方法
内容:
A:通过反射获取构造方法并使用
B:通过反射获取成员变量并使用
C:通过反射获取成员方法并使用
面试题:
A:给任意对象的任意属性赋值。
B:通过反射运行配置文件的内容。
C:反射越过泛型检测
我的练习:
import java.lang.reflect.Method; import java.util.ArrayList; public class ArrayListDemo { public static void main(String[] args) throws Exception { // 需求:请把array集合中添加三个字符串。 ArrayList<Integer> array = new ArrayList<Integer>(); Class c = array.getClass(); // Java.util.ArrayList Method m = c.getMethod("add", Object.class); m.invoke(array, "hello"); m.invoke(array, "world"); m.invoke(array, "java"); System.out.println(array); } }
设计模式和面试题
模板模式
抽象类 {
具体方法(模板方法)
抽象方法; //需要被重写的
}
我的代码:
public abstract class GetTime { public long getTime() { long start = System.currentTimeMillis(); code(); long end = System.currentTimeMillis(); return end - start; } public abstract void code(); // 这个代码是变化的 }
装饰模式
IO流最常见
Scanner sc = new Scanner(System.in);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
如果你实在不是特别的理解,你就可以认为:一个类的构造方法接收一个对象,其实就是对该对象进行了装饰。