网络编程
网络编程
通过编程语言来实现计算机间的数据共享和数据传递
网络编程的模型
网络编程三要素
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));
如果你实在不是特别的理解,你就可以认为:一个类的构造方法接收一个对象,其实就是对该对象进行了装饰。