什么是网络编程
计算机与计算机之间通过网络进行数据传输
两种软件架构
网络编程3要素
IP
IPv4
IPv6
@Test
public void test01() throws UnknownHostException {
// InetAddress.getByName 可以是名字或ip
InetAddress address = InetAddress.getByName("LAPTOP-7IJTG2U2");
System.out.println(address);
String hostName = address.getHostName();
System.out.println(hostName);
String ip = address.getHostAddress();
System.out.println(ip);
}
端口号
协议
OSI参考模型
TCP/IP协议
UDP
发送数据,接收数据
代码
/*
54321端口发送数据到12345端口,从12345端口取出数据
*/
@Test
public void UDP_Send() throws IOException {
//1.创建DatagramSocket对象(快递公司)
//空参:绑定随机端口
DatagramSocket ds = new DatagramSocket(54321);
//2.打包数据
byte[] data="测试UDP".getBytes();
InetAddress address = InetAddress.getByName("LAPTOP-7IJTG2U2");
int port=12345;
DatagramPacket dp = new DatagramPacket(data,data.length,address,12345);
//发送数据,释放资源
ds.send(dp);//向名为“LAPTOP-7IJTG2U2”的计算机的12345端口发送数据
ds.close();
}
@Test
public void UDP_Receive() throws IOException {
//创建DatagramSocket对象,绑定端口12345,因为数据被发送到12345端口
DatagramSocket ds = new DatagramSocket(12345);
InetAddress address = InetAddress.getByName("LAPTOP-7IJTG2U2");
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
System.out.println("12345端口等待接收数据中");
ds.receive(dp);
System.out.println("12345端口接收到数据");
byte[] data = dp.getData();
String s = new String(data,0,dp.getLength());
System.out.println("从ip:"+dp.getAddress()+"的"+dp.getPort()+"端口获取到数据:"+s);
}
先运行UDP_Receive,会阻塞在ds.receive ,再运行UDP_Send发送数据
运行结果
12345端口等待接收数据中
12345端口接收到数据
从ip:/192.168.123.1的54321端口获取到数据:测试UDP
Process finished with exit code 0
UDP案例:聊天室
需求
发送(聊天室里面的人)
public class RoomSend {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
Scanner sc = new Scanner(System.in);
InetAddress address = InetAddress.getByName("127.0.0.1");
int port=12345;
while (true){
System.out.println("请输入:");
String str = sc.next();
if("886".equals(str)){
break;
}
byte[] bytes = str.getBytes();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
ds.send(dp);
}
ds.close();
}
}
接收 (聊天室)
public class RoomReceive {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(12345);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, 0,bytes.length);
while (true){
ds.receive(dp);
System.out.println(dp.getAddress()+"--"+dp.getPort()+"--"+new String(dp.getData(),0,dp.getLength()));
}
}
}
允许创建多个RoomSend
测试
TCP
发送数据,接收数据
服务端
public class Server {
public static void main(String[] args) throws IOException {
//1.创建ServerSocket对象
ServerSocket ss = new ServerSocket(10000);
//2.监听客户端的链接,没有客户端链接会一直卡在这里,有客户端连接返回socket对象
Socket socket = ss.accept();
//3.获取输入流,读数据
int b;
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((b=br.read())!=-1){
System.out.print((char)b);
}
//4.释放资源
br.close();
socket.close();
//ss.close(); //客户端不关闭
}
}
客户端
public class Client {
public static void main(String[] args) throws IOException {
//1.创建socket对象,连接不到服务器的端口10000会报错
Socket socket = new Socket("127.0.0.1", 10000);
//2.获取socket对象的输出流,输出数据
OutputStream os = socket.getOutputStream();
os.write("我测".getBytes());
//3.释放资源
os.close();
socket.close();
}
}
TCP的三次握手和四次挥手
三次握手
四次挥手
练习
接收并反馈信息
上传文件
服务端
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10000);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\java_workspace\\demo3\\src\\main\\java\\com\\example\\upload\\copy.png"));
int len;
byte[] bytes = new byte[1024];
while ((len=bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
socket.close();
ss.close();
System.out.println("传输完成");
}
}
客户端
public class Client {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream(new File("D:\\java_workspace\\demo3\\src\\main\\java\\com\\example\\upload\\img.png"));
BufferedInputStream bis = new BufferedInputStream(fis);
int len;
byte[] bytes = new byte[1024];
Socket socket = new Socket("127.0.0.1", 10000);
OutputStream os = socket.getOutputStream();
while ((len= fis.read(bytes))!=-1){
os.write(bytes,0,len);
}
fis.close();
socket.shutdownOutput();
os.close();
socket.close();
}
}
上传文件(线程版)
服务端
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10000);
while (true){
Socket socket = ss.accept();
new Thread(new MyRunnable(socket)).start();
}
}
}
public class MyRunnable implements Runnable{
private Socket socket;
public MyRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\java_workspace\\demo3\\src\\main\\java\\com\\example\\upload\\" + UUID.randomUUID().toString().replace("-", "") + ".png"));
int len;
byte[] bytes = new byte[1024];
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
bos.close();
bis.close();
socket.close();
System.out.println("传输完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
public class TCPClient {
public static void main(String[] args) throws IOException, InterruptedException {
FileInputStream fis = new FileInputStream(new File("D:\\java_workspace\\demo3\\src\\main\\java\\com\\example\\upload\\img.png"));
BufferedInputStream bis = new BufferedInputStream(fis);
int len;
byte[] bytes = new byte[1024];
Socket socket = new Socket("127.0.0.1", 10000);
OutputStream os = socket.getOutputStream();
while ((len = fis.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
Thread.sleep(5000);
fis.close();
socket.shutdownOutput();
os.close();
socket.close();
}
}
上传文件(线程池版)
服务端
public class TCPServer {
private static ThreadPoolExecutor myThreadPool = new ThreadPoolExecutor(
4,//核心线程数
17,//最大线程数
1,//空闲线程最大存活时间
TimeUnit.MINUTES,//时间单位
new ArrayBlockingQueue<>(2),//长度为3的等待队列
Executors.defaultThreadFactory(),//创建线程工厂
new ThreadPoolExecutor.AbortPolicy()//设置拒绝策略:丢弃任务并抛出异常
);
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10000);
while (true){
Socket socket = ss.accept();
TCPServer.myThreadPool.submit(new MyRunnable(socket));
// new Thread(new MyRunnable(socket)).start();
}
}
}