7.0 KiB
7.0 KiB
网络编程:
软件架构:
BS
Browser Server 浏览器 服务端
CS
Client Server 客户段 服务端
总结:
网络编程三要素
IP
特殊ip地址:
常用命令:
ipconfig:查看本机ip地址
ping:检查网络是否畅通
端口
协议
UDP协议:不可靠 速度快
案例:收发消息:
接收端:
public class Receive {
public static void main(String[] args) throws Exception{
//创建DatagramSocket对象
DatagramSocket socket = new DatagramSocket(9999);
//创建DatagramPacket对象
DatagramPacket packet = new DatagramPacket(new byte[1024],1024);
//接受信息
socket.receive(packet);
//拆包裹
byte [] data =packet.getData();
String msg = new String(data);
String ip = packet.getAddress().getHostAddress();
System.out.println("从"+ip+"ip发过来的信息:"+msg);
//释放资源
socket.close();
}
}
发送端:
public class Send {
public static void main(String[] args) throws Exception{
//创建DatagramSocket对象
DatagramSocket socket = new DatagramSocket(8888);
//准备材料
String msg ="あんな别吃了";
byte[] bytes = msg.getBytes();
//打包包裹
DatagramPacket packet = new DatagramPacket(bytes,
bytes.length,
InetAddress.getByName("127.0.0.1"),//参数为对方的ip对方的端口
9999);
socket.send(packet);
socket.close();
}
}
TCP协议:可靠信息安全,速度慢
三次握手:
四次挥手:
大型案例:重点分析:
TCP上传文件:
客户端
package com.ice.cat.test;
import java.io.*;
import java.lang.reflect.Type;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("10.104.117.228",9999);
//获取输入输出流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//将字节流转化为字符流,用来处理一些中文字符,再转化为字符缓冲流,可以读取一整行
BufferedReader br = new BufferedReader(new InputStreamReader(is));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//写出文件的名字
File file = new File("C:\\Users\\asus\\Pictures\\ariya.png");
bw.write(file.getName());//没带换行符
bw.newLine();
bw.flush();
//接受客户端反馈
String flag = br.readLine();
if (flag.equals("ok")){
//继续上传文件
//创建本地流,上传图片
FileInputStream fle = new FileInputStream(file);
byte [] bys = new byte[1024];
int lne;
while ((lne = fle.read(bys)) != -1){
os.write(bys,0,lne);
}
fle.close();
//重点:给服务端一个结束标记
socket.shutdownOutput();//通俗理解,写出了一个-1标记
}
//读取服务端的返回消息消息
String result = br.readLine();
System.out.println(result);
socket.close();
}
}
服务端:
package com.ice.cat.test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.*;
public class Server {
public static void main(String[] args) throws Exception {
//创建线程池
ThreadPoolExecutor pool = new ThreadPoolExecutor(4,
6,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
ServerSocket server = new ServerSocket(9999);
System.out.println("服务端开启,等待客户端连接");
//响应请求
//多次响应上传图片,用循环包裹
while (true) {
Socket socket = server.accept();
pool.submit(new SubmitTask(socket));
}
}
}
线程池代码:为实现多次运行,可在不同线程进行调用
package com.ice.cat.test;
import java.io.*;
import java.net.Socket;
import java.util.UUID;
public class SubmitTask implements Runnable{
private Socket socket;
public SubmitTask(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//将字节流转化为字符流,用来处理一些中文字符,再转化为字符缓冲流,可以读取一整行
BufferedReader br = new BufferedReader(new InputStreamReader(is));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//接受文件名字
String resultName = br.readLine();
//给用户端反馈
bw.write("ok");
bw.newLine();
bw.flush();
//读取客户端上传的文件,注意写出上传的位置
//为避免文件名字重复使用UUID方法
File file = new File("C:\\Users\\asus\\Desktop\\JAVA", UUID.randomUUID().toString() + resultName);
//准备本地的输出流,将网络服务端数据写入到指定位置
FileOutputStream fos = new FileOutputStream(file);
//读取网络流数据,写入到本地文件
int lne;
byte[] bys = new byte[1024];
//is为网络输入流,没有关联文件,不可能有-1
while ((lne = is.read(bys)) != -1) {
fos.write(bys, 0, lne);
}
fos.close();
//回写给客户段消息
bw.write("上传成功");
bw.newLine();
bw.flush();
//关流
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
补充点:若文件名重复则使用UUID.randomUUID().toString()来生成随机名字
